On Thu, Aug 14, 2025 at 12:37 AM André Almeida <andrealmeid@xxxxxxxxxx> wrote: > > To keep ovl's inodes consistent with their real inodes, create a new > mask for inode file attributes that needs to be copied. Add the > S_CASEFOLD flag as part of the flags that need to be copied along with > the other file attributes. > > Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx> Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx> > --- > Changes from v3: > - Create new flag OVL_FATTR_I_FLAGS_MASK for the file attributes and add > S_CASEFOLD in the OVL_COPY_I_FLAGS_MASK. > - Add WARN()s to check for inode consistency > - Add check for copied up directories > > Changes from v2: > - Instead of manually setting the flag if the realpath dentry is > casefolded, just add this flag as part of the flags that need to be > copied. > --- > fs/overlayfs/copy_up.c | 2 +- > fs/overlayfs/inode.c | 1 + > fs/overlayfs/overlayfs.h | 8 +++++--- > fs/overlayfs/super.c | 1 + > 4 files changed, 8 insertions(+), 4 deletions(-) > > diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c > index 27396fe63f6d5b36143750443304a1f0856e2f56..66bd43a99d2e8548eecf21699a9a6b97e9454d79 100644 > --- a/fs/overlayfs/copy_up.c > +++ b/fs/overlayfs/copy_up.c > @@ -670,7 +670,7 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) > if (err) > return err; > > - if (inode->i_flags & OVL_COPY_I_FLAGS_MASK && > + if (inode->i_flags & OVL_FATTR_I_FLAGS_MASK && > (S_ISREG(c->stat.mode) || S_ISDIR(c->stat.mode))) { > /* > * Copy the fileattr inode flags that are the source of already > diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c > index ecb9f2019395ecd01a124ad029375b1a1d13ebb5..aaa4cf579561299c50046f5ded03d93f056c370c 100644 > --- a/fs/overlayfs/inode.c > +++ b/fs/overlayfs/inode.c > @@ -1277,6 +1277,7 @@ struct inode *ovl_get_inode(struct super_block *sb, > } > ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); > ovl_inode_init(inode, oip, ino, fsid); > + WARN_ON_ONCE(!!IS_CASEFOLDED(inode) != ofs->casefold); > > if (upperdentry && ovl_is_impuredir(sb, upperdentry)) > ovl_set_flag(OVL_IMPURE, inode); > diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h > index bb0d7ded8e763a4a7a6fc506d966ed2f3bdb4f06..50d550dd1b9d7841723880da85359e735bfc9277 100644 > --- a/fs/overlayfs/overlayfs.h > +++ b/fs/overlayfs/overlayfs.h > @@ -821,10 +821,12 @@ struct inode *ovl_get_inode(struct super_block *sb, > struct ovl_inode_params *oip); > void ovl_copyattr(struct inode *to); > > +/* vfs fileattr flags read from overlay.protattr xattr to ovl inode */ > +#define OVL_PROT_I_FLAGS_MASK (S_APPEND | S_IMMUTABLE) > +/* vfs fileattr flags copied from real to ovl inode */ > +#define OVL_FATTR_I_FLAGS_MASK (OVL_PROT_I_FLAGS_MASK | S_SYNC | S_NOATIME) > /* vfs inode flags copied from real to ovl inode */ > -#define OVL_COPY_I_FLAGS_MASK (S_SYNC | S_NOATIME | S_APPEND | S_IMMUTABLE) > -/* vfs inode flags read from overlay.protattr xattr to ovl inode */ > -#define OVL_PROT_I_FLAGS_MASK (S_APPEND | S_IMMUTABLE) > +#define OVL_COPY_I_FLAGS_MASK (OVL_FATTR_I_FLAGS_MASK | S_CASEFOLD) > > /* > * fileattr flags copied from lower to upper inode on copy up. > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index a99c77802efa1a6d96c43019728d3517fccdc16a..7937aa4daa9c29e8b9219f7fcc2abe7fb55b2e5c 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -1335,6 +1335,7 @@ static struct dentry *ovl_get_root(struct super_block *sb, > ovl_dentry_set_flag(OVL_E_CONNECTED, root); > ovl_set_upperdata(d_inode(root)); > ovl_inode_init(d_inode(root), &oip, ino, fsid); > + WARN_ON(!!IS_CASEFOLDED(d_inode(root)) != ofs->casefold); > ovl_dentry_init_flags(root, upperdentry, oe, DCACHE_OP_WEAK_REVALIDATE); > /* root keeps a reference of upperdentry */ > dget(upperdentry); > > -- > 2.50.1 >