]> www.infradead.org Git - users/hch/misc.git/commitdiff
ovl: Prepare for mounting case-insensitive enabled layers
authorAndré Almeida <andrealmeid@igalia.com>
Thu, 14 Aug 2025 17:22:14 +0000 (14:22 -0300)
committerAmir Goldstein <amir73il@gmail.com>
Tue, 23 Sep 2025 10:29:35 +0000 (12:29 +0200)
Prepare for mounting layers with case-insensitive dentries in order to
supporting such layers in overlayfs, while enforcing uniform casefold
layers.

Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Gabriel Krisman Bertazi <gabriel@krisman.be>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
fs/overlayfs/ovl_entry.h
fs/overlayfs/params.c
fs/overlayfs/params.h

index 4c1bae935ced274f93a0d23fe10d34455e226ec4..1d4828dbcf7ac4ba9657221e601bbf79d970d225 100644 (file)
@@ -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 */
index f4e7fff909ac49e2f8c58a76273426c1158a7472..63b7346c5ee1c127a9c33b12c3704aa035ff88cf 100644 (file)
@@ -276,17 +276,26 @@ static int ovl_mount_dir(const char *name, struct path *path)
 static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path,
                               enum ovl_opt layer, const char *name, bool upper)
 {
+       bool is_casefolded = ovl_dentry_casefolded(path->dentry);
        struct ovl_fs_context *ctx = fc->fs_private;
+       struct ovl_fs *ofs = 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.
+        * ovl stack from inconsistent case-folded directories.
         */
-       if (ovl_dentry_casefolded(path->dentry))
-               return invalfc(fc, "case-insensitive directory on %s not supported", name);
+       if (!ctx->casefold_set) {
+               ofs->casefold = is_casefolded;
+               ctx->casefold_set = true;
+       }
+
+       if (ofs->casefold != is_casefolded) {
+               return invalfc(fc, "case-%ssensitive directory on %s is inconsistent",
+                              is_casefolded ? "in" : "", name);
+       }
 
        if (ovl_dentry_weird(path->dentry))
                return invalfc(fc, "filesystem on %s not supported", name);
index c96d939820211ddc63e265670a2aff60d95eec49..ffd53cdd84827cce827e8852f2de545f966ce60d 100644 (file)
@@ -33,6 +33,7 @@ struct ovl_fs_context {
        struct ovl_opt_set set;
        struct ovl_fs_context_layer *lower;
        char *lowerdir_all; /* user provided lowerdir string */
+       bool casefold_set;
 };
 
 int ovl_init_fs_context(struct fs_context *fc);