Drop the restriction for casefold dentries to enable support for case-insensitive filesystems in overlayfs. Support case-insensitive filesystems with the condition that they should be uniformly enabled across the stack and the layers (i.e. if the root mount dir has casefold enabled, so should all the dirs bellow for every layer). Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx> --- Changes from v2: - Create new ovl_fs flag, bool casefold - Check if casefolded dentry is consistent with the root dentry --- fs/overlayfs/namei.c | 17 +++++++++-------- fs/overlayfs/ovl_entry.h | 1 + fs/overlayfs/params.c | 7 ++----- fs/overlayfs/util.c | 8 ++++---- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 76d6248b625e7c58e09685e421aef616aadea40a..08b34e52b36f93d4da09e4d13b51d23dc99ca6d6 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -239,13 +239,14 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, char val; /* - * We allow filesystems that are case-folding capable but deny composing - * ovl stack from case-folded directories. If someone has enabled case - * folding on a directory on underlying layer, the warranty of the ovl - * stack is voided. + * We allow filesystems that are case-folding capable as long as the + * layers are consistently enabled in the stack, enabled for every dir + * or disabled in all dirs. If someone has enabled case folding on a + * directory on underlying layer, the warranty of the ovl stack is + * voided. */ - if (ovl_dentry_casefolded(base)) { - warn = "case folded parent"; + if (ofs->casefold != ovl_dentry_casefolded(base)) { + warn = "parent wrong casefold"; err = -ESTALE; goto out_warn; } @@ -259,8 +260,8 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, goto out_err; } - if (ovl_dentry_casefolded(this)) { - warn = "case folded child"; + if (ofs->casefold != ovl_dentry_casefolded(this)) { + warn = "child wrong casefold"; err = -EREMOTE; goto out_warn; } diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index 4c1bae935ced274f93a0d23fe10d34455e226ec4..1d4828dbcf7ac4ba9657221e601bbf79d970d225 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -91,6 +91,7 @@ struct ovl_fs { struct mutex whiteout_lock; /* r/o snapshot of upperdir sb's only taken on volatile mounts */ errseq_t errseq; + bool casefold; }; /* Number of lower layers, not including data-only layers */ diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index f4e7fff909ac49e2f8c58a76273426c1158a7472..afa1c29515a9729bfe88c8166da4aefa6cddc5a5 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -277,16 +277,13 @@ static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path, enum ovl_opt layer, const char *name, bool upper) { struct ovl_fs_context *ctx = fc->fs_private; + struct ovl_fs *ovl = fc->s_fs_info; if (!d_is_dir(path->dentry)) return invalfc(fc, "%s is not a directory", name); - /* - * Allow filesystems that are case-folding capable but deny composing - * ovl stack from case-folded directories. - */ if (ovl_dentry_casefolded(path->dentry)) - return invalfc(fc, "case-insensitive directory on %s not supported", name); + ovl->casefold = true; if (ovl_dentry_weird(path->dentry)) return invalfc(fc, "filesystem on %s not supported", name); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index a33115e7384c129c543746326642813add63f060..7a6ee058568283453350153c1720c35e11ad4d1b 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -210,11 +210,11 @@ bool ovl_dentry_weird(struct dentry *dentry) return true; /* - * Allow filesystems that are case-folding capable but deny composing - * ovl stack from case-folded directories. + * Exceptionally for casefold dentries, we accept that they have their + * own hash and compare operations */ - if (sb_has_encoding(dentry->d_sb)) - return IS_CASEFOLDED(d_inode(dentry)); + if (ovl_dentry_casefolded(dentry)) + return false; return dentry->d_flags & (DCACHE_OP_HASH | DCACHE_OP_COMPARE); } -- 2.50.1