1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
8 #include "xfs_format.h"
9 #include "xfs_log_format.h"
10 #include "xfs_trans_resv.h"
12 #include "xfs_shared.h"
13 #include "xfs_mount.h"
15 #include "xfs_defer.h"
16 #include "xfs_trans.h"
17 #include "xfs_trans_priv.h"
18 #include "xfs_extfree_item.h"
20 #include "xfs_btree.h"
22 #include "xfs_alloc.h"
24 #include "xfs_trace.h"
25 #include "xfs_error.h"
26 #include "xfs_log_priv.h"
27 #include "xfs_log_recover.h"
29 struct kmem_cache
*xfs_efi_cache
;
30 struct kmem_cache
*xfs_efd_cache
;
32 static const struct xfs_item_ops xfs_efi_item_ops
;
34 static inline struct xfs_efi_log_item
*EFI_ITEM(struct xfs_log_item
*lip
)
36 return container_of(lip
, struct xfs_efi_log_item
, efi_item
);
41 struct xfs_efi_log_item
*efip
)
43 kvfree(efip
->efi_item
.li_lv_shadow
);
44 if (efip
->efi_format
.efi_nextents
> XFS_EFI_MAX_FAST_EXTENTS
)
47 kmem_cache_free(xfs_efi_cache
, efip
);
51 * Freeing the efi requires that we remove it from the AIL if it has already
52 * been placed there. However, the EFI may not yet have been placed in the AIL
53 * when called by xfs_efi_release() from EFD processing due to the ordering of
54 * committed vs unpin operations in bulk insert operations. Hence the reference
55 * count to ensure only the last caller frees the EFI.
59 struct xfs_efi_log_item
*efip
)
61 ASSERT(atomic_read(&efip
->efi_refcount
) > 0);
62 if (!atomic_dec_and_test(&efip
->efi_refcount
))
65 xfs_trans_ail_delete(&efip
->efi_item
, 0);
66 xfs_efi_item_free(efip
);
71 struct xfs_log_item
*lip
,
75 struct xfs_efi_log_item
*efip
= EFI_ITEM(lip
);
78 *nbytes
+= xfs_efi_log_format_sizeof(efip
->efi_format
.efi_nextents
);
82 * This is called to fill in the vector of log iovecs for the
83 * given efi log item. We use only 1 iovec, and we point that
84 * at the efi_log_format structure embedded in the efi item.
85 * It is at this point that we assert that all of the extent
86 * slots in the efi item have been filled.
90 struct xfs_log_item
*lip
,
91 struct xfs_log_vec
*lv
)
93 struct xfs_efi_log_item
*efip
= EFI_ITEM(lip
);
94 struct xfs_log_iovec
*vecp
= NULL
;
96 ASSERT(atomic_read(&efip
->efi_next_extent
) ==
97 efip
->efi_format
.efi_nextents
);
99 efip
->efi_format
.efi_type
= XFS_LI_EFI
;
100 efip
->efi_format
.efi_size
= 1;
102 xlog_copy_iovec(lv
, &vecp
, XLOG_REG_TYPE_EFI_FORMAT
,
104 xfs_efi_log_format_sizeof(efip
->efi_format
.efi_nextents
));
109 * The unpin operation is the last place an EFI is manipulated in the log. It is
110 * either inserted in the AIL or aborted in the event of a log I/O error. In
111 * either case, the EFI transaction has been successfully committed to make it
112 * this far. Therefore, we expect whoever committed the EFI to either construct
113 * and commit the EFD or drop the EFD's reference in the event of error. Simply
114 * drop the log's EFI reference now that the log is done with it.
118 struct xfs_log_item
*lip
,
121 struct xfs_efi_log_item
*efip
= EFI_ITEM(lip
);
122 xfs_efi_release(efip
);
126 * The EFI has been either committed or aborted if the transaction has been
127 * cancelled. If the transaction was cancelled, an EFD isn't going to be
128 * constructed and thus we free the EFI here directly.
131 xfs_efi_item_release(
132 struct xfs_log_item
*lip
)
134 xfs_efi_release(EFI_ITEM(lip
));
138 * Allocate and initialize an efi item with the given number of extents.
140 STATIC
struct xfs_efi_log_item
*
142 struct xfs_mount
*mp
,
146 struct xfs_efi_log_item
*efip
;
148 ASSERT(nextents
> 0);
149 if (nextents
> XFS_EFI_MAX_FAST_EXTENTS
) {
150 efip
= kzalloc(xfs_efi_log_item_sizeof(nextents
),
151 GFP_KERNEL
| __GFP_NOFAIL
);
153 efip
= kmem_cache_zalloc(xfs_efi_cache
,
154 GFP_KERNEL
| __GFP_NOFAIL
);
157 xfs_log_item_init(mp
, &efip
->efi_item
, XFS_LI_EFI
, &xfs_efi_item_ops
);
158 efip
->efi_format
.efi_nextents
= nextents
;
159 efip
->efi_format
.efi_id
= (uintptr_t)(void *)efip
;
160 atomic_set(&efip
->efi_next_extent
, 0);
161 atomic_set(&efip
->efi_refcount
, 2);
167 * Copy an EFI format buffer from the given buf, and into the destination
168 * EFI format structure.
169 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
170 * one of which will be the native format for this kernel.
171 * It will handle the conversion of formats if necessary.
174 xfs_efi_copy_format(xfs_log_iovec_t
*buf
, xfs_efi_log_format_t
*dst_efi_fmt
)
176 xfs_efi_log_format_t
*src_efi_fmt
= buf
->i_addr
;
178 uint len
= xfs_efi_log_format_sizeof(src_efi_fmt
->efi_nextents
);
179 uint len32
= xfs_efi_log_format32_sizeof(src_efi_fmt
->efi_nextents
);
180 uint len64
= xfs_efi_log_format64_sizeof(src_efi_fmt
->efi_nextents
);
182 if (buf
->i_len
== len
) {
183 memcpy(dst_efi_fmt
, src_efi_fmt
,
184 offsetof(struct xfs_efi_log_format
, efi_extents
));
185 for (i
= 0; i
< src_efi_fmt
->efi_nextents
; i
++)
186 memcpy(&dst_efi_fmt
->efi_extents
[i
],
187 &src_efi_fmt
->efi_extents
[i
],
188 sizeof(struct xfs_extent
));
190 } else if (buf
->i_len
== len32
) {
191 xfs_efi_log_format_32_t
*src_efi_fmt_32
= buf
->i_addr
;
193 dst_efi_fmt
->efi_type
= src_efi_fmt_32
->efi_type
;
194 dst_efi_fmt
->efi_size
= src_efi_fmt_32
->efi_size
;
195 dst_efi_fmt
->efi_nextents
= src_efi_fmt_32
->efi_nextents
;
196 dst_efi_fmt
->efi_id
= src_efi_fmt_32
->efi_id
;
197 for (i
= 0; i
< dst_efi_fmt
->efi_nextents
; i
++) {
198 dst_efi_fmt
->efi_extents
[i
].ext_start
=
199 src_efi_fmt_32
->efi_extents
[i
].ext_start
;
200 dst_efi_fmt
->efi_extents
[i
].ext_len
=
201 src_efi_fmt_32
->efi_extents
[i
].ext_len
;
204 } else if (buf
->i_len
== len64
) {
205 xfs_efi_log_format_64_t
*src_efi_fmt_64
= buf
->i_addr
;
207 dst_efi_fmt
->efi_type
= src_efi_fmt_64
->efi_type
;
208 dst_efi_fmt
->efi_size
= src_efi_fmt_64
->efi_size
;
209 dst_efi_fmt
->efi_nextents
= src_efi_fmt_64
->efi_nextents
;
210 dst_efi_fmt
->efi_id
= src_efi_fmt_64
->efi_id
;
211 for (i
= 0; i
< dst_efi_fmt
->efi_nextents
; i
++) {
212 dst_efi_fmt
->efi_extents
[i
].ext_start
=
213 src_efi_fmt_64
->efi_extents
[i
].ext_start
;
214 dst_efi_fmt
->efi_extents
[i
].ext_len
=
215 src_efi_fmt_64
->efi_extents
[i
].ext_len
;
219 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, NULL
, buf
->i_addr
,
221 return -EFSCORRUPTED
;
224 static inline struct xfs_efd_log_item
*EFD_ITEM(struct xfs_log_item
*lip
)
226 return container_of(lip
, struct xfs_efd_log_item
, efd_item
);
230 xfs_efd_item_free(struct xfs_efd_log_item
*efdp
)
232 kvfree(efdp
->efd_item
.li_lv_shadow
);
233 if (efdp
->efd_format
.efd_nextents
> XFS_EFD_MAX_FAST_EXTENTS
)
236 kmem_cache_free(xfs_efd_cache
, efdp
);
241 struct xfs_log_item
*lip
,
245 struct xfs_efd_log_item
*efdp
= EFD_ITEM(lip
);
248 *nbytes
+= xfs_efd_log_format_sizeof(efdp
->efd_format
.efd_nextents
);
252 * This is called to fill in the vector of log iovecs for the
253 * given efd log item. We use only 1 iovec, and we point that
254 * at the efd_log_format structure embedded in the efd item.
255 * It is at this point that we assert that all of the extent
256 * slots in the efd item have been filled.
260 struct xfs_log_item
*lip
,
261 struct xfs_log_vec
*lv
)
263 struct xfs_efd_log_item
*efdp
= EFD_ITEM(lip
);
264 struct xfs_log_iovec
*vecp
= NULL
;
266 ASSERT(efdp
->efd_next_extent
== efdp
->efd_format
.efd_nextents
);
268 efdp
->efd_format
.efd_type
= XFS_LI_EFD
;
269 efdp
->efd_format
.efd_size
= 1;
271 xlog_copy_iovec(lv
, &vecp
, XLOG_REG_TYPE_EFD_FORMAT
,
273 xfs_efd_log_format_sizeof(efdp
->efd_format
.efd_nextents
));
277 * The EFD is either committed or aborted if the transaction is cancelled. If
278 * the transaction is cancelled, drop our reference to the EFI and free the EFD.
281 xfs_efd_item_release(
282 struct xfs_log_item
*lip
)
284 struct xfs_efd_log_item
*efdp
= EFD_ITEM(lip
);
286 xfs_efi_release(efdp
->efd_efip
);
287 xfs_efd_item_free(efdp
);
290 static struct xfs_log_item
*
292 struct xfs_log_item
*lip
)
294 return &EFD_ITEM(lip
)->efd_efip
->efi_item
;
297 static const struct xfs_item_ops xfs_efd_item_ops
= {
298 .flags
= XFS_ITEM_RELEASE_WHEN_COMMITTED
|
299 XFS_ITEM_INTENT_DONE
,
300 .iop_size
= xfs_efd_item_size
,
301 .iop_format
= xfs_efd_item_format
,
302 .iop_release
= xfs_efd_item_release
,
303 .iop_intent
= xfs_efd_item_intent
,
306 static inline struct xfs_extent_free_item
*xefi_entry(const struct list_head
*e
)
308 return list_entry(e
, struct xfs_extent_free_item
, xefi_list
);
312 * Fill the EFD with all extents from the EFI when we need to roll the
313 * transaction and continue with a new EFI.
315 * This simply copies all the extents in the EFI to the EFD rather than make
316 * assumptions about which extents in the EFI have already been processed. We
317 * currently keep the xefi list in the same order as the EFI extent list, but
318 * that may not always be the case. Copying everything avoids leaving a landmine
319 * were we fail to cancel all the extents in an EFI if the xefi list is
320 * processed in a different order to the extents in the EFI.
324 struct xfs_efd_log_item
*efdp
)
326 struct xfs_efi_log_item
*efip
= efdp
->efd_efip
;
329 ASSERT(efip
->efi_format
.efi_nextents
> 0);
330 ASSERT(efdp
->efd_next_extent
< efip
->efi_format
.efi_nextents
);
332 for (i
= 0; i
< efip
->efi_format
.efi_nextents
; i
++) {
333 efdp
->efd_format
.efd_extents
[i
] =
334 efip
->efi_format
.efi_extents
[i
];
336 efdp
->efd_next_extent
= efip
->efi_format
.efi_nextents
;
341 struct xfs_efd_log_item
*efdp
,
342 struct xfs_extent_free_item
*xefi
)
344 struct xfs_extent
*extp
;
346 ASSERT(efdp
->efd_next_extent
< efdp
->efd_format
.efd_nextents
);
348 extp
= &efdp
->efd_format
.efd_extents
[efdp
->efd_next_extent
];
349 extp
->ext_start
= xefi
->xefi_startblock
;
350 extp
->ext_len
= xefi
->xefi_blockcount
;
352 efdp
->efd_next_extent
++;
355 /* Sort bmap items by AG. */
357 xfs_extent_free_diff_items(
359 const struct list_head
*a
,
360 const struct list_head
*b
)
362 struct xfs_extent_free_item
*ra
= xefi_entry(a
);
363 struct xfs_extent_free_item
*rb
= xefi_entry(b
);
365 return ra
->xefi_pag
->pag_agno
- rb
->xefi_pag
->pag_agno
;
368 /* Log a free extent to the intent item. */
370 xfs_extent_free_log_item(
371 struct xfs_trans
*tp
,
372 struct xfs_efi_log_item
*efip
,
373 struct xfs_extent_free_item
*xefi
)
376 struct xfs_extent
*extp
;
379 * atomic_inc_return gives us the value after the increment;
380 * we want to use it as an array index so we need to subtract 1 from
383 next_extent
= atomic_inc_return(&efip
->efi_next_extent
) - 1;
384 ASSERT(next_extent
< efip
->efi_format
.efi_nextents
);
385 extp
= &efip
->efi_format
.efi_extents
[next_extent
];
386 extp
->ext_start
= xefi
->xefi_startblock
;
387 extp
->ext_len
= xefi
->xefi_blockcount
;
390 static struct xfs_log_item
*
391 xfs_extent_free_create_intent(
392 struct xfs_trans
*tp
,
393 struct list_head
*items
,
397 struct xfs_mount
*mp
= tp
->t_mountp
;
398 struct xfs_efi_log_item
*efip
= xfs_efi_init(mp
, count
);
399 struct xfs_extent_free_item
*xefi
;
404 list_sort(mp
, items
, xfs_extent_free_diff_items
);
405 list_for_each_entry(xefi
, items
, xefi_list
)
406 xfs_extent_free_log_item(tp
, efip
, xefi
);
407 return &efip
->efi_item
;
410 /* Get an EFD so we can process all the free extents. */
411 static struct xfs_log_item
*
412 xfs_extent_free_create_done(
413 struct xfs_trans
*tp
,
414 struct xfs_log_item
*intent
,
417 struct xfs_efi_log_item
*efip
= EFI_ITEM(intent
);
418 struct xfs_efd_log_item
*efdp
;
422 if (count
> XFS_EFD_MAX_FAST_EXTENTS
) {
423 efdp
= kzalloc(xfs_efd_log_item_sizeof(count
),
424 GFP_KERNEL
| __GFP_NOFAIL
);
426 efdp
= kmem_cache_zalloc(xfs_efd_cache
,
427 GFP_KERNEL
| __GFP_NOFAIL
);
430 xfs_log_item_init(tp
->t_mountp
, &efdp
->efd_item
, XFS_LI_EFD
,
432 efdp
->efd_efip
= efip
;
433 efdp
->efd_format
.efd_nextents
= count
;
434 efdp
->efd_format
.efd_efi_id
= efip
->efi_format
.efi_id
;
436 return &efdp
->efd_item
;
439 /* Add this deferred EFI to the transaction. */
441 xfs_extent_free_defer_add(
442 struct xfs_trans
*tp
,
443 struct xfs_extent_free_item
*xefi
,
444 struct xfs_defer_pending
**dfpp
)
446 struct xfs_mount
*mp
= tp
->t_mountp
;
448 trace_xfs_extent_free_defer(mp
, xefi
);
450 xefi
->xefi_pag
= xfs_perag_intent_get(mp
, xefi
->xefi_startblock
);
451 if (xefi
->xefi_agresv
== XFS_AG_RESV_AGFL
)
452 *dfpp
= xfs_defer_add(tp
, &xefi
->xefi_list
,
453 &xfs_agfl_free_defer_type
);
455 *dfpp
= xfs_defer_add(tp
, &xefi
->xefi_list
,
456 &xfs_extent_free_defer_type
);
459 /* Cancel a free extent. */
461 xfs_extent_free_cancel_item(
462 struct list_head
*item
)
464 struct xfs_extent_free_item
*xefi
= xefi_entry(item
);
466 xfs_perag_intent_put(xefi
->xefi_pag
);
467 kmem_cache_free(xfs_extfree_item_cache
, xefi
);
470 /* Process a free extent. */
472 xfs_extent_free_finish_item(
473 struct xfs_trans
*tp
,
474 struct xfs_log_item
*done
,
475 struct list_head
*item
,
476 struct xfs_btree_cur
**state
)
478 struct xfs_owner_info oinfo
= { };
479 struct xfs_extent_free_item
*xefi
= xefi_entry(item
);
480 struct xfs_efd_log_item
*efdp
= EFD_ITEM(done
);
481 struct xfs_mount
*mp
= tp
->t_mountp
;
485 agbno
= XFS_FSB_TO_AGBNO(mp
, xefi
->xefi_startblock
);
487 oinfo
.oi_owner
= xefi
->xefi_owner
;
488 if (xefi
->xefi_flags
& XFS_EFI_ATTR_FORK
)
489 oinfo
.oi_flags
|= XFS_OWNER_INFO_ATTR_FORK
;
490 if (xefi
->xefi_flags
& XFS_EFI_BMBT_BLOCK
)
491 oinfo
.oi_flags
|= XFS_OWNER_INFO_BMBT_BLOCK
;
493 trace_xfs_extent_free_deferred(mp
, xefi
);
496 * If we need a new transaction to make progress, the caller will log a
497 * new EFI with the current contents. It will also log an EFD to cancel
498 * the existing EFI, and so we need to copy all the unprocessed extents
499 * in this EFI to the EFD so this works correctly.
501 if (!(xefi
->xefi_flags
& XFS_EFI_CANCELLED
))
502 error
= __xfs_free_extent(tp
, xefi
->xefi_pag
, agbno
,
503 xefi
->xefi_blockcount
, &oinfo
, xefi
->xefi_agresv
,
504 xefi
->xefi_flags
& XFS_EFI_SKIP_DISCARD
);
505 if (error
== -EAGAIN
) {
506 xfs_efd_from_efi(efdp
);
510 xfs_efd_add_extent(efdp
, xefi
);
511 xfs_extent_free_cancel_item(item
);
515 /* Abort all pending EFIs. */
517 xfs_extent_free_abort_intent(
518 struct xfs_log_item
*intent
)
520 xfs_efi_release(EFI_ITEM(intent
));
524 * AGFL blocks are accounted differently in the reserve pools and are not
525 * inserted into the busy extent list.
528 xfs_agfl_free_finish_item(
529 struct xfs_trans
*tp
,
530 struct xfs_log_item
*done
,
531 struct list_head
*item
,
532 struct xfs_btree_cur
**state
)
534 struct xfs_owner_info oinfo
= { };
535 struct xfs_mount
*mp
= tp
->t_mountp
;
536 struct xfs_efd_log_item
*efdp
= EFD_ITEM(done
);
537 struct xfs_extent_free_item
*xefi
= xefi_entry(item
);
538 struct xfs_buf
*agbp
;
542 ASSERT(xefi
->xefi_blockcount
== 1);
543 agbno
= XFS_FSB_TO_AGBNO(mp
, xefi
->xefi_startblock
);
544 oinfo
.oi_owner
= xefi
->xefi_owner
;
546 trace_xfs_agfl_free_deferred(mp
, xefi
);
548 error
= xfs_alloc_read_agf(xefi
->xefi_pag
, tp
, 0, &agbp
);
550 error
= xfs_free_ag_extent(tp
, agbp
, xefi
->xefi_pag
->pag_agno
,
551 agbno
, 1, &oinfo
, XFS_AG_RESV_AGFL
);
553 xfs_efd_add_extent(efdp
, xefi
);
554 xfs_extent_free_cancel_item(&xefi
->xefi_list
);
558 /* Is this recovered EFI ok? */
560 xfs_efi_validate_ext(
561 struct xfs_mount
*mp
,
562 struct xfs_extent
*extp
)
564 return xfs_verify_fsbext(mp
, extp
->ext_start
, extp
->ext_len
);
568 xfs_efi_recover_work(
569 struct xfs_mount
*mp
,
570 struct xfs_defer_pending
*dfp
,
571 struct xfs_extent
*extp
)
573 struct xfs_extent_free_item
*xefi
;
575 xefi
= kmem_cache_zalloc(xfs_extfree_item_cache
,
576 GFP_KERNEL
| __GFP_NOFAIL
);
577 xefi
->xefi_startblock
= extp
->ext_start
;
578 xefi
->xefi_blockcount
= extp
->ext_len
;
579 xefi
->xefi_agresv
= XFS_AG_RESV_NONE
;
580 xefi
->xefi_owner
= XFS_RMAP_OWN_UNKNOWN
;
581 xefi
->xefi_pag
= xfs_perag_intent_get(mp
, extp
->ext_start
);
583 xfs_defer_add_item(dfp
, &xefi
->xefi_list
);
587 * Process an extent free intent item that was recovered from
588 * the log. We need to free the extents that it describes.
591 xfs_extent_free_recover_work(
592 struct xfs_defer_pending
*dfp
,
593 struct list_head
*capture_list
)
595 struct xfs_trans_res resv
;
596 struct xfs_log_item
*lip
= dfp
->dfp_intent
;
597 struct xfs_efi_log_item
*efip
= EFI_ITEM(lip
);
598 struct xfs_mount
*mp
= lip
->li_log
->l_mp
;
599 struct xfs_trans
*tp
;
604 * First check the validity of the extents described by the
605 * EFI. If any are bad, then assume that all are bad and
608 for (i
= 0; i
< efip
->efi_format
.efi_nextents
; i
++) {
609 if (!xfs_efi_validate_ext(mp
,
610 &efip
->efi_format
.efi_extents
[i
])) {
611 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
,
613 sizeof(efip
->efi_format
));
614 return -EFSCORRUPTED
;
617 xfs_efi_recover_work(mp
, dfp
, &efip
->efi_format
.efi_extents
[i
]);
620 resv
= xlog_recover_resv(&M_RES(mp
)->tr_itruncate
);
621 error
= xfs_trans_alloc(mp
, &resv
, 0, 0, 0, &tp
);
625 error
= xlog_recover_finish_intent(tp
, dfp
);
626 if (error
== -EFSCORRUPTED
)
627 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
,
629 sizeof(efip
->efi_format
));
633 return xfs_defer_ops_capture_and_commit(tp
, capture_list
);
636 xfs_trans_cancel(tp
);
640 /* Relog an intent item to push the log tail forward. */
641 static struct xfs_log_item
*
642 xfs_extent_free_relog_intent(
643 struct xfs_trans
*tp
,
644 struct xfs_log_item
*intent
,
645 struct xfs_log_item
*done_item
)
647 struct xfs_efd_log_item
*efdp
= EFD_ITEM(done_item
);
648 struct xfs_efi_log_item
*efip
;
649 struct xfs_extent
*extp
;
652 count
= EFI_ITEM(intent
)->efi_format
.efi_nextents
;
653 extp
= EFI_ITEM(intent
)->efi_format
.efi_extents
;
655 efdp
->efd_next_extent
= count
;
656 memcpy(efdp
->efd_format
.efd_extents
, extp
, count
* sizeof(*extp
));
658 efip
= xfs_efi_init(tp
->t_mountp
, count
);
659 memcpy(efip
->efi_format
.efi_extents
, extp
, count
* sizeof(*extp
));
660 atomic_set(&efip
->efi_next_extent
, count
);
662 return &efip
->efi_item
;
665 const struct xfs_defer_op_type xfs_extent_free_defer_type
= {
666 .name
= "extent_free",
667 .max_items
= XFS_EFI_MAX_FAST_EXTENTS
,
668 .create_intent
= xfs_extent_free_create_intent
,
669 .abort_intent
= xfs_extent_free_abort_intent
,
670 .create_done
= xfs_extent_free_create_done
,
671 .finish_item
= xfs_extent_free_finish_item
,
672 .cancel_item
= xfs_extent_free_cancel_item
,
673 .recover_work
= xfs_extent_free_recover_work
,
674 .relog_intent
= xfs_extent_free_relog_intent
,
677 /* sub-type with special handling for AGFL deferred frees */
678 const struct xfs_defer_op_type xfs_agfl_free_defer_type
= {
680 .max_items
= XFS_EFI_MAX_FAST_EXTENTS
,
681 .create_intent
= xfs_extent_free_create_intent
,
682 .abort_intent
= xfs_extent_free_abort_intent
,
683 .create_done
= xfs_extent_free_create_done
,
684 .finish_item
= xfs_agfl_free_finish_item
,
685 .cancel_item
= xfs_extent_free_cancel_item
,
686 .recover_work
= xfs_extent_free_recover_work
,
687 .relog_intent
= xfs_extent_free_relog_intent
,
692 struct xfs_log_item
*lip
,
695 return EFI_ITEM(lip
)->efi_format
.efi_id
== intent_id
;
698 static const struct xfs_item_ops xfs_efi_item_ops
= {
699 .flags
= XFS_ITEM_INTENT
,
700 .iop_size
= xfs_efi_item_size
,
701 .iop_format
= xfs_efi_item_format
,
702 .iop_unpin
= xfs_efi_item_unpin
,
703 .iop_release
= xfs_efi_item_release
,
704 .iop_match
= xfs_efi_item_match
,
708 * This routine is called to create an in-core extent free intent
709 * item from the efi format structure which was logged on disk.
710 * It allocates an in-core efi, copies the extents from the format
711 * structure into it, and adds the efi to the AIL with the given
715 xlog_recover_efi_commit_pass2(
717 struct list_head
*buffer_list
,
718 struct xlog_recover_item
*item
,
721 struct xfs_mount
*mp
= log
->l_mp
;
722 struct xfs_efi_log_item
*efip
;
723 struct xfs_efi_log_format
*efi_formatp
;
726 efi_formatp
= item
->ri_buf
[0].i_addr
;
728 if (item
->ri_buf
[0].i_len
< xfs_efi_log_format_sizeof(0)) {
729 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
,
730 item
->ri_buf
[0].i_addr
, item
->ri_buf
[0].i_len
);
731 return -EFSCORRUPTED
;
734 efip
= xfs_efi_init(mp
, efi_formatp
->efi_nextents
);
735 error
= xfs_efi_copy_format(&item
->ri_buf
[0], &efip
->efi_format
);
737 xfs_efi_item_free(efip
);
740 atomic_set(&efip
->efi_next_extent
, efi_formatp
->efi_nextents
);
742 xlog_recover_intent_item(log
, &efip
->efi_item
, lsn
,
743 &xfs_extent_free_defer_type
);
747 const struct xlog_recover_item_ops xlog_efi_item_ops
= {
748 .item_type
= XFS_LI_EFI
,
749 .commit_pass2
= xlog_recover_efi_commit_pass2
,
753 * This routine is called when an EFD format structure is found in a committed
754 * transaction in the log. Its purpose is to cancel the corresponding EFI if it
755 * was still in the log. To do this it searches the AIL for the EFI with an id
756 * equal to that in the EFD format structure. If we find it we drop the EFD
757 * reference, which removes the EFI from the AIL and frees it.
760 xlog_recover_efd_commit_pass2(
762 struct list_head
*buffer_list
,
763 struct xlog_recover_item
*item
,
766 struct xfs_efd_log_format
*efd_formatp
;
767 int buflen
= item
->ri_buf
[0].i_len
;
769 efd_formatp
= item
->ri_buf
[0].i_addr
;
771 if (buflen
< sizeof(struct xfs_efd_log_format
)) {
772 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, log
->l_mp
,
773 efd_formatp
, buflen
);
774 return -EFSCORRUPTED
;
777 if (item
->ri_buf
[0].i_len
!= xfs_efd_log_format32_sizeof(
778 efd_formatp
->efd_nextents
) &&
779 item
->ri_buf
[0].i_len
!= xfs_efd_log_format64_sizeof(
780 efd_formatp
->efd_nextents
)) {
781 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, log
->l_mp
,
782 efd_formatp
, buflen
);
783 return -EFSCORRUPTED
;
786 xlog_recover_release_intent(log
, XFS_LI_EFI
, efd_formatp
->efd_efi_id
);
790 const struct xlog_recover_item_ops xlog_efd_item_ops
= {
791 .item_type
= XFS_LI_EFD
,
792 .commit_pass2
= xlog_recover_efd_commit_pass2
,