On Wed, Apr 9, 2025 at 5:01 PM André Almeida <andrealmeid@xxxxxxxxxx> wrote: > > ovl_dentry_weird() is used to avoid problems with filesystems that has > their d_hash and d_compare implementations. Create an exception for this > function, where only casefold filesystems are eligible to use their own > d_hash and d_compare functions, allowing to support casefold > filesystems. What do you mean by this sentence? Any casefold fs can be on any layer? All layers on the same casefold sb? same casefold fstype? > > Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx> > --- > fs/overlayfs/namei.c | 11 ++++++----- > fs/overlayfs/overlayfs.h | 2 +- > fs/overlayfs/params.c | 3 ++- > fs/overlayfs/util.c | 12 +++++++----- > 4 files changed, 16 insertions(+), 12 deletions(-) > > diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c > index be5c65d6f8484b1fba6b3fee379ba1d034c0df8a..140bc609ffebe00151cbb446720f5106dbeb2ef2 100644 > --- a/fs/overlayfs/namei.c > +++ b/fs/overlayfs/namei.c > @@ -192,7 +192,7 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, > return real; > } > > - if (ovl_dentry_weird(real)) { > + if (ovl_dentry_weird(real, ofs)) { > dput(real); > return NULL; > } > @@ -244,7 +244,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, > goto out_err; > } > > - if (ovl_dentry_weird(this)) { > + if (ovl_dentry_weird(this, ofs)) { > /* Don't support traversing automounts and other weirdness */ > err = -EREMOTE; > goto out_err; > @@ -365,6 +365,7 @@ static int ovl_lookup_data_layer(struct dentry *dentry, const char *redirect, > struct path *datapath) > { > int err; > + struct ovl_fs *ovl = OVL_FS(layer->fs->sb); ofs please > > err = vfs_path_lookup(layer->mnt->mnt_root, layer->mnt, redirect, > LOOKUP_BENEATH | LOOKUP_NO_SYMLINKS | LOOKUP_NO_XDEV, > @@ -376,7 +377,7 @@ static int ovl_lookup_data_layer(struct dentry *dentry, const char *redirect, > return err; > > err = -EREMOTE; > - if (ovl_dentry_weird(datapath->dentry)) > + if (ovl_dentry_weird(datapath->dentry, ovl)) > goto out_path_put; > > err = -ENOENT; > @@ -767,7 +768,7 @@ struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh) > > if (ovl_is_whiteout(index)) > err = -ESTALE; > - else if (ovl_dentry_weird(index)) > + else if (ovl_dentry_weird(index, ofs)) > err = -EIO; > else > return index; > @@ -815,7 +816,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper, > dput(index); > index = ERR_PTR(-ESTALE); > goto out; > - } else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) || > + } else if (ovl_dentry_weird(index, ofs) || ovl_is_whiteout(index) || > inode_wrong_type(inode, d_inode(origin)->i_mode)) { > /* > * Index should always be of the same file type as origin > diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h > index 6f2f8f4cfbbc177fbd5441483395d7ff72efe332..f3de013517598c44c15ca9f950f6c2f0a5c2084b 100644 > --- a/fs/overlayfs/overlayfs.h > +++ b/fs/overlayfs/overlayfs.h > @@ -445,7 +445,7 @@ void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry, > struct ovl_entry *oe); > void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, > struct ovl_entry *oe, unsigned int mask); > -bool ovl_dentry_weird(struct dentry *dentry); > +bool ovl_dentry_weird(struct dentry *dentry, struct ovl_fs *ovl); > enum ovl_path_type ovl_path_type(struct dentry *dentry); > void ovl_path_upper(struct dentry *dentry, struct path *path); > void ovl_path_lower(struct dentry *dentry, struct path *path); > diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c > index 6759f7d040c89d3b3c01572579c854a900411157..459e8bddf1777c12c9fa0bdfc150e2ea22eaafc3 100644 > --- a/fs/overlayfs/params.c > +++ b/fs/overlayfs/params.c > @@ -277,6 +277,7 @@ 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; ofs pls > > if (!d_is_dir(path->dentry)) > return invalfc(fc, "%s is not a directory", name); > @@ -290,7 +291,7 @@ static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path, > if (sb_has_encoding(path->mnt->mnt_sb)) > return invalfc(fc, "case-insensitive capable filesystem on %s not supported", name); > > - if (ovl_dentry_weird(path->dentry)) > + if (ovl_dentry_weird(path->dentry, ovl)) > return invalfc(fc, "filesystem on %s not supported", name); > > /* > diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c > index 0819c739cc2ffce0dfefa84d3ff8f9f103eec191..4dd523a1a13ab0a6cf51d967d0b712873e6d8580 100644 > --- a/fs/overlayfs/util.c > +++ b/fs/overlayfs/util.c > @@ -200,15 +200,17 @@ void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, > spin_unlock(&dentry->d_lock); > } > > -bool ovl_dentry_weird(struct dentry *dentry) > +bool ovl_dentry_weird(struct dentry *dentry, struct ovl_fs *ovl) ovl_fs *ofs as first argument please > { > + int flags = DCACHE_NEED_AUTOMOUNT | DCACHE_MANAGE_TRANSIT; > + > + if (!ovl->casefold) > + flags |= DCACHE_OP_HASH | DCACHE_OP_COMPARE; > + > if (!d_can_lookup(dentry) && !d_is_file(dentry) && !d_is_symlink(dentry)) > return true; > > - return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | > - DCACHE_MANAGE_TRANSIT | > - DCACHE_OP_HASH | > - DCACHE_OP_COMPARE); > + return dentry->d_flags & flags; > } > > enum ovl_path_type ovl_path_type(struct dentry *dentry) > > -- > 2.49.0 >