From: Chandan Babu R <chandan.babu@oracle.com>
To: linux-xfs@vger.kernel.org
Cc: Chandan Babu R <chandan.babu@oracle.com>,
djwong@kernel.org, david@fromorbit.com
Subject: [PATCH V8 16/19] xfs: Conditionally upgrade existing inodes to use large extent counters
Date: Mon, 21 Mar 2022 10:47:47 +0530 [thread overview]
Message-ID: <20220321051750.400056-17-chandan.babu@oracle.com> (raw)
In-Reply-To: <20220321051750.400056-1-chandan.babu@oracle.com>
This commit enables upgrading existing inodes to use large extent counters
provided that underlying filesystem's superblock has large extent counter
feature enabled.
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
---
fs/xfs/libxfs/xfs_attr.c | 9 ++++++-
fs/xfs/libxfs/xfs_bmap.c | 10 ++++++--
fs/xfs/libxfs/xfs_inode_fork.c | 27 +++++++++++++++++++++
fs/xfs/libxfs/xfs_inode_fork.h | 2 ++
fs/xfs/xfs_bmap_item.c | 8 ++++++-
fs/xfs/xfs_bmap_util.c | 43 ++++++++++++++++++++++++++++++----
fs/xfs/xfs_dquot.c | 9 ++++++-
fs/xfs/xfs_iomap.c | 17 ++++++++++++--
fs/xfs/xfs_reflink.c | 17 ++++++++++++--
fs/xfs/xfs_rtalloc.c | 9 ++++++-
10 files changed, 136 insertions(+), 15 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 23523b802539..6e56aa17fd82 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -776,8 +776,15 @@ xfs_attr_set(
if (args->value || xfs_inode_hasattr(dp)) {
error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
+
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(args->trans, dp,
+ XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
+ if (error)
+ goto out_trans_cancel;
+ }
}
error = xfs_attr_lookup(args);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 5a089674c666..0cb915bf8285 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -4524,13 +4524,19 @@ xfs_bmapi_convert_delalloc(
return error;
xfs_ilock(ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, ip, 0);
error = xfs_iext_count_may_overflow(ip, whichfork,
XFS_IEXT_ADD_NOSPLIT_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
- xfs_trans_ijoin(tp, ip, 0);
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_ADD_NOSPLIT_CNT);
+ if (error)
+ goto out_trans_cancel;
+ }
if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &bma.icur, &bma.got) ||
bma.got.br_startoff > offset_fsb) {
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index bb5d841aac58..aff9242db829 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -756,3 +756,30 @@ xfs_iext_count_may_overflow(
return 0;
}
+
+int
+xfs_iext_count_upgrade(
+ struct xfs_trans *tp,
+ struct xfs_inode *ip,
+ int nr_to_add)
+{
+ if (!xfs_has_large_extent_counts(ip->i_mount) ||
+ (ip->i_diflags2 & XFS_DIFLAG2_NREXT64) ||
+ XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
+ return -EFBIG;
+
+ ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+ /*
+ * The value of nr_to_add cannot be larger than 2^17
+ *
+ * - XFS_MAX_EXTCNT_ATTR_FORK_LARGE - XFS_MAX_EXTCNT_ATTR_FORK_SMALL
+ * i.e. 2^32 - 2^15
+ * - XFS_MAX_EXTCNT_DATA_FORK_LARGE - XFS_MAX_EXTCNT_DATA_FORK_SMALL
+ * i.e. 2^48 - 2^31
+ */
+ ASSERT(nr_to_add <= (1 << 17));
+
+ return 0;
+}
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h
index fd5c3c2d77e0..f2fe513e7252 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.h
+++ b/fs/xfs/libxfs/xfs_inode_fork.h
@@ -288,6 +288,8 @@ int xfs_ifork_verify_local_data(struct xfs_inode *ip);
int xfs_ifork_verify_local_attr(struct xfs_inode *ip);
int xfs_iext_count_may_overflow(struct xfs_inode *ip, int whichfork,
int nr_to_add);
+int xfs_iext_count_upgrade(struct xfs_trans *tp, struct xfs_inode *ip,
+ int nr_to_add);
/* returns true if the fork has extents but they are not read in yet. */
static inline bool xfs_need_iread_extents(struct xfs_ifork *ifp)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index e1f4d7d5a011..e8729abc15ab 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -506,9 +506,15 @@ xfs_bui_item_recover(
iext_delta = XFS_IEXT_PUNCH_HOLE_CNT;
error = xfs_iext_count_may_overflow(ip, whichfork, iext_delta);
- if (error)
+ if (error && error != -EFBIG)
goto err_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip, iext_delta);
+ if (error)
+ goto err_cancel;
+ }
+
count = bmap->me_len;
error = xfs_trans_log_finish_bmap_update(tp, budp, bui_type, ip,
whichfork, bmap->me_startoff, bmap->me_startblock,
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 18c1b99311a8..9f7112625934 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -859,9 +859,16 @@ xfs_alloc_file_space(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_ADD_NOSPLIT_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto error;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_ADD_NOSPLIT_CNT);
+ if (error)
+ goto error;
+ }
+
error = xfs_bmapi_write(tp, ip, startoffset_fsb,
allocatesize_fsb, XFS_BMAPI_PREALLOC, 0, imapp,
&nimaps);
@@ -914,9 +921,15 @@ xfs_unmap_extent(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_PUNCH_HOLE_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip, XFS_IEXT_PUNCH_HOLE_CNT);
+ if (error)
+ goto out_trans_cancel;
+ }
+
error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done);
if (error)
goto out_trans_cancel;
@@ -1195,9 +1208,15 @@ xfs_insert_file_space(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_PUNCH_HOLE_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip, XFS_IEXT_PUNCH_HOLE_CNT);
+ if (error)
+ goto out_trans_cancel;
+ }
+
/*
* The extent shifting code works on extent granularity. So, if stop_fsb
* is not the starting block of extent, we need to split the extent at
@@ -1423,16 +1442,30 @@ xfs_swap_extent_rmap(
error = xfs_iext_count_may_overflow(ip,
XFS_DATA_FORK,
XFS_IEXT_SWAP_RMAP_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out;
+
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_SWAP_RMAP_CNT);
+ if (error)
+ goto out;
+ }
}
if (xfs_bmap_is_real_extent(&irec)) {
error = xfs_iext_count_may_overflow(tip,
XFS_DATA_FORK,
XFS_IEXT_SWAP_RMAP_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out;
+
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_SWAP_RMAP_CNT);
+ if (error)
+ goto out;
+ }
}
/* Remove the mapping from the donor file. */
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 5afedcbc78c7..8b8fc98a01eb 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -322,9 +322,16 @@ xfs_dquot_disk_alloc(
error = xfs_iext_count_may_overflow(quotip, XFS_DATA_FORK,
XFS_IEXT_ADD_NOSPLIT_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto err_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, quotip,
+ XFS_IEXT_ADD_NOSPLIT_CNT);
+ if (error)
+ goto err_cancel;
+ }
+
/* Create the block mapping. */
error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset,
XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0, &map,
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 87e1cf5060bd..57c3c2ccb07b 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -251,9 +251,15 @@ xfs_iomap_write_direct(
return error;
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK, nr_exts);
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip, nr_exts);
+ if (error)
+ goto out_trans_cancel;
+ }
+
/*
* From this point onwards we overwrite the imap pointer that the
* caller gave to us.
@@ -555,9 +561,16 @@ xfs_iomap_write_unwritten(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_WRITE_UNWRITTEN_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto error_on_bmapi_transaction;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_WRITE_UNWRITTEN_CNT);
+ if (error)
+ goto error_on_bmapi_transaction;
+ }
+
/*
* Modify the unwritten extent state of the buffer.
*/
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index db70060e7bf6..04717be330d7 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -617,9 +617,16 @@ xfs_reflink_end_cow_extent(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_REFLINK_END_COW_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_REFLINK_END_COW_CNT);
+ if (error)
+ goto out_cancel;
+ }
+
/*
* In case of racing, overlapping AIO writes no COW extents might be
* left by the time I/O completes for the loser of the race. In that
@@ -1118,9 +1125,15 @@ xfs_reflink_remap_extent(
++iext_delta;
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK, iext_delta);
- if (error)
+ if (error && error != -EFBIG)
goto out_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip, iext_delta);
+ if (error)
+ goto out_cancel;
+ }
+
if (smap_real) {
/*
* If the extent we're unmapping is backed by storage (written
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index b8c79ee791af..8cab153201d0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -806,9 +806,16 @@ xfs_growfs_rt_alloc(
error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
XFS_IEXT_ADD_NOSPLIT_CNT);
- if (error)
+ if (error && error != -EFBIG)
goto out_trans_cancel;
+ if (error == -EFBIG) {
+ error = xfs_iext_count_upgrade(tp, ip,
+ XFS_IEXT_ADD_NOSPLIT_CNT);
+ if (error)
+ goto out_trans_cancel;
+ }
+
/*
* Allocate blocks to the bitmap file.
*/
--
2.30.2
next prev parent reply other threads:[~2022-03-21 5:19 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-21 5:17 [PATCH V8 00/19] xfs: Extend per-inode extent counters Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 01/19] xfs: Move extent count limits to xfs_format.h Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 02/19] xfs: Define max extent length based on on-disk format definition Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 03/19] xfs: Introduce xfs_iext_max_nextents() helper Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 04/19] xfs: Use xfs_extnum_t instead of basic data types Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 05/19] xfs: Introduce xfs_dfork_nextents() helper Chandan Babu R
2022-03-24 21:31 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 06/19] xfs: Use basic types to define xfs_log_dinode's di_nextents and di_anextents Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 07/19] xfs: Promote xfs_extnum_t and xfs_aextnum_t to 64 and 32-bits respectively Chandan Babu R
2022-03-24 21:33 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 08/19] xfs: Introduce XFS_SB_FEAT_INCOMPAT_NREXT64 and associated per-fs feature bit Chandan Babu R
2022-03-24 21:37 ` Dave Chinner
2022-03-24 21:40 ` Darrick J. Wong
2022-03-25 6:01 ` Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 09/19] xfs: Introduce XFS_FSOP_GEOM_FLAGS_NREXT64 Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 10/19] xfs: Introduce XFS_DIFLAG2_NREXT64 and associated helpers Chandan Babu R
2022-03-24 21:38 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 11/19] xfs: Use uint64_t to count maximum blocks that can be used by BMBT Chandan Babu R
2022-03-24 21:42 ` Dave Chinner
2022-03-25 6:01 ` Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 12/19] xfs: Introduce macros to represent new maximum extent counts for data/attr forks Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 13/19] xfs: Replace numbered inode recovery error messages with descriptive ones Chandan Babu R
2022-03-24 21:47 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 14/19] xfs: Introduce per-inode 64-bit extent counters Chandan Babu R
2022-03-24 21:53 ` Dave Chinner
2022-03-25 6:02 ` Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 15/19] xfs: Directory's data fork extent counter can never overflow Chandan Babu R
2022-03-24 22:14 ` Dave Chinner
2022-03-25 6:02 ` Chandan Babu R
2022-03-25 6:37 ` Chandan Babu R
2022-03-29 5:22 ` Chandan Babu R
2022-03-29 6:23 ` Dave Chinner
2022-03-30 3:43 ` Darrick J. Wong
2022-03-30 15:39 ` Chandan Babu R
2022-03-30 15:52 ` Darrick J. Wong
2022-04-01 1:27 ` Dave Chinner
2022-04-01 7:46 ` Chandan Babu R
2022-03-21 5:17 ` Chandan Babu R [this message]
2022-03-24 22:28 ` [PATCH V8 16/19] xfs: Conditionally upgrade existing inodes to use large extent counters Dave Chinner
2022-03-25 6:02 ` Chandan Babu R
2022-03-21 5:17 ` [PATCH V8 17/19] xfs: Decouple XFS_IBULK flags from XFS_IWALK flags Chandan Babu R
2022-03-24 22:28 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 18/19] xfs: Enable bulkstat ioctl to support 64-bit per-inode extent counters Chandan Babu R
2022-03-24 22:33 ` Dave Chinner
2022-03-21 5:17 ` [PATCH V8 19/19] xfs: Add XFS_SB_FEAT_INCOMPAT_NREXT64 to the list of supported flags Chandan Babu R
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220321051750.400056-17-chandan.babu@oracle.com \
--to=chandan.babu@oracle.com \
--cc=david@fromorbit.com \
--cc=djwong@kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.