Skip to content

Commit 4c8900b

Browse files
author
Darrick J. Wong
committed
xfs: support logging EFIs for realtime extents
Teach the EFI mechanism how to free realtime extents. We're going to need this to enforce proper ordering of operations when we enable realtime rmap. Declare a new log intent item type (XFS_LI_EFI_RT) and a separate defer ops for rt extents. This keeps the ondisk artifacts and processing code completely separate between the rt and non-rt cases. Hopefully this will make it easier to debug filesystem problems. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent b57283e commit 4c8900b

File tree

9 files changed

+286
-39
lines changed

9 files changed

+286
-39
lines changed

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,8 +2648,17 @@ xfs_defer_extent_free(
26482648
ASSERT(!isnullstartblock(bno));
26492649
ASSERT(!(free_flags & ~XFS_FREE_EXTENT_ALL_FLAGS));
26502650

2651-
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbext(mp, bno, len)))
2652-
return -EFSCORRUPTED;
2651+
if (free_flags & XFS_FREE_EXTENT_REALTIME) {
2652+
if (type != XFS_AG_RESV_NONE) {
2653+
ASSERT(type == XFS_AG_RESV_NONE);
2654+
return -EFSCORRUPTED;
2655+
}
2656+
if (XFS_IS_CORRUPT(mp, !xfs_verify_rtbext(mp, bno, len)))
2657+
return -EFSCORRUPTED;
2658+
} else {
2659+
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbext(mp, bno, len)))
2660+
return -EFSCORRUPTED;
2661+
}
26532662

26542663
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
26552664
GFP_KERNEL | __GFP_NOFAIL);
@@ -2658,6 +2667,8 @@ xfs_defer_extent_free(
26582667
xefi->xefi_agresv = type;
26592668
if (free_flags & XFS_FREE_EXTENT_SKIP_DISCARD)
26602669
xefi->xefi_flags |= XFS_EFI_SKIP_DISCARD;
2670+
if (free_flags & XFS_FREE_EXTENT_REALTIME)
2671+
xefi->xefi_flags |= XFS_EFI_REALTIME;
26612672
if (oinfo) {
26622673
ASSERT(oinfo->oi_offset == 0);
26632674

fs/xfs/libxfs/xfs_alloc.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,11 @@ int xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
237237
/* Don't issue a discard for the blocks freed. */
238238
#define XFS_FREE_EXTENT_SKIP_DISCARD (1U << 0)
239239

240-
#define XFS_FREE_EXTENT_ALL_FLAGS (XFS_FREE_EXTENT_SKIP_DISCARD)
240+
/* Free blocks on the realtime device. */
241+
#define XFS_FREE_EXTENT_REALTIME (1U << 1)
242+
243+
#define XFS_FREE_EXTENT_ALL_FLAGS (XFS_FREE_EXTENT_SKIP_DISCARD | \
244+
XFS_FREE_EXTENT_REALTIME)
241245

242246
/*
243247
* List of extents to be free "later".
@@ -257,6 +261,12 @@ struct xfs_extent_free_item {
257261
#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
258262
#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */
259263
#define XFS_EFI_CANCELLED (1U << 3) /* dont actually free the space */
264+
#define XFS_EFI_REALTIME (1U << 4) /* freeing realtime extent */
265+
266+
static inline bool xfs_efi_is_realtime(const struct xfs_extent_free_item *xefi)
267+
{
268+
return xefi->xefi_flags & XFS_EFI_REALTIME;
269+
}
260270

261271
struct xfs_alloc_autoreap {
262272
struct xfs_defer_pending *dfp;

fs/xfs/libxfs/xfs_defer.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,12 @@ xfs_defer_add(
846846

847847
ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
848848

849+
if (!ops->finish_item) {
850+
ASSERT(ops->finish_item != NULL);
851+
xfs_force_shutdown(tp->t_mountp, SHUTDOWN_CORRUPT_INCORE);
852+
return NULL;
853+
}
854+
849855
dfp = xfs_defer_find_last(tp, ops);
850856
if (!dfp || !xfs_defer_can_append(dfp, ops))
851857
dfp = xfs_defer_alloc(&tp->t_dfops, ops);

fs/xfs/libxfs/xfs_defer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ extern const struct xfs_defer_op_type xfs_refcount_update_defer_type;
7171
extern const struct xfs_defer_op_type xfs_rmap_update_defer_type;
7272
extern const struct xfs_defer_op_type xfs_extent_free_defer_type;
7373
extern const struct xfs_defer_op_type xfs_agfl_free_defer_type;
74+
extern const struct xfs_defer_op_type xfs_rtextent_free_defer_type;
7475
extern const struct xfs_defer_op_type xfs_attr_defer_type;
7576
extern const struct xfs_defer_op_type xfs_exchmaps_defer_type;
7677

fs/xfs/libxfs/xfs_log_format.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ typedef struct xfs_trans_header {
248248
#define XFS_LI_ATTRD 0x1247 /* attr set/remove done */
249249
#define XFS_LI_XMI 0x1248 /* mapping exchange intent */
250250
#define XFS_LI_XMD 0x1249 /* mapping exchange done */
251+
#define XFS_LI_EFI_RT 0x124a /* realtime extent free intent */
252+
#define XFS_LI_EFD_RT 0x124b /* realtime extent free done */
251253

252254
#define XFS_LI_TYPE_DESC \
253255
{ XFS_LI_EFI, "XFS_LI_EFI" }, \
@@ -267,7 +269,9 @@ typedef struct xfs_trans_header {
267269
{ XFS_LI_ATTRI, "XFS_LI_ATTRI" }, \
268270
{ XFS_LI_ATTRD, "XFS_LI_ATTRD" }, \
269271
{ XFS_LI_XMI, "XFS_LI_XMI" }, \
270-
{ XFS_LI_XMD, "XFS_LI_XMD" }
272+
{ XFS_LI_XMD, "XFS_LI_XMD" }, \
273+
{ XFS_LI_EFI_RT, "XFS_LI_EFI_RT" }, \
274+
{ XFS_LI_EFD_RT, "XFS_LI_EFD_RT" }
271275

272276
/*
273277
* Inode Log Item Format definitions.

fs/xfs/libxfs/xfs_log_recover.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ extern const struct xlog_recover_item_ops xlog_attri_item_ops;
7777
extern const struct xlog_recover_item_ops xlog_attrd_item_ops;
7878
extern const struct xlog_recover_item_ops xlog_xmi_item_ops;
7979
extern const struct xlog_recover_item_ops xlog_xmd_item_ops;
80+
extern const struct xlog_recover_item_ops xlog_rtefi_item_ops;
81+
extern const struct xlog_recover_item_ops xlog_rtefd_item_ops;
8082

8183
/*
8284
* Macros, structures, prototypes for internal log manager use.

0 commit comments

Comments
 (0)