summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-05-25 19:34:40 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-05-25 19:34:40 -0700
commitbabf0bb978e3c9fce6c4eba6b744c8754fd43d8e (patch)
tree5ba842c2855515047416e5b5950a0b56ff25d9e1 /fs/xfs/xfs_mount.c
parente375780b631a5fc2a61a3b4fa12429255361a31e (diff)
parentefd409a4329f6927795be5ae080cd3ec8c014f49 (diff)
downloadlinux-stable-babf0bb978e3c9fce6c4eba6b744c8754fd43d8e.tar.gz
linux-stable-babf0bb978e3c9fce6c4eba6b744c8754fd43d8e.tar.bz2
linux-stable-babf0bb978e3c9fce6c4eba6b744c8754fd43d8e.zip
Merge tag 'xfs-5.19-for-linus' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Dave Chinner: "This is a big update with lots of new code. The summary below them all, so I'll just touch on teh higlights. The two main new features are Large Extent Counts and Logged Attribute Replay - these are two new foundational features that we are building more complex future features on top of. For upcoming functionality, we need to be able to store hundreds of millions of xattrs per inode. The Large Extent Count feature removes the limits that prevent this scale of xattr storage, and while we were modifying the on disk extent count format we also increased the number of data extents we support per inode from 2^32 to 2^47. We also need to be able to modify xattrs as part of larger atomic transactions rather than as standalone transactions. The Logged Attribute Replay feature introduces the infrastructure that allows us to use intents to record the attribute modifications in the journal before we start them, hence allowing other atomic transactions to log attribute modification intents and then defer the actual modification to later. If we then crash, log recovery then guarantees that the attribute is replayed in the context of the atomic transaction that logged the intent. A significant chunk of the commits in this merge are for the base attribute replay functionality along with fixes, improvements and cleanups related to this new functioanlity. Allison deserves a big round of thanks for her ongoing work to get this functionality into XFS. There are also many other smaller changes and improvements, so overall this is one of the bigger XFS merge requests in some time. I will be following up next week with another smaller pull request - we already have another round of fixes and improvements to the logged attribute replay functionality just about ready to go. They'll soak and test over the next week, and I'll send a pull request for them near the end of the merge window. Summary: - support for printk message indexing. - large extent counts to provide support for up to 2^47 data extents and 2^32 attribute extents, allowing us to scale beyond 4 billion data extents to billions of xattrs per inode. - conversion of various flags fields to be consistently declared as unsigned bit fields. - improvements to realtime extent accounting and converts them to per-cpu counters to match all the other block and inode accounting. - reworks core log formatting code to reduce iterations, have a shorter, cleaner fast path and generally be easier to understand and maintain. - improvements to rmap btree searches that reduce overhead by up to 30% resulting in xfs_scrub runtime reductions of 15%. - improvements to reflink that remove the size limitations in remapping operations and greatly reduce the size of transaction reservations. - reworks the minimum log size calculations to allow us to change transaction reservations without changing the minimum supported log size. - removal of quota warning support as it has never been used on Linux. - intent whiteouts to allow us to cancel intents that are completed entirely in memory rather than having use CPU and disk bandwidth formatting and writing them into the journal when it is not necessary. This makes rmap, reflink and extent freeing slightly more efficient, but provides massive improvements for.... - Logged Attribute Replay feature support. This is a fundamental change to the way we modify attributes, laying the foundation for future integration of attribute modifications as part of other atomic transactional operations the filesystem performs. - Lots of cleanups and fixes for the logged attribute replay functionality" * tag 'xfs-5.19-for-linus' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (124 commits) xfs: can't use kmem_zalloc() for attribute buffers xfs: detect empty attr leaf blocks in xfs_attr3_leaf_verify xfs: ATTR_REPLACE algorithm with LARP enabled needs rework xfs: use XFS_DA_OP flags in deferred attr ops xfs: remove xfs_attri_remove_iter xfs: switch attr remove to xfs_attri_set_iter xfs: introduce attr remove initial states into xfs_attr_set_iter xfs: xfs_attr_set_iter() does not need to return EAGAIN xfs: clean up final attr removal in xfs_attr_set_iter xfs: remote xattr removal in xfs_attr_set_iter() is conditional xfs: XFS_DAS_LEAF_REPLACE state only needed if !LARP xfs: split remote attr setting out from replace path xfs: consolidate leaf/node states in xfs_attr_set_iter xfs: kill XFS_DAC_LEAF_ADDNAME_INIT xfs: separate out initial attr_set states xfs: don't set quota warning values xfs: remove warning counters from struct xfs_dquot_res xfs: remove quota warning limit from struct xfs_quota_limits xfs: rework deferred attribute operation setup xfs: make xattri_leaf_bp more useful ...
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c91
1 files changed, 53 insertions, 38 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c5f153c3693f..0c0bcbd4949d 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -468,6 +468,8 @@ STATIC int
xfs_check_summary_counts(
struct xfs_mount *mp)
{
+ int error = 0;
+
/*
* The AG0 superblock verifier rejects in-progress filesystems,
* so we should never see the flag set this far into mounting.
@@ -506,11 +508,32 @@ xfs_check_summary_counts(
* superblock to be correct and we don't need to do anything here.
* Otherwise, recalculate the summary counters.
*/
- if ((!xfs_has_lazysbcount(mp) || xfs_is_clean(mp)) &&
- !xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS))
- return 0;
+ if ((xfs_has_lazysbcount(mp) && !xfs_is_clean(mp)) ||
+ xfs_fs_has_sickness(mp, XFS_SICK_FS_COUNTERS)) {
+ error = xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount);
+ if (error)
+ return error;
+ }
- return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount);
+ /*
+ * Older kernels misused sb_frextents to reflect both incore
+ * reservations made by running transactions and the actual count of
+ * free rt extents in the ondisk metadata. Transactions committed
+ * during runtime can therefore contain a superblock update that
+ * undercounts the number of free rt extents tracked in the rt bitmap.
+ * A clean unmount record will have the correct frextents value since
+ * there can be no other transactions running at that point.
+ *
+ * If we're mounting the rt volume after recovering the log, recompute
+ * frextents from the rtbitmap file to fix the inconsistency.
+ */
+ if (xfs_has_realtime(mp) && !xfs_is_clean(mp)) {
+ error = xfs_rtalloc_reinit_frextents(mp);
+ if (error)
+ return error;
+ }
+
+ return 0;
}
/*
@@ -784,11 +807,6 @@ xfs_mountfs(
goto out_inodegc_shrinker;
}
- /* Make sure the summary counts are ok. */
- error = xfs_check_summary_counts(mp);
- if (error)
- goto out_log_dealloc;
-
/* Enable background inode inactivation workers. */
xfs_inodegc_start(mp);
xfs_blockgc_start(mp);
@@ -844,6 +862,11 @@ xfs_mountfs(
goto out_rele_rip;
}
+ /* Make sure the summary counts are ok. */
+ error = xfs_check_summary_counts(mp);
+ if (error)
+ goto out_rtunmount;
+
/*
* If this is a read-only mount defer the superblock updates until
* the next remount into writeable mode. Otherwise we would never
@@ -1087,24 +1110,33 @@ xfs_fs_writable(
return true;
}
+/* Adjust m_fdblocks or m_frextents. */
int
-xfs_mod_fdblocks(
+xfs_mod_freecounter(
struct xfs_mount *mp,
+ struct percpu_counter *counter,
int64_t delta,
bool rsvd)
{
int64_t lcounter;
long long res_used;
+ uint64_t set_aside = 0;
s32 batch;
- uint64_t set_aside;
+ bool has_resv_pool;
+
+ ASSERT(counter == &mp->m_fdblocks || counter == &mp->m_frextents);
+ has_resv_pool = (counter == &mp->m_fdblocks);
+ if (rsvd)
+ ASSERT(has_resv_pool);
if (delta > 0) {
/*
* If the reserve pool is depleted, put blocks back into it
* first. Most of the time the pool is full.
*/
- if (likely(mp->m_resblks == mp->m_resblks_avail)) {
- percpu_counter_add(&mp->m_fdblocks, delta);
+ if (likely(!has_resv_pool ||
+ mp->m_resblks == mp->m_resblks_avail)) {
+ percpu_counter_add(counter, delta);
return 0;
}
@@ -1116,7 +1148,7 @@ xfs_mod_fdblocks(
} else {
delta -= res_used;
mp->m_resblks_avail = mp->m_resblks;
- percpu_counter_add(&mp->m_fdblocks, delta);
+ percpu_counter_add(counter, delta);
}
spin_unlock(&mp->m_sb_lock);
return 0;
@@ -1130,7 +1162,7 @@ xfs_mod_fdblocks(
* then make everything serialise as we are real close to
* ENOSPC.
*/
- if (__percpu_counter_compare(&mp->m_fdblocks, 2 * XFS_FDBLOCKS_BATCH,
+ if (__percpu_counter_compare(counter, 2 * XFS_FDBLOCKS_BATCH,
XFS_FDBLOCKS_BATCH) < 0)
batch = 1;
else
@@ -1147,9 +1179,10 @@ xfs_mod_fdblocks(
* problems (i.e. transaction abort, pagecache discards, etc.) than
* slightly premature -ENOSPC.
*/
- set_aside = xfs_fdblocks_unavailable(mp);
- percpu_counter_add_batch(&mp->m_fdblocks, delta, batch);
- if (__percpu_counter_compare(&mp->m_fdblocks, set_aside,
+ if (has_resv_pool)
+ set_aside = xfs_fdblocks_unavailable(mp);
+ percpu_counter_add_batch(counter, delta, batch);
+ if (__percpu_counter_compare(counter, set_aside,
XFS_FDBLOCKS_BATCH) >= 0) {
/* we had space! */
return 0;
@@ -1160,8 +1193,8 @@ xfs_mod_fdblocks(
* that took us to ENOSPC.
*/
spin_lock(&mp->m_sb_lock);
- percpu_counter_add(&mp->m_fdblocks, -delta);
- if (!rsvd)
+ percpu_counter_add(counter, -delta);
+ if (!has_resv_pool || !rsvd)
goto fdblocks_enospc;
lcounter = (long long)mp->m_resblks_avail + delta;
@@ -1178,24 +1211,6 @@ fdblocks_enospc:
return -ENOSPC;
}
-int
-xfs_mod_frextents(
- struct xfs_mount *mp,
- int64_t delta)
-{
- int64_t lcounter;
- int ret = 0;
-
- spin_lock(&mp->m_sb_lock);
- lcounter = mp->m_sb.sb_frextents + delta;
- if (lcounter < 0)
- ret = -ENOSPC;
- else
- mp->m_sb.sb_frextents = lcounter;
- spin_unlock(&mp->m_sb_lock);
- return ret;
-}
-
/*
* Used to free the superblock along various error paths.
*/