diff options
author | Christoph Hellwig <hch@lst.de> | 2019-06-28 22:27:32 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2019-06-28 22:27:32 -0400 |
commit | 9ce632a28a41bd9aeeaa3913d95b23648a82c2ee (patch) | |
tree | be33e14549bbef071ce6b0d23f45012a6876d437 | |
parent | ddf92053e45c0e07dcb031b56512d52f98cde517 (diff) |
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>
-rw-r--r-- | fs/xfs/xfs_bmap_item.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_extfree_item.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_icreate_item.c | 18 | ||||
-rw-r--r-- | fs/xfs/xfs_refcount_item.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_rmap_item.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 7 |
7 files changed, 18 insertions, 121 deletions
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index bb5fff120ef5..6c3c03770b3f 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c | |||
@@ -210,38 +210,13 @@ xfs_bud_item_release( | |||
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 | * This is the ops vector shared by all bud log items. | 213 | * This is the ops vector shared by all bud log items. |
239 | */ | 214 | */ |
240 | static const struct xfs_item_ops xfs_bud_item_ops = { | 215 | static const struct xfs_item_ops xfs_bud_item_ops = { |
216 | .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, | ||
241 | .iop_size = xfs_bud_item_size, | 217 | .iop_size = xfs_bud_item_size, |
242 | .iop_format = xfs_bud_item_format, | 218 | .iop_format = xfs_bud_item_format, |
243 | .iop_release = xfs_bud_item_release, | 219 | .iop_release = xfs_bud_item_release, |
244 | .iop_committed = xfs_bud_item_committed, | ||
245 | }; | 220 | }; |
246 | 221 | ||
247 | /* | 222 | /* |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 70df19007995..811923231bb7 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -309,38 +309,13 @@ xfs_efd_item_release( | |||
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 | * This is the ops vector shared by all efd log items. | 312 | * This is the ops vector shared by all efd log items. |
338 | */ | 313 | */ |
339 | static const struct xfs_item_ops xfs_efd_item_ops = { | 314 | static const struct xfs_item_ops xfs_efd_item_ops = { |
315 | .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, | ||
340 | .iop_size = xfs_efd_item_size, | 316 | .iop_size = xfs_efd_item_size, |
341 | .iop_format = xfs_efd_item_format, | 317 | .iop_format = xfs_efd_item_format, |
342 | .iop_release = xfs_efd_item_release, | 318 | .iop_release = xfs_efd_item_release, |
343 | .iop_committed = xfs_efd_item_committed, | ||
344 | }; | 319 | }; |
345 | 320 | ||
346 | /* | 321 | /* |
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c index 9aceb35dce24..ac9918da5f4a 100644 --- a/fs/xfs/xfs_icreate_item.c +++ b/fs/xfs/xfs_icreate_item.c | |||
@@ -64,29 +64,13 @@ xfs_icreate_item_release( | |||
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 | * This is the ops vector shared by all buf log items. | 67 | * This is the ops vector shared by all buf log items. |
84 | */ | 68 | */ |
85 | static const struct xfs_item_ops xfs_icreate_item_ops = { | 69 | static const struct xfs_item_ops xfs_icreate_item_ops = { |
70 | .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, | ||
86 | .iop_size = xfs_icreate_item_size, | 71 | .iop_size = xfs_icreate_item_size, |
87 | .iop_format = xfs_icreate_item_format, | 72 | .iop_format = xfs_icreate_item_format, |
88 | .iop_release = xfs_icreate_item_release, | 73 | .iop_release = xfs_icreate_item_release, |
89 | .iop_committed = xfs_icreate_item_committed, | ||
90 | }; | 74 | }; |
91 | 75 | ||
92 | 76 | ||
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 9f8fb23dcc81..5b03478c5d1f 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c | |||
@@ -214,38 +214,13 @@ xfs_cud_item_release( | |||
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 | * This is the ops vector shared by all cud log items. | 217 | * This is the ops vector shared by all cud log items. |
243 | */ | 218 | */ |
244 | static const struct xfs_item_ops xfs_cud_item_ops = { | 219 | static const struct xfs_item_ops xfs_cud_item_ops = { |
220 | .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, | ||
245 | .iop_size = xfs_cud_item_size, | 221 | .iop_size = xfs_cud_item_size, |
246 | .iop_format = xfs_cud_item_format, | 222 | .iop_format = xfs_cud_item_format, |
247 | .iop_release = xfs_cud_item_release, | 223 | .iop_release = xfs_cud_item_release, |
248 | .iop_committed = xfs_cud_item_committed, | ||
249 | }; | 224 | }; |
250 | 225 | ||
251 | /* | 226 | /* |
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c index e907bd169de5..3fbc7c5ffa96 100644 --- a/fs/xfs/xfs_rmap_item.c +++ b/fs/xfs/xfs_rmap_item.c | |||
@@ -235,38 +235,13 @@ xfs_rud_item_release( | |||
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 | * This is the ops vector shared by all rud log items. | 238 | * This is the ops vector shared by all rud log items. |
264 | */ | 239 | */ |
265 | static const struct xfs_item_ops xfs_rud_item_ops = { | 240 | static const struct xfs_item_ops xfs_rud_item_ops = { |
241 | .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, | ||
266 | .iop_size = xfs_rud_item_size, | 242 | .iop_size = xfs_rud_item_size, |
267 | .iop_format = xfs_rud_item_format, | 243 | .iop_format = xfs_rud_item_format, |
268 | .iop_release = xfs_rud_item_release, | 244 | .iop_release = xfs_rud_item_release, |
269 | .iop_committed = xfs_rud_item_committed, | ||
270 | }; | 245 | }; |
271 | 246 | ||
272 | /* | 247 | /* |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 261c51486d7a..b026f87608ce 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -851,6 +851,12 @@ xfs_trans_committed_bulk( | |||
851 | 851 | ||
852 | if (aborted) | 852 | if (aborted) |
853 | set_bit(XFS_LI_ABORTED, &lip->li_flags); | 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 | if (lip->li_ops->iop_committed) | 860 | if (lip->li_ops->iop_committed) |
855 | item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); | 861 | item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); |
856 | else | 862 | else |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 522c1d565aa4..ef5fd5db5350 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -67,6 +67,7 @@ typedef struct xfs_log_item { | |||
67 | { (1 << XFS_LI_DIRTY), "DIRTY" } | 67 | { (1 << XFS_LI_DIRTY), "DIRTY" } |
68 | 68 | ||
69 | struct xfs_item_ops { | 69 | struct xfs_item_ops { |
70 | unsigned flags; | ||
70 | void (*iop_size)(xfs_log_item_t *, int *, int *); | 71 | void (*iop_size)(xfs_log_item_t *, int *, int *); |
71 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); | 72 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); |
72 | void (*iop_pin)(xfs_log_item_t *); | 73 | void (*iop_pin)(xfs_log_item_t *); |
@@ -78,6 +79,12 @@ struct xfs_item_ops { | |||
78 | void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); | 79 | void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); |
79 | }; | 80 | }; |
80 | 81 | ||
82 | /* | ||
83 | * Release the log item as soon as committed. This is for items just logging | ||
84 | * intents that never need to be written back in place. | ||
85 | */ | ||
86 | #define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0) | ||
87 | |||
81 | void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, | 88 | void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, |
82 | int type, const struct xfs_item_ops *ops); | 89 | int type, const struct xfs_item_ops *ops); |
83 | 90 | ||