[PATCH v4 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied

André Almeida posted 9 patches 1 month, 3 weeks ago
[PATCH v4 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied
Posted by André Almeida 1 month, 3 weeks ago
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@igalia.com>
---
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

Re: [PATCH v4 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied
Posted by Amir Goldstein 1 month, 3 weeks ago
On Thu, Aug 14, 2025 at 12:37 AM André Almeida <andrealmeid@igalia.com> 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@igalia.com>

Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> ---
> 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
>