When case-insensitive and fscrypt were adapted to work together, we moved the
code that sets the dentry operations for case-insensitive dentries(d_hash and
d_compare) to happen from a helper inside ->lookup. This is because fscrypt
wants to set d_revalidate only on some dentries, so it does it only for them in
d_revalidate.
But, case-insensitive hooks are actually set on all dentries in the filesystem,
so the natural place to do it is through s_d_op and let d_alloc handle it [1].
In addition, doing it inside the ->lookup is a problem for case-insensitive
dentries that are not created through ->lookup, like those coming
open-by-fhandle[2], which will not see the required d_ops.
This patchset therefore reverts to using sb->s_d_op to set the dentry operations
for case-insensitive filesystems. In order to set case-insensitive hooks early
and not require every dentry to have d_revalidate in case-insensitive
filesystems, it introduces a patch suggested by Al Viro to disable d_revalidate
on some dentries on the fly.
It survives fstests encrypt and quick groups without regressions. Based on v6.7-rc1.
[1] https://lore.kernel.org/linux-fsdevel/20231123195327.GP38156@ZenIV/
[2] https://lore.kernel.org/linux-fsdevel/20231123171255.GN38156@ZenIV/
Gabriel Krisman Bertazi (8):
dcache: Add helper to disable d_revalidate for a specific dentry
fscrypt: Drop d_revalidate if key is available
libfs: Merge encrypted_ci_dentry_ops and ci_dentry_ops
libfs: Expose generic_ci_dentry_ops outside of libfs
ext4: Set the case-insensitive dentry operations through ->s_d_op
f2fs: Set the case-insensitive dentry operations through ->s_d_op
libfs: Don't support setting casefold operations during lookup
fscrypt: Move d_revalidate configuration back into fscrypt
fs/crypto/fname.c | 9 +++++-
fs/crypto/hooks.c | 8 ++++++
fs/dcache.c | 10 +++++++
fs/ext4/namei.c | 1 -
fs/ext4/super.c | 3 ++
fs/f2fs/namei.c | 1 -
fs/f2fs/super.c | 3 ++
fs/libfs.c | 64 +++--------------------------------------
fs/ubifs/dir.c | 1 -
include/linux/dcache.h | 1 +
include/linux/fs.h | 2 +-
include/linux/fscrypt.h | 10 +++----
12 files changed, 43 insertions(+), 70 deletions(-)
--
2.43.0
All dentries in a case-insensitive filesystem have the same set of
dentry operations. Therefore, we should let VFS propagate them from
sb->s_d_op d_alloc instead of setting at lookup time.
This was already the case before commit bb9cd9106b22 ("fscrypt: Have
filesystems handle their d_ops"), but it was changed to set at
lookup-time to facilitate the integration with fscrypt. But it's a
problem because dentries that don't get created through ->lookup() won't
have any visibility of the operations. Let's revert to the previous
implementation.
Suggested-by: Al Viro <[email protected]>
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/f2fs/namei.c | 6 +++++-
fs/f2fs/super.c | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index d0053b0284d8..4053846e2cd3 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -532,7 +532,11 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
}
err = f2fs_prepare_lookup(dir, dentry, &fname);
- generic_set_encrypted_ci_d_ops(dentry);
+
+ /* Case-insensitive volumes set dentry ops through sb->s_d_op. */
+ if (!dir->i_sb->s_encoding)
+ generic_set_encrypted_ci_d_ops(dentry);
+
if (err == -ENOENT)
goto out_splice;
if (err)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 033af907c3b1..0a199eb5b01e 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4663,6 +4663,9 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
goto free_node_inode;
}
+ if (sb->s_encoding)
+ sb->s_d_op = &generic_ci_dentry_ops;
+
sb->s_root = d_make_root(root); /* allocate root dentry */
if (!sb->s_root) {
err = -ENOMEM;
--
2.43.0
All dentries in a case-insensitive filesystem have the same set of
dentry operations. Therefore, we should let VFS propagate them from
sb->s_d_op d_alloc instead of setting at lookup time.
This was already the case before commit bb9cd9106b22 ("fscrypt: Have
filesystems handle their d_ops"), but it was changed to set at
lookup-time to facilitate the integration with fscrypt. But it's a
problem because dentries that don't get created through ->lookup() won't
have any visibility of the operations. Let's revert to the previous
implementation.
Suggested-by: Al Viro <[email protected]>
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/ext4/namei.c | 6 +++++-
fs/ext4/super.c | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index d252935f9c8a..3c1208d5d85b 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1762,7 +1762,11 @@ static struct buffer_head *ext4_lookup_entry(struct inode *dir,
struct buffer_head *bh;
err = ext4_fname_prepare_lookup(dir, dentry, &fname);
- generic_set_encrypted_ci_d_ops(dentry);
+
+ /* Case-insensitive volumes set dentry ops through sb->s_d_op. */
+ if (!dir->i_sb->s_encoding)
+ generic_set_encrypted_ci_d_ops(dentry);
+
if (err == -ENOENT)
return NULL;
if (err)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index c5fcf377ab1f..5ac1c9df9956 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5493,6 +5493,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
goto failed_mount4;
}
+ if (sb->s_encoding)
+ sb->s_d_op = &generic_ci_dentry_ops;
+
sb->s_root = d_make_root(root);
if (!sb->s_root) {
ext4_msg(sb, KERN_ERR, "get root dentry failed");
--
2.43.0
In preparation to allow filesystems to set this through sb->s_d_op,
expose the symbol directly to the filesystems.
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/libfs.c | 2 +-
include/linux/fs.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index 52c944173e57..b8ecada3a5b2 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1765,7 +1765,7 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str)
return 0;
}
-static const struct dentry_operations generic_ci_dentry_ops = {
+const struct dentry_operations generic_ci_dentry_ops = {
.d_hash = generic_ci_d_hash,
.d_compare = generic_ci_d_compare,
#if defined(CONFIG_FS_ENCRYPTION)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 98b7a7a8c42e..887a27d07f96 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3202,6 +3202,7 @@ extern int generic_file_fsync(struct file *, loff_t, loff_t, int);
extern int generic_check_addressable(unsigned, u64);
extern void generic_set_encrypted_ci_d_ops(struct dentry *dentry);
+extern const struct dentry_operations generic_ci_dentry_ops;
int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
unsigned int ia_valid);
--
2.43.0
In preparation to get case-insensitive dentry operations from
sb->s_d_op again, use the same structure for case-insensitive
filesystems with and without fscrypt.
This means that on a casefolded filesystem without fscrypt, we end up
having to call fscrypt_d_revalidate once per dentry, which does the
function call extra cost. We could avoid it by calling
d_set_always_valid in generic_set_encrypted_ci_d_ops, but this entire
function will go away in the following patches, and it is not worth the
extra complexity. Also, since the first fscrypt_d_revalidate will call
d_set_always_valid for us, we'll only have only pay the cost once, and
not per-lookup.
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/libfs.c | 34 ++++++----------------------------
1 file changed, 6 insertions(+), 28 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index e9440d55073c..52c944173e57 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1768,6 +1768,9 @@ static int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str)
static const struct dentry_operations generic_ci_dentry_ops = {
.d_hash = generic_ci_d_hash,
.d_compare = generic_ci_d_compare,
+#if defined(CONFIG_FS_ENCRYPTION)
+ .d_revalidate = fscrypt_d_revalidate,
+#endif
};
#endif
@@ -1777,14 +1780,6 @@ static const struct dentry_operations generic_encrypted_dentry_ops = {
};
#endif
-#if defined(CONFIG_FS_ENCRYPTION) && IS_ENABLED(CONFIG_UNICODE)
-static const struct dentry_operations generic_encrypted_ci_dentry_ops = {
- .d_hash = generic_ci_d_hash,
- .d_compare = generic_ci_d_compare,
- .d_revalidate = fscrypt_d_revalidate,
-};
-#endif
-
/**
* generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry
* @dentry: dentry to set ops on
@@ -1801,38 +1796,21 @@ static const struct dentry_operations generic_encrypted_ci_dentry_ops = {
* Encryption works differently in that the only dentry operation it needs is
* d_revalidate, which it only needs on dentries that have the no-key name flag.
* The no-key flag can't be set "later", so we don't have to worry about that.
- *
- * Finally, to maximize compatibility with overlayfs (which isn't compatible
- * with certain dentry operations) and to avoid taking an unnecessary
- * performance hit, we use custom dentry_operations for each possible
- * combination rather than always installing all operations.
*/
void generic_set_encrypted_ci_d_ops(struct dentry *dentry)
{
-#ifdef CONFIG_FS_ENCRYPTION
- bool needs_encrypt_ops = dentry->d_flags & DCACHE_NOKEY_NAME;
-#endif
#if IS_ENABLED(CONFIG_UNICODE)
- bool needs_ci_ops = dentry->d_sb->s_encoding;
-#endif
-#if defined(CONFIG_FS_ENCRYPTION) && IS_ENABLED(CONFIG_UNICODE)
- if (needs_encrypt_ops && needs_ci_ops) {
- d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops);
+ if (dentry->d_sb->s_encoding) {
+ d_set_d_op(dentry, &generic_ci_dentry_ops);
return;
}
#endif
#ifdef CONFIG_FS_ENCRYPTION
- if (needs_encrypt_ops) {
+ if (dentry->d_flags & DCACHE_NOKEY_NAME) {
d_set_d_op(dentry, &generic_encrypted_dentry_ops);
return;
}
#endif
-#if IS_ENABLED(CONFIG_UNICODE)
- if (needs_ci_ops) {
- d_set_d_op(dentry, &generic_ci_dentry_ops);
- return;
- }
-#endif
}
EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops);
--
2.43.0
No filesystems depend on it anymore, and it is generally a bad idea.
Since all dentries should have the same set of dentry operations in
case-insensitive filesystems, it should be configured through ->s_d_op.
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/libfs.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index b8ecada3a5b2..41c02c003265 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1784,27 +1784,12 @@ static const struct dentry_operations generic_encrypted_dentry_ops = {
* generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry
* @dentry: dentry to set ops on
*
- * Casefolded directories need d_hash and d_compare set, so that the dentries
- * contained in them are handled case-insensitively. Note that these operations
- * are needed on the parent directory rather than on the dentries in it, and
- * while the casefolding flag can be toggled on and off on an empty directory,
- * dentry_operations can't be changed later. As a result, if the filesystem has
- * casefolding support enabled at all, we have to give all dentries the
- * casefolding operations even if their inode doesn't have the casefolding flag
- * currently (and thus the casefolding ops would be no-ops for now).
- *
* Encryption works differently in that the only dentry operation it needs is
* d_revalidate, which it only needs on dentries that have the no-key name flag.
* The no-key flag can't be set "later", so we don't have to worry about that.
*/
void generic_set_encrypted_ci_d_ops(struct dentry *dentry)
{
-#if IS_ENABLED(CONFIG_UNICODE)
- if (dentry->d_sb->s_encoding) {
- d_set_d_op(dentry, &generic_ci_dentry_ops);
- return;
- }
-#endif
#ifdef CONFIG_FS_ENCRYPTION
if (dentry->d_flags & DCACHE_NOKEY_NAME) {
d_set_d_op(dentry, &generic_encrypted_dentry_ops);
--
2.43.0
This partially reverts commit bb9cd9106b22 ("fscrypt: Have filesystems
handle their d_ops"), which moved this handler out of fscrypt and into
the filesystems, in preparation to support casefold and fscrypt
combinations. Now that we set casefolding operations through
->s_d_op, move this back into fscrypt, where it belongs, but take care
to handle filesystems that set their own sb->s_d_op.
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
fs/crypto/hooks.c | 8 ++++++++
fs/ext4/namei.c | 5 -----
fs/f2fs/namei.c | 5 -----
fs/libfs.c | 19 -------------------
fs/ubifs/dir.c | 1 -
include/linux/fs.h | 1 -
include/linux/fscrypt.h | 10 +++++-----
7 files changed, 13 insertions(+), 36 deletions(-)
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 52504dd478d3..166837d5af29 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -94,6 +94,10 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
}
EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename);
+static const struct dentry_operations fscrypt_dentry_ops = {
+ .d_revalidate = fscrypt_d_revalidate,
+};
+
int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
struct fscrypt_name *fname)
{
@@ -106,6 +110,10 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_NOKEY_NAME;
spin_unlock(&dentry->d_lock);
+
+ /* Give preference to the filesystem hooks, if any. */
+ if (!dentry->d_op)
+ d_set_d_op(dentry, &fscrypt_dentry_ops);
}
return err;
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 3c1208d5d85b..3f0b853a371e 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1762,11 +1762,6 @@ static struct buffer_head *ext4_lookup_entry(struct inode *dir,
struct buffer_head *bh;
err = ext4_fname_prepare_lookup(dir, dentry, &fname);
-
- /* Case-insensitive volumes set dentry ops through sb->s_d_op. */
- if (!dir->i_sb->s_encoding)
- generic_set_encrypted_ci_d_ops(dentry);
-
if (err == -ENOENT)
return NULL;
if (err)
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 4053846e2cd3..b40c6c393bd6 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -532,11 +532,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
}
err = f2fs_prepare_lookup(dir, dentry, &fname);
-
- /* Case-insensitive volumes set dentry ops through sb->s_d_op. */
- if (!dir->i_sb->s_encoding)
- generic_set_encrypted_ci_d_ops(dentry);
-
if (err == -ENOENT)
goto out_splice;
if (err)
diff --git a/fs/libfs.c b/fs/libfs.c
index 41c02c003265..4fed170dfe49 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1780,25 +1780,6 @@ static const struct dentry_operations generic_encrypted_dentry_ops = {
};
#endif
-/**
- * generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry
- * @dentry: dentry to set ops on
- *
- * Encryption works differently in that the only dentry operation it needs is
- * d_revalidate, which it only needs on dentries that have the no-key name flag.
- * The no-key flag can't be set "later", so we don't have to worry about that.
- */
-void generic_set_encrypted_ci_d_ops(struct dentry *dentry)
-{
-#ifdef CONFIG_FS_ENCRYPTION
- if (dentry->d_flags & DCACHE_NOKEY_NAME) {
- d_set_d_op(dentry, &generic_encrypted_dentry_ops);
- return;
- }
-#endif
-}
-EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops);
-
/**
* inode_maybe_inc_iversion - increments i_version
* @inode: inode with the i_version that should be updated
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 3b13c648d490..51b9a10a9851 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -205,7 +205,6 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino);
err = fscrypt_prepare_lookup(dir, dentry, &nm);
- generic_set_encrypted_ci_d_ops(dentry);
if (err == -ENOENT)
return d_splice_alias(NULL, dentry);
if (err)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 887a27d07f96..e5ae21f9f637 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3201,7 +3201,6 @@ extern int generic_file_fsync(struct file *, loff_t, loff_t, int);
extern int generic_check_addressable(unsigned, u64);
-extern void generic_set_encrypted_ci_d_ops(struct dentry *dentry);
extern const struct dentry_operations generic_ci_dentry_ops;
int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 12f9e455d569..97a11280c2bd 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -961,11 +961,11 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir,
* key is available, then the lookup is assumed to be by plaintext name;
* otherwise, it is assumed to be by no-key name.
*
- * This will set DCACHE_NOKEY_NAME on the dentry if the lookup is by no-key
- * name. In this case the filesystem must assign the dentry a dentry_operations
- * which contains fscrypt_d_revalidate (or contains a d_revalidate method that
- * calls fscrypt_d_revalidate), so that the dentry will be invalidated if the
- * directory's encryption key is later added.
+ * This also optionally installs a custom ->d_revalidate() method which will
+ * invalidate the dentry if it was created without the key and the key is later
+ * added. If the filesystem provides its own ->d_op hooks, they will be used
+ * instead, but then the filesystem must make sure to call fscrypt_d_revalidate
+ * in its d_revalidate hook, to check if fscrypt considers the dentry stale.
*
* Return: 0 on success; -ENOENT if the directory's key is unavailable but the
* filename isn't a valid no-key name, so a negative dentry should be created;
--
2.43.0
Hi Gabriel,
kernel test robot noticed the following build errors:
[auto build test ERROR on jaegeuk-f2fs/dev-test]
[also build test ERROR on jaegeuk-f2fs/dev tytso-ext4/dev linus/master v6.7-rc5 next-20231214]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Gabriel-Krisman-Bertazi/dcache-Add-helper-to-disable-d_revalidate-for-a-specific-dentry/20231214-074322
base: https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev-test
patch link: https://lore.kernel.org/r/20231213234031.1081-6-krisman%40suse.de
patch subject: [PATCH 5/8] ext4: Set the case-insensitive dentry operations through ->s_d_op
config: arc-vdk_hs38_defconfig (https://download.01.org/0day-ci/archive/20231214/[email protected]/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231214/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
fs/ext4/super.c: In function '__ext4_fill_super':
>> fs/ext4/super.c:5496:15: error: 'struct super_block' has no member named 's_encoding'
5496 | if (sb->s_encoding)
| ^~
vim +5496 fs/ext4/super.c
5215
5216 static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
5217 {
5218 struct ext4_super_block *es = NULL;
5219 struct ext4_sb_info *sbi = EXT4_SB(sb);
5220 ext4_fsblk_t logical_sb_block;
5221 struct inode *root;
5222 int needs_recovery;
5223 int err;
5224 ext4_group_t first_not_zeroed;
5225 struct ext4_fs_context *ctx = fc->fs_private;
5226 int silent = fc->sb_flags & SB_SILENT;
5227
5228 /* Set defaults for the variables that will be set during parsing */
5229 if (!(ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO))
5230 ctx->journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
5231
5232 sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS;
5233 sbi->s_sectors_written_start =
5234 part_stat_read(sb->s_bdev, sectors[STAT_WRITE]);
5235
5236 err = ext4_load_super(sb, &logical_sb_block, silent);
5237 if (err)
5238 goto out_fail;
5239
5240 es = sbi->s_es;
5241 sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);
5242
5243 err = ext4_init_metadata_csum(sb, es);
5244 if (err)
5245 goto failed_mount;
5246
5247 ext4_set_def_opts(sb, es);
5248
5249 sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
5250 sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
5251 sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
5252 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
5253 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
5254
5255 /*
5256 * set default s_li_wait_mult for lazyinit, for the case there is
5257 * no mount option specified.
5258 */
5259 sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
5260
5261 err = ext4_inode_info_init(sb, es);
5262 if (err)
5263 goto failed_mount;
5264
5265 err = parse_apply_sb_mount_options(sb, ctx);
5266 if (err < 0)
5267 goto failed_mount;
5268
5269 sbi->s_def_mount_opt = sbi->s_mount_opt;
5270 sbi->s_def_mount_opt2 = sbi->s_mount_opt2;
5271
5272 err = ext4_check_opt_consistency(fc, sb);
5273 if (err < 0)
5274 goto failed_mount;
5275
5276 ext4_apply_options(fc, sb);
5277
5278 err = ext4_encoding_init(sb, es);
5279 if (err)
5280 goto failed_mount;
5281
5282 err = ext4_check_journal_data_mode(sb);
5283 if (err)
5284 goto failed_mount;
5285
5286 sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
5287 (test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
5288
5289 /* i_version is always enabled now */
5290 sb->s_flags |= SB_I_VERSION;
5291
5292 err = ext4_check_feature_compatibility(sb, es, silent);
5293 if (err)
5294 goto failed_mount;
5295
5296 err = ext4_block_group_meta_init(sb, silent);
5297 if (err)
5298 goto failed_mount;
5299
5300 ext4_hash_info_init(sb);
5301
5302 err = ext4_handle_clustersize(sb);
5303 if (err)
5304 goto failed_mount;
5305
5306 err = ext4_check_geometry(sb, es);
5307 if (err)
5308 goto failed_mount;
5309
5310 timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
5311 spin_lock_init(&sbi->s_error_lock);
5312 INIT_WORK(&sbi->s_sb_upd_work, update_super_work);
5313
5314 err = ext4_group_desc_init(sb, es, logical_sb_block, &first_not_zeroed);
5315 if (err)
5316 goto failed_mount3;
5317
5318 err = ext4_es_register_shrinker(sbi);
5319 if (err)
5320 goto failed_mount3;
5321
5322 sbi->s_stripe = ext4_get_stripe_size(sbi);
5323 /*
5324 * It's hard to get stripe aligned blocks if stripe is not aligned with
5325 * cluster, just disable stripe and alert user to simpfy code and avoid
5326 * stripe aligned allocation which will rarely successes.
5327 */
5328 if (sbi->s_stripe > 0 && sbi->s_cluster_ratio > 1 &&
5329 sbi->s_stripe % sbi->s_cluster_ratio != 0) {
5330 ext4_msg(sb, KERN_WARNING,
5331 "stripe (%lu) is not aligned with cluster size (%u), "
5332 "stripe is disabled",
5333 sbi->s_stripe, sbi->s_cluster_ratio);
5334 sbi->s_stripe = 0;
5335 }
5336 sbi->s_extent_max_zeroout_kb = 32;
5337
5338 /*
5339 * set up enough so that it can read an inode
5340 */
5341 sb->s_op = &ext4_sops;
5342 sb->s_export_op = &ext4_export_ops;
5343 sb->s_xattr = ext4_xattr_handlers;
5344 #ifdef CONFIG_FS_ENCRYPTION
5345 sb->s_cop = &ext4_cryptops;
5346 #endif
5347 #ifdef CONFIG_FS_VERITY
5348 sb->s_vop = &ext4_verityops;
5349 #endif
5350 #ifdef CONFIG_QUOTA
5351 sb->dq_op = &ext4_quota_operations;
5352 if (ext4_has_feature_quota(sb))
5353 sb->s_qcop = &dquot_quotactl_sysfile_ops;
5354 else
5355 sb->s_qcop = &ext4_qctl_operations;
5356 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
5357 #endif
5358 memcpy(&sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
5359
5360 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5361 mutex_init(&sbi->s_orphan_lock);
5362
5363 ext4_fast_commit_init(sb);
5364
5365 sb->s_root = NULL;
5366
5367 needs_recovery = (es->s_last_orphan != 0 ||
5368 ext4_has_feature_orphan_present(sb) ||
5369 ext4_has_feature_journal_needs_recovery(sb));
5370
5371 if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb)) {
5372 err = ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block));
5373 if (err)
5374 goto failed_mount3a;
5375 }
5376
5377 err = -EINVAL;
5378 /*
5379 * The first inode we look at is the journal inode. Don't try
5380 * root first: it may be modified in the journal!
5381 */
5382 if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
5383 err = ext4_load_and_init_journal(sb, es, ctx);
5384 if (err)
5385 goto failed_mount3a;
5386 } else if (test_opt(sb, NOLOAD) && !sb_rdonly(sb) &&
5387 ext4_has_feature_journal_needs_recovery(sb)) {
5388 ext4_msg(sb, KERN_ERR, "required journal recovery "
5389 "suppressed and not mounted read-only");
5390 goto failed_mount3a;
5391 } else {
5392 /* Nojournal mode, all journal mount options are illegal */
5393 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
5394 ext4_msg(sb, KERN_ERR, "can't mount with "
5395 "journal_async_commit, fs mounted w/o journal");
5396 goto failed_mount3a;
5397 }
5398
5399 if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
5400 ext4_msg(sb, KERN_ERR, "can't mount with "
5401 "journal_checksum, fs mounted w/o journal");
5402 goto failed_mount3a;
5403 }
5404 if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
5405 ext4_msg(sb, KERN_ERR, "can't mount with "
5406 "commit=%lu, fs mounted w/o journal",
5407 sbi->s_commit_interval / HZ);
5408 goto failed_mount3a;
5409 }
5410 if (EXT4_MOUNT_DATA_FLAGS &
5411 (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
5412 ext4_msg(sb, KERN_ERR, "can't mount with "
5413 "data=, fs mounted w/o journal");
5414 goto failed_mount3a;
5415 }
5416 sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
5417 clear_opt(sb, JOURNAL_CHECKSUM);
5418 clear_opt(sb, DATA_FLAGS);
5419 clear_opt2(sb, JOURNAL_FAST_COMMIT);
5420 sbi->s_journal = NULL;
5421 needs_recovery = 0;
5422 }
5423
5424 if (!test_opt(sb, NO_MBCACHE)) {
5425 sbi->s_ea_block_cache = ext4_xattr_create_cache();
5426 if (!sbi->s_ea_block_cache) {
5427 ext4_msg(sb, KERN_ERR,
5428 "Failed to create ea_block_cache");
5429 err = -EINVAL;
5430 goto failed_mount_wq;
5431 }
5432
5433 if (ext4_has_feature_ea_inode(sb)) {
5434 sbi->s_ea_inode_cache = ext4_xattr_create_cache();
5435 if (!sbi->s_ea_inode_cache) {
5436 ext4_msg(sb, KERN_ERR,
5437 "Failed to create ea_inode_cache");
5438 err = -EINVAL;
5439 goto failed_mount_wq;
5440 }
5441 }
5442 }
5443
5444 /*
5445 * Get the # of file system overhead blocks from the
5446 * superblock if present.
5447 */
5448 sbi->s_overhead = le32_to_cpu(es->s_overhead_clusters);
5449 /* ignore the precalculated value if it is ridiculous */
5450 if (sbi->s_overhead > ext4_blocks_count(es))
5451 sbi->s_overhead = 0;
5452 /*
5453 * If the bigalloc feature is not enabled recalculating the
5454 * overhead doesn't take long, so we might as well just redo
5455 * it to make sure we are using the correct value.
5456 */
5457 if (!ext4_has_feature_bigalloc(sb))
5458 sbi->s_overhead = 0;
5459 if (sbi->s_overhead == 0) {
5460 err = ext4_calculate_overhead(sb);
5461 if (err)
5462 goto failed_mount_wq;
5463 }
5464
5465 /*
5466 * The maximum number of concurrent works can be high and
5467 * concurrency isn't really necessary. Limit it to 1.
5468 */
5469 EXT4_SB(sb)->rsv_conversion_wq =
5470 alloc_workqueue("ext4-rsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
5471 if (!EXT4_SB(sb)->rsv_conversion_wq) {
5472 printk(KERN_ERR "EXT4-fs: failed to create workqueue\n");
5473 err = -ENOMEM;
5474 goto failed_mount4;
5475 }
5476
5477 /*
5478 * The jbd2_journal_load will have done any necessary log recovery,
5479 * so we can safely mount the rest of the filesystem now.
5480 */
5481
5482 root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL);
5483 if (IS_ERR(root)) {
5484 ext4_msg(sb, KERN_ERR, "get root inode failed");
5485 err = PTR_ERR(root);
5486 root = NULL;
5487 goto failed_mount4;
5488 }
5489 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
5490 ext4_msg(sb, KERN_ERR, "corrupt root inode, run e2fsck");
5491 iput(root);
5492 err = -EFSCORRUPTED;
5493 goto failed_mount4;
5494 }
5495
> 5496 if (sb->s_encoding)
5497 sb->s_d_op = &generic_ci_dentry_ops;
5498
5499 sb->s_root = d_make_root(root);
5500 if (!sb->s_root) {
5501 ext4_msg(sb, KERN_ERR, "get root dentry failed");
5502 err = -ENOMEM;
5503 goto failed_mount4;
5504 }
5505
5506 err = ext4_setup_super(sb, es, sb_rdonly(sb));
5507 if (err == -EROFS) {
5508 sb->s_flags |= SB_RDONLY;
5509 } else if (err)
5510 goto failed_mount4a;
5511
5512 ext4_set_resv_clusters(sb);
5513
5514 if (test_opt(sb, BLOCK_VALIDITY)) {
5515 err = ext4_setup_system_zone(sb);
5516 if (err) {
5517 ext4_msg(sb, KERN_ERR, "failed to initialize system "
5518 "zone (%d)", err);
5519 goto failed_mount4a;
5520 }
5521 }
5522 ext4_fc_replay_cleanup(sb);
5523
5524 ext4_ext_init(sb);
5525
5526 /*
5527 * Enable optimize_scan if number of groups is > threshold. This can be
5528 * turned off by passing "mb_optimize_scan=0". This can also be
5529 * turned on forcefully by passing "mb_optimize_scan=1".
5530 */
5531 if (!(ctx->spec & EXT4_SPEC_mb_optimize_scan)) {
5532 if (sbi->s_groups_count >= MB_DEFAULT_LINEAR_SCAN_THRESHOLD)
5533 set_opt2(sb, MB_OPTIMIZE_SCAN);
5534 else
5535 clear_opt2(sb, MB_OPTIMIZE_SCAN);
5536 }
5537
5538 err = ext4_mb_init(sb);
5539 if (err) {
5540 ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
5541 err);
5542 goto failed_mount5;
5543 }
5544
5545 /*
5546 * We can only set up the journal commit callback once
5547 * mballoc is initialized
5548 */
5549 if (sbi->s_journal)
5550 sbi->s_journal->j_commit_callback =
5551 ext4_journal_commit_callback;
5552
5553 err = ext4_percpu_param_init(sbi);
5554 if (err)
5555 goto failed_mount6;
5556
5557 if (ext4_has_feature_flex_bg(sb))
5558 if (!ext4_fill_flex_info(sb)) {
5559 ext4_msg(sb, KERN_ERR,
5560 "unable to initialize "
5561 "flex_bg meta info!");
5562 err = -ENOMEM;
5563 goto failed_mount6;
5564 }
5565
5566 err = ext4_register_li_request(sb, first_not_zeroed);
5567 if (err)
5568 goto failed_mount6;
5569
5570 err = ext4_register_sysfs(sb);
5571 if (err)
5572 goto failed_mount7;
5573
5574 err = ext4_init_orphan_info(sb);
5575 if (err)
5576 goto failed_mount8;
5577 #ifdef CONFIG_QUOTA
5578 /* Enable quota usage during mount. */
5579 if (ext4_has_feature_quota(sb) && !sb_rdonly(sb)) {
5580 err = ext4_enable_quotas(sb);
5581 if (err)
5582 goto failed_mount9;
5583 }
5584 #endif /* CONFIG_QUOTA */
5585
5586 /*
5587 * Save the original bdev mapping's wb_err value which could be
5588 * used to detect the metadata async write error.
5589 */
5590 spin_lock_init(&sbi->s_bdev_wb_lock);
5591 errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
5592 &sbi->s_bdev_wb_err);
5593 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
5594 ext4_orphan_cleanup(sb, es);
5595 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
5596 /*
5597 * Update the checksum after updating free space/inode counters and
5598 * ext4_orphan_cleanup. Otherwise the superblock can have an incorrect
5599 * checksum in the buffer cache until it is written out and
5600 * e2fsprogs programs trying to open a file system immediately
5601 * after it is mounted can fail.
5602 */
5603 ext4_superblock_csum_set(sb);
5604 if (needs_recovery) {
5605 ext4_msg(sb, KERN_INFO, "recovery complete");
5606 err = ext4_mark_recovery_complete(sb, es);
5607 if (err)
5608 goto failed_mount10;
5609 }
5610
5611 if (test_opt(sb, DISCARD) && !bdev_max_discard_sectors(sb->s_bdev))
5612 ext4_msg(sb, KERN_WARNING,
5613 "mounting with \"discard\" option, but the device does not support discard");
5614
5615 if (es->s_error_count)
5616 mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */
5617
5618 /* Enable message ratelimiting. Default is 10 messages per 5 secs. */
5619 ratelimit_state_init(&sbi->s_err_ratelimit_state, 5 * HZ, 10);
5620 ratelimit_state_init(&sbi->s_warning_ratelimit_state, 5 * HZ, 10);
5621 ratelimit_state_init(&sbi->s_msg_ratelimit_state, 5 * HZ, 10);
5622 atomic_set(&sbi->s_warning_count, 0);
5623 atomic_set(&sbi->s_msg_count, 0);
5624
5625 return 0;
5626
5627 failed_mount10:
5628 ext4_quotas_off(sb, EXT4_MAXQUOTAS);
5629 failed_mount9: __maybe_unused
5630 ext4_release_orphan_info(sb);
5631 failed_mount8:
5632 ext4_unregister_sysfs(sb);
5633 kobject_put(&sbi->s_kobj);
5634 failed_mount7:
5635 ext4_unregister_li_request(sb);
5636 failed_mount6:
5637 ext4_mb_release(sb);
5638 ext4_flex_groups_free(sbi);
5639 ext4_percpu_param_destroy(sbi);
5640 failed_mount5:
5641 ext4_ext_release(sb);
5642 ext4_release_system_zone(sb);
5643 failed_mount4a:
5644 dput(sb->s_root);
5645 sb->s_root = NULL;
5646 failed_mount4:
5647 ext4_msg(sb, KERN_ERR, "mount failed");
5648 if (EXT4_SB(sb)->rsv_conversion_wq)
5649 destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq);
5650 failed_mount_wq:
5651 ext4_xattr_destroy_cache(sbi->s_ea_inode_cache);
5652 sbi->s_ea_inode_cache = NULL;
5653
5654 ext4_xattr_destroy_cache(sbi->s_ea_block_cache);
5655 sbi->s_ea_block_cache = NULL;
5656
5657 if (sbi->s_journal) {
5658 /* flush s_sb_upd_work before journal destroy. */
5659 flush_work(&sbi->s_sb_upd_work);
5660 jbd2_journal_destroy(sbi->s_journal);
5661 sbi->s_journal = NULL;
5662 }
5663 failed_mount3a:
5664 ext4_es_unregister_shrinker(sbi);
5665 failed_mount3:
5666 /* flush s_sb_upd_work before sbi destroy */
5667 flush_work(&sbi->s_sb_upd_work);
5668 del_timer_sync(&sbi->s_err_report);
5669 ext4_stop_mmpd(sbi);
5670 ext4_group_desc_free(sbi);
5671 failed_mount:
5672 if (sbi->s_chksum_driver)
5673 crypto_free_shash(sbi->s_chksum_driver);
5674
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Gabriel,
kernel test robot noticed the following build warnings:
[auto build test WARNING on jaegeuk-f2fs/dev-test]
[also build test WARNING on jaegeuk-f2fs/dev tytso-ext4/dev linus/master v6.7-rc5 next-20231214]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Gabriel-Krisman-Bertazi/dcache-Add-helper-to-disable-d_revalidate-for-a-specific-dentry/20231214-074322
base: https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev-test
patch link: https://lore.kernel.org/r/20231213234031.1081-9-krisman%40suse.de
patch subject: [PATCH 8/8] fscrypt: Move d_revalidate configuration back into fscrypt
config: x86_64-randconfig-123-20231214 (https://download.01.org/0day-ci/archive/20231214/[email protected]/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231214/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
>> fs/libfs.c:1778:39: warning: unused variable 'generic_encrypted_dentry_ops' [-Wunused-const-variable]
static const struct dentry_operations generic_encrypted_dentry_ops = {
^
1 warning generated.
vim +/generic_encrypted_dentry_ops +1778 fs/libfs.c
608af703519a58 Daniel Rosenberg 2020-11-19 1776
608af703519a58 Daniel Rosenberg 2020-11-19 1777 #ifdef CONFIG_FS_ENCRYPTION
608af703519a58 Daniel Rosenberg 2020-11-19 @1778 static const struct dentry_operations generic_encrypted_dentry_ops = {
608af703519a58 Daniel Rosenberg 2020-11-19 1779 .d_revalidate = fscrypt_d_revalidate,
608af703519a58 Daniel Rosenberg 2020-11-19 1780 };
608af703519a58 Daniel Rosenberg 2020-11-19 1781 #endif
608af703519a58 Daniel Rosenberg 2020-11-19 1782
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Gabriel,
kernel test robot noticed the following build errors:
[auto build test ERROR on jaegeuk-f2fs/dev-test]
[also build test ERROR on jaegeuk-f2fs/dev tytso-ext4/dev linus/master v6.7-rc5 next-20231214]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Gabriel-Krisman-Bertazi/dcache-Add-helper-to-disable-d_revalidate-for-a-specific-dentry/20231214-074322
base: https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev-test
patch link: https://lore.kernel.org/r/20231213234031.1081-7-krisman%40suse.de
patch subject: [PATCH 6/8] f2fs: Set the case-insensitive dentry operations through ->s_d_op
config: x86_64-buildonly-randconfig-002-20231214 (https://download.01.org/0day-ci/archive/20231214/[email protected]/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231214/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
fs/f2fs/super.c: In function 'f2fs_fill_super':
>> fs/f2fs/super.c:4669:15: error: 'struct super_block' has no member named 's_encoding'
4669 | if (sb->s_encoding)
| ^~
vim +4669 fs/f2fs/super.c
4491
4492 sb->s_op = &f2fs_sops;
4493 #ifdef CONFIG_FS_ENCRYPTION
4494 sb->s_cop = &f2fs_cryptops;
4495 #endif
4496 #ifdef CONFIG_FS_VERITY
4497 sb->s_vop = &f2fs_verityops;
4498 #endif
4499 sb->s_xattr = f2fs_xattr_handlers;
4500 sb->s_export_op = &f2fs_export_ops;
4501 sb->s_magic = F2FS_SUPER_MAGIC;
4502 sb->s_time_gran = 1;
4503 sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
4504 (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
4505 memcpy(&sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));
4506 sb->s_iflags |= SB_I_CGROUPWB;
4507
4508 /* init f2fs-specific super block info */
4509 sbi->valid_super_block = valid_super_block;
4510
4511 /* disallow all the data/node/meta page writes */
4512 set_sbi_flag(sbi, SBI_POR_DOING);
4513
4514 err = f2fs_init_write_merge_io(sbi);
4515 if (err)
4516 goto free_bio_info;
4517
4518 init_sb_info(sbi);
4519
4520 err = f2fs_init_iostat(sbi);
4521 if (err)
4522 goto free_bio_info;
4523
4524 err = init_percpu_info(sbi);
4525 if (err)
4526 goto free_iostat;
4527
4528 if (F2FS_IO_ALIGNED(sbi)) {
4529 sbi->write_io_dummy =
4530 mempool_create_page_pool(2 * (F2FS_IO_SIZE(sbi) - 1), 0);
4531 if (!sbi->write_io_dummy) {
4532 err = -ENOMEM;
4533 goto free_percpu;
4534 }
4535 }
4536
4537 /* init per sbi slab cache */
4538 err = f2fs_init_xattr_caches(sbi);
4539 if (err)
4540 goto free_io_dummy;
4541 err = f2fs_init_page_array_cache(sbi);
4542 if (err)
4543 goto free_xattr_cache;
4544
4545 /* get an inode for meta space */
4546 sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi));
4547 if (IS_ERR(sbi->meta_inode)) {
4548 f2fs_err(sbi, "Failed to read F2FS meta data inode");
4549 err = PTR_ERR(sbi->meta_inode);
4550 goto free_page_array_cache;
4551 }
4552
4553 err = f2fs_get_valid_checkpoint(sbi);
4554 if (err) {
4555 f2fs_err(sbi, "Failed to get valid F2FS checkpoint");
4556 goto free_meta_inode;
4557 }
4558
4559 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_QUOTA_NEED_FSCK_FLAG))
4560 set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
4561 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_DISABLED_QUICK_FLAG)) {
4562 set_sbi_flag(sbi, SBI_CP_DISABLED_QUICK);
4563 sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_QUICK_INTERVAL;
4564 }
4565
4566 if (__is_set_ckpt_flags(F2FS_CKPT(sbi), CP_FSCK_FLAG))
4567 set_sbi_flag(sbi, SBI_NEED_FSCK);
4568
4569 /* Initialize device list */
4570 err = f2fs_scan_devices(sbi);
4571 if (err) {
4572 f2fs_err(sbi, "Failed to find devices");
4573 goto free_devices;
4574 }
4575
4576 err = f2fs_init_post_read_wq(sbi);
4577 if (err) {
4578 f2fs_err(sbi, "Failed to initialize post read workqueue");
4579 goto free_devices;
4580 }
4581
4582 sbi->total_valid_node_count =
4583 le32_to_cpu(sbi->ckpt->valid_node_count);
4584 percpu_counter_set(&sbi->total_valid_inode_count,
4585 le32_to_cpu(sbi->ckpt->valid_inode_count));
4586 sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
4587 sbi->total_valid_block_count =
4588 le64_to_cpu(sbi->ckpt->valid_block_count);
4589 sbi->last_valid_block_count = sbi->total_valid_block_count;
4590 sbi->reserved_blocks = 0;
4591 sbi->current_reserved_blocks = 0;
4592 limit_reserve_root(sbi);
4593 adjust_unusable_cap_perc(sbi);
4594
4595 f2fs_init_extent_cache_info(sbi);
4596
4597 f2fs_init_ino_entry_info(sbi);
4598
4599 f2fs_init_fsync_node_info(sbi);
4600
4601 /* setup checkpoint request control and start checkpoint issue thread */
4602 f2fs_init_ckpt_req_control(sbi);
4603 if (!f2fs_readonly(sb) && !test_opt(sbi, DISABLE_CHECKPOINT) &&
4604 test_opt(sbi, MERGE_CHECKPOINT)) {
4605 err = f2fs_start_ckpt_thread(sbi);
4606 if (err) {
4607 f2fs_err(sbi,
4608 "Failed to start F2FS issue_checkpoint_thread (%d)",
4609 err);
4610 goto stop_ckpt_thread;
4611 }
4612 }
4613
4614 /* setup f2fs internal modules */
4615 err = f2fs_build_segment_manager(sbi);
4616 if (err) {
4617 f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)",
4618 err);
4619 goto free_sm;
4620 }
4621 err = f2fs_build_node_manager(sbi);
4622 if (err) {
4623 f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)",
4624 err);
4625 goto free_nm;
4626 }
4627
4628 err = adjust_reserved_segment(sbi);
4629 if (err)
4630 goto free_nm;
4631
4632 /* For write statistics */
4633 sbi->sectors_written_start = f2fs_get_sectors_written(sbi);
4634
4635 /* Read accumulated write IO statistics if exists */
4636 seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE);
4637 if (__exist_node_summaries(sbi))
4638 sbi->kbytes_written =
4639 le64_to_cpu(seg_i->journal->info.kbytes_written);
4640
4641 f2fs_build_gc_manager(sbi);
4642
4643 err = f2fs_build_stats(sbi);
4644 if (err)
4645 goto free_nm;
4646
4647 /* get an inode for node space */
4648 sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi));
4649 if (IS_ERR(sbi->node_inode)) {
4650 f2fs_err(sbi, "Failed to read node inode");
4651 err = PTR_ERR(sbi->node_inode);
4652 goto free_stats;
4653 }
4654
4655 /* read root inode and dentry */
4656 root = f2fs_iget(sb, F2FS_ROOT_INO(sbi));
4657 if (IS_ERR(root)) {
4658 f2fs_err(sbi, "Failed to read root inode");
4659 err = PTR_ERR(root);
4660 goto free_node_inode;
4661 }
4662 if (!S_ISDIR(root->i_mode) || !root->i_blocks ||
4663 !root->i_size || !root->i_nlink) {
4664 iput(root);
4665 err = -EINVAL;
4666 goto free_node_inode;
4667 }
4668
> 4669 if (sb->s_encoding)
4670 sb->s_d_op = &generic_ci_dentry_ops;
4671
4672 sb->s_root = d_make_root(root); /* allocate root dentry */
4673 if (!sb->s_root) {
4674 err = -ENOMEM;
4675 goto free_node_inode;
4676 }
4677
4678 err = f2fs_init_compress_inode(sbi);
4679 if (err)
4680 goto free_root_inode;
4681
4682 err = f2fs_register_sysfs(sbi);
4683 if (err)
4684 goto free_compress_inode;
4685
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki