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

xfs: add a flag to release log items on commit

We have various items that are released from ->iop_comitting. Add a
flag to just call ->iop_release from the commit path to avoid tons
of boilerplate code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

authored by

Christoph Hellwig and committed by
Darrick J. Wong
9ce632a2 ddf92053

+18 -121
+1 -26
fs/xfs/xfs_bmap_item.c
··· 210 210 } 211 211 212 212 /* 213 - * When the bud item is committed to disk, all we need to do is delete our 214 - * reference to our partner bui item and then free ourselves. Since we're 215 - * freeing ourselves we must return -1 to keep the transaction code from 216 - * further referencing this item. 217 - */ 218 - STATIC xfs_lsn_t 219 - xfs_bud_item_committed( 220 - struct xfs_log_item *lip, 221 - xfs_lsn_t lsn) 222 - { 223 - struct xfs_bud_log_item *budp = BUD_ITEM(lip); 224 - 225 - /* 226 - * Drop the BUI reference regardless of whether the BUD has been 227 - * aborted. Once the BUD transaction is constructed, it is the sole 228 - * responsibility of the BUD to release the BUI (even if the BUI is 229 - * aborted due to log I/O error). 230 - */ 231 - xfs_bui_release(budp->bud_buip); 232 - kmem_zone_free(xfs_bud_zone, budp); 233 - 234 - return (xfs_lsn_t)-1; 235 - } 236 - 237 - /* 238 213 * This is the ops vector shared by all bud log items. 239 214 */ 240 215 static const struct xfs_item_ops xfs_bud_item_ops = { 216 + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 241 217 .iop_size = xfs_bud_item_size, 242 218 .iop_format = xfs_bud_item_format, 243 219 .iop_release = xfs_bud_item_release, 244 - .iop_committed = xfs_bud_item_committed, 245 220 }; 246 221 247 222 /*
+1 -26
fs/xfs/xfs_extfree_item.c
··· 309 309 } 310 310 311 311 /* 312 - * When the efd item is committed to disk, all we need to do is delete our 313 - * reference to our partner efi item and then free ourselves. Since we're 314 - * freeing ourselves we must return -1 to keep the transaction code from further 315 - * referencing this item. 316 - */ 317 - STATIC xfs_lsn_t 318 - xfs_efd_item_committed( 319 - struct xfs_log_item *lip, 320 - xfs_lsn_t lsn) 321 - { 322 - struct xfs_efd_log_item *efdp = EFD_ITEM(lip); 323 - 324 - /* 325 - * Drop the EFI reference regardless of whether the EFD has been 326 - * aborted. Once the EFD transaction is constructed, it is the sole 327 - * responsibility of the EFD to release the EFI (even if the EFI is 328 - * aborted due to log I/O error). 329 - */ 330 - xfs_efi_release(efdp->efd_efip); 331 - xfs_efd_item_free(efdp); 332 - 333 - return (xfs_lsn_t)-1; 334 - } 335 - 336 - /* 337 312 * This is the ops vector shared by all efd log items. 338 313 */ 339 314 static const struct xfs_item_ops xfs_efd_item_ops = { 315 + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 340 316 .iop_size = xfs_efd_item_size, 341 317 .iop_format = xfs_efd_item_format, 342 318 .iop_release = xfs_efd_item_release, 343 - .iop_committed = xfs_efd_item_committed, 344 319 }; 345 320 346 321 /*
+1 -17
fs/xfs/xfs_icreate_item.c
··· 64 64 } 65 65 66 66 /* 67 - * Because we have ordered buffers being tracked in the AIL for the inode 68 - * creation, we don't need the create item after this. Hence we can free 69 - * the log item and return -1 to tell the caller we're done with the item. 70 - */ 71 - STATIC xfs_lsn_t 72 - xfs_icreate_item_committed( 73 - struct xfs_log_item *lip, 74 - xfs_lsn_t lsn) 75 - { 76 - struct xfs_icreate_item *icp = ICR_ITEM(lip); 77 - 78 - kmem_zone_free(xfs_icreate_zone, icp); 79 - return (xfs_lsn_t)-1; 80 - } 81 - 82 - /* 83 67 * This is the ops vector shared by all buf log items. 84 68 */ 85 69 static const struct xfs_item_ops xfs_icreate_item_ops = { 70 + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 86 71 .iop_size = xfs_icreate_item_size, 87 72 .iop_format = xfs_icreate_item_format, 88 73 .iop_release = xfs_icreate_item_release, 89 - .iop_committed = xfs_icreate_item_committed, 90 74 }; 91 75 92 76
+1 -26
fs/xfs/xfs_refcount_item.c
··· 214 214 } 215 215 216 216 /* 217 - * When the cud item is committed to disk, all we need to do is delete our 218 - * reference to our partner cui item and then free ourselves. Since we're 219 - * freeing ourselves we must return -1 to keep the transaction code from 220 - * further referencing this item. 221 - */ 222 - STATIC xfs_lsn_t 223 - xfs_cud_item_committed( 224 - struct xfs_log_item *lip, 225 - xfs_lsn_t lsn) 226 - { 227 - struct xfs_cud_log_item *cudp = CUD_ITEM(lip); 228 - 229 - /* 230 - * Drop the CUI reference regardless of whether the CUD has been 231 - * aborted. Once the CUD transaction is constructed, it is the sole 232 - * responsibility of the CUD to release the CUI (even if the CUI is 233 - * aborted due to log I/O error). 234 - */ 235 - xfs_cui_release(cudp->cud_cuip); 236 - kmem_zone_free(xfs_cud_zone, cudp); 237 - 238 - return (xfs_lsn_t)-1; 239 - } 240 - 241 - /* 242 217 * This is the ops vector shared by all cud log items. 243 218 */ 244 219 static const struct xfs_item_ops xfs_cud_item_ops = { 220 + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 245 221 .iop_size = xfs_cud_item_size, 246 222 .iop_format = xfs_cud_item_format, 247 223 .iop_release = xfs_cud_item_release, 248 - .iop_committed = xfs_cud_item_committed, 249 224 }; 250 225 251 226 /*
+1 -26
fs/xfs/xfs_rmap_item.c
··· 235 235 } 236 236 237 237 /* 238 - * When the rud item is committed to disk, all we need to do is delete our 239 - * reference to our partner rui item and then free ourselves. Since we're 240 - * freeing ourselves we must return -1 to keep the transaction code from 241 - * further referencing this item. 242 - */ 243 - STATIC xfs_lsn_t 244 - xfs_rud_item_committed( 245 - struct xfs_log_item *lip, 246 - xfs_lsn_t lsn) 247 - { 248 - struct xfs_rud_log_item *rudp = RUD_ITEM(lip); 249 - 250 - /* 251 - * Drop the RUI reference regardless of whether the RUD has been 252 - * aborted. Once the RUD transaction is constructed, it is the sole 253 - * responsibility of the RUD to release the RUI (even if the RUI is 254 - * aborted due to log I/O error). 255 - */ 256 - xfs_rui_release(rudp->rud_ruip); 257 - kmem_zone_free(xfs_rud_zone, rudp); 258 - 259 - return (xfs_lsn_t)-1; 260 - } 261 - 262 - /* 263 238 * This is the ops vector shared by all rud log items. 264 239 */ 265 240 static const struct xfs_item_ops xfs_rud_item_ops = { 241 + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 266 242 .iop_size = xfs_rud_item_size, 267 243 .iop_format = xfs_rud_item_format, 268 244 .iop_release = xfs_rud_item_release, 269 - .iop_committed = xfs_rud_item_committed, 270 245 }; 271 246 272 247 /*
+6
fs/xfs/xfs_trans.c
··· 851 851 852 852 if (aborted) 853 853 set_bit(XFS_LI_ABORTED, &lip->li_flags); 854 + 855 + if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) { 856 + lip->li_ops->iop_release(lip); 857 + continue; 858 + } 859 + 854 860 if (lip->li_ops->iop_committed) 855 861 item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); 856 862 else
+7
fs/xfs/xfs_trans.h
··· 67 67 { (1 << XFS_LI_DIRTY), "DIRTY" } 68 68 69 69 struct xfs_item_ops { 70 + unsigned flags; 70 71 void (*iop_size)(xfs_log_item_t *, int *, int *); 71 72 void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); 72 73 void (*iop_pin)(xfs_log_item_t *); ··· 78 77 xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); 79 78 void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); 80 79 }; 80 + 81 + /* 82 + * Release the log item as soon as committed. This is for items just logging 83 + * intents that never need to be written back in place. 84 + */ 85 + #define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0) 81 86 82 87 void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, 83 88 int type, const struct xfs_item_ops *ops);