Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: streamline defer op type handling

There's no need to bundle a pointer to the defer op type into the defer
op control structure. Instead, store the defer op type enum, which
enables us to shorten some of the lines.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>

+43 -45
+27 -23
fs/xfs/libxfs/xfs_defer.c
··· 191 191 { 192 192 struct list_head *li; 193 193 struct xfs_defer_pending *dfp; 194 + const struct xfs_defer_op_type *ops; 194 195 195 196 list_for_each_entry(dfp, &tp->t_dfops, dfp_list) { 196 - dfp->dfp_intent = dfp->dfp_type->create_intent(tp, 197 - dfp->dfp_count); 197 + ops = defer_op_types[dfp->dfp_type]; 198 + dfp->dfp_intent = ops->create_intent(tp, dfp->dfp_count); 198 199 trace_xfs_defer_create_intent(tp->t_mountp, dfp); 199 - list_sort(tp->t_mountp, &dfp->dfp_work, 200 - dfp->dfp_type->diff_items); 200 + list_sort(tp->t_mountp, &dfp->dfp_work, ops->diff_items); 201 201 list_for_each(li, &dfp->dfp_work) 202 - dfp->dfp_type->log_item(tp, dfp->dfp_intent, li); 202 + ops->log_item(tp, dfp->dfp_intent, li); 203 203 } 204 204 } 205 205 ··· 210 210 struct list_head *dop_pending) 211 211 { 212 212 struct xfs_defer_pending *dfp; 213 + const struct xfs_defer_op_type *ops; 213 214 214 215 trace_xfs_defer_trans_abort(tp, _RET_IP_); 215 216 216 217 /* Abort intent items that don't have a done item. */ 217 218 list_for_each_entry(dfp, dop_pending, dfp_list) { 219 + ops = defer_op_types[dfp->dfp_type]; 218 220 trace_xfs_defer_pending_abort(tp->t_mountp, dfp); 219 221 if (dfp->dfp_intent && !dfp->dfp_done) { 220 - dfp->dfp_type->abort_intent(dfp->dfp_intent); 222 + ops->abort_intent(dfp->dfp_intent); 221 223 dfp->dfp_intent = NULL; 222 224 } 223 225 } ··· 323 321 struct xfs_defer_pending *pli; 324 322 struct list_head *pwi; 325 323 struct list_head *n; 324 + const struct xfs_defer_op_type *ops; 326 325 327 326 /* 328 327 * Free the pending items. Caller should already have arranged 329 328 * for the intent items to be released. 330 329 */ 331 330 list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) { 331 + ops = defer_op_types[dfp->dfp_type]; 332 332 trace_xfs_defer_cancel_list(mp, dfp); 333 333 list_del(&dfp->dfp_list); 334 334 list_for_each_safe(pwi, n, &dfp->dfp_work) { 335 335 list_del(pwi); 336 336 dfp->dfp_count--; 337 - dfp->dfp_type->cancel_item(pwi); 337 + ops->cancel_item(pwi); 338 338 } 339 339 ASSERT(dfp->dfp_count == 0); 340 340 kmem_free(dfp); ··· 360 356 struct list_head *n; 361 357 void *state; 362 358 int error = 0; 363 - void (*cleanup_fn)(struct xfs_trans *, void *, int); 359 + const struct xfs_defer_op_type *ops; 364 360 LIST_HEAD(dop_pending); 365 361 366 362 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); ··· 383 379 /* Log an intent-done item for the first pending item. */ 384 380 dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, 385 381 dfp_list); 382 + ops = defer_op_types[dfp->dfp_type]; 386 383 trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); 387 - dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, 384 + dfp->dfp_done = ops->create_done(*tp, dfp->dfp_intent, 388 385 dfp->dfp_count); 389 - cleanup_fn = dfp->dfp_type->finish_cleanup; 390 386 391 387 /* Finish the work items. */ 392 388 state = NULL; 393 389 list_for_each_safe(li, n, &dfp->dfp_work) { 394 390 list_del(li); 395 391 dfp->dfp_count--; 396 - error = dfp->dfp_type->finish_item(*tp, li, 397 - dfp->dfp_done, &state); 392 + error = ops->finish_item(*tp, li, dfp->dfp_done, 393 + &state); 398 394 if (error == -EAGAIN) { 399 395 /* 400 396 * Caller wants a fresh transaction; ··· 410 406 * xfs_defer_cancel will take care of freeing 411 407 * all these lists and stuff. 412 408 */ 413 - if (cleanup_fn) 414 - cleanup_fn(*tp, state, error); 409 + if (ops->finish_cleanup) 410 + ops->finish_cleanup(*tp, state, error); 415 411 goto out; 416 412 } 417 413 } ··· 423 419 * a Fresh Transaction while Finishing 424 420 * Deferred Work" above. 425 421 */ 426 - dfp->dfp_intent = dfp->dfp_type->create_intent(*tp, 422 + dfp->dfp_intent = ops->create_intent(*tp, 427 423 dfp->dfp_count); 428 424 dfp->dfp_done = NULL; 429 425 list_for_each(li, &dfp->dfp_work) 430 - dfp->dfp_type->log_item(*tp, dfp->dfp_intent, 431 - li); 426 + ops->log_item(*tp, dfp->dfp_intent, li); 432 427 } else { 433 428 /* Done with the dfp, free it. */ 434 429 list_del(&dfp->dfp_list); 435 430 kmem_free(dfp); 436 431 } 437 432 438 - if (cleanup_fn) 439 - cleanup_fn(*tp, state, error); 433 + if (ops->finish_cleanup) 434 + ops->finish_cleanup(*tp, state, error); 440 435 } 441 436 442 437 out: ··· 495 492 struct list_head *li) 496 493 { 497 494 struct xfs_defer_pending *dfp = NULL; 495 + const struct xfs_defer_op_type *ops; 498 496 499 497 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); 500 498 BUILD_BUG_ON(ARRAY_SIZE(defer_op_types) != XFS_DEFER_OPS_TYPE_MAX); ··· 508 504 if (!list_empty(&tp->t_dfops)) { 509 505 dfp = list_last_entry(&tp->t_dfops, 510 506 struct xfs_defer_pending, dfp_list); 511 - if (dfp->dfp_type->type != type || 512 - (dfp->dfp_type->max_items && 513 - dfp->dfp_count >= dfp->dfp_type->max_items)) 507 + ops = defer_op_types[dfp->dfp_type]; 508 + if (dfp->dfp_type != type || 509 + (ops->max_items && dfp->dfp_count >= ops->max_items)) 514 510 dfp = NULL; 515 511 } 516 512 if (!dfp) { 517 513 dfp = kmem_alloc(sizeof(struct xfs_defer_pending), 518 514 KM_SLEEP | KM_NOFS); 519 - dfp->dfp_type = defer_op_types[type]; 515 + dfp->dfp_type = type; 520 516 dfp->dfp_intent = NULL; 521 517 dfp->dfp_done = NULL; 522 518 dfp->dfp_count = 0;
+15 -16
fs/xfs/libxfs/xfs_defer.h
··· 9 9 struct xfs_defer_op_type; 10 10 11 11 /* 12 - * Save a log intent item and a list of extents, so that we can replay 13 - * whatever action had to happen to the extent list and file the log done 14 - * item. 15 - */ 16 - struct xfs_defer_pending { 17 - const struct xfs_defer_op_type *dfp_type; /* function pointers */ 18 - struct list_head dfp_list; /* pending items */ 19 - void *dfp_intent; /* log intent item */ 20 - void *dfp_done; /* log done item */ 21 - struct list_head dfp_work; /* work items */ 22 - unsigned int dfp_count; /* # extent items */ 23 - }; 24 - 25 - /* 26 12 * Header for deferred operation list. 27 13 */ 28 14 enum xfs_defer_ops_type { ··· 20 34 XFS_DEFER_OPS_TYPE_MAX, 21 35 }; 22 36 37 + /* 38 + * Save a log intent item and a list of extents, so that we can replay 39 + * whatever action had to happen to the extent list and file the log done 40 + * item. 41 + */ 42 + struct xfs_defer_pending { 43 + struct list_head dfp_list; /* pending items */ 44 + struct list_head dfp_work; /* work items */ 45 + void *dfp_intent; /* log intent item */ 46 + void *dfp_done; /* log done item */ 47 + unsigned int dfp_count; /* # extent items */ 48 + enum xfs_defer_ops_type dfp_type; 49 + }; 50 + 23 51 void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, 24 52 struct list_head *h); 25 53 int xfs_defer_finish_noroll(struct xfs_trans **tp); ··· 43 43 44 44 /* Description of a deferred type. */ 45 45 struct xfs_defer_op_type { 46 - enum xfs_defer_ops_type type; 47 - unsigned int max_items; 48 46 void (*abort_intent)(void *); 49 47 void *(*create_done)(struct xfs_trans *, void *, unsigned int); 50 48 int (*finish_item)(struct xfs_trans *, struct list_head *, void *, ··· 52 54 int (*diff_items)(void *, struct list_head *, struct list_head *); 53 55 void *(*create_intent)(struct xfs_trans *, uint); 54 56 void (*log_item)(struct xfs_trans *, void *, struct list_head *); 57 + unsigned int max_items; 55 58 }; 56 59 57 60 extern const struct xfs_defer_op_type xfs_bmap_update_defer_type;
+1 -1
fs/xfs/xfs_trace.h
··· 2276 2276 ), 2277 2277 TP_fast_assign( 2278 2278 __entry->dev = mp ? mp->m_super->s_dev : 0; 2279 - __entry->type = dfp->dfp_type->type; 2279 + __entry->type = dfp->dfp_type; 2280 2280 __entry->intent = dfp->dfp_intent; 2281 2281 __entry->committed = dfp->dfp_done != NULL; 2282 2282 __entry->nr = dfp->dfp_count;
-1
fs/xfs/xfs_trans_bmap.c
··· 222 222 } 223 223 224 224 const struct xfs_defer_op_type xfs_bmap_update_defer_type = { 225 - .type = XFS_DEFER_OPS_TYPE_BMAP, 226 225 .max_items = XFS_BUI_MAX_FAST_EXTENTS, 227 226 .diff_items = xfs_bmap_update_diff_items, 228 227 .create_intent = xfs_bmap_update_create_intent,
-2
fs/xfs/xfs_trans_extfree.c
··· 208 208 } 209 209 210 210 const struct xfs_defer_op_type xfs_extent_free_defer_type = { 211 - .type = XFS_DEFER_OPS_TYPE_FREE, 212 211 .max_items = XFS_EFI_MAX_FAST_EXTENTS, 213 212 .diff_items = xfs_extent_free_diff_items, 214 213 .create_intent = xfs_extent_free_create_intent, ··· 275 276 276 277 /* sub-type with special handling for AGFL deferred frees */ 277 278 const struct xfs_defer_op_type xfs_agfl_free_defer_type = { 278 - .type = XFS_DEFER_OPS_TYPE_AGFL_FREE, 279 279 .max_items = XFS_EFI_MAX_FAST_EXTENTS, 280 280 .diff_items = xfs_extent_free_diff_items, 281 281 .create_intent = xfs_extent_free_create_intent,
-1
fs/xfs/xfs_trans_refcount.c
··· 229 229 } 230 230 231 231 const struct xfs_defer_op_type xfs_refcount_update_defer_type = { 232 - .type = XFS_DEFER_OPS_TYPE_REFCOUNT, 233 232 .max_items = XFS_CUI_MAX_FAST_EXTENTS, 234 233 .diff_items = xfs_refcount_update_diff_items, 235 234 .create_intent = xfs_refcount_update_create_intent,
-1
fs/xfs/xfs_trans_rmap.c
··· 246 246 } 247 247 248 248 const struct xfs_defer_op_type xfs_rmap_update_defer_type = { 249 - .type = XFS_DEFER_OPS_TYPE_RMAP, 250 249 .max_items = XFS_RUI_MAX_FAST_EXTENTS, 251 250 .diff_items = xfs_rmap_update_diff_items, 252 251 .create_intent = xfs_rmap_update_create_intent,