linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/9] ovl: Enable support for casefold layers
@ 2025-08-14 17:22 André Almeida
  2025-08-14 17:22 ` [PATCH v5 1/9] fs: Create sb_encoding() helper André Almeida
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

Hi all,

We would like to support the usage of casefold layers with overlayfs to
be used with container tools. This use case requires a simple setup,
where every layer will have the same encoding setting (i.e. Unicode
version and flags), using one upper and one lower layer.

* Implementation

When merge layers, ovl uses a red-black tree to check if a given dentry
name from a lower layers already exists in the upper layer. For merging
case-insensitive names, we need to store then in tree casefolded.
However, when displaying to the user the dentry name, we need to respect
the name chosen when the file was created (e.g. Picture.PNG, instead of
picture.png). To achieve this, I create a new field for cache entries
that stores the casefolded names and a function ovl_strcmp() that uses
this name for searching the rb_tree. For composing the layer, ovl uses
the original name, keeping it consistency with whatever name the user
created.

The rest of the patches are mostly for checking if casefold is being
consistently used across the layers and dropping the mount restrictions
that prevented case-insensitive filesystems to be mounted.

Thanks for the feedback!

---
Changes in v5:
- Reordered commits. libfs commits come earlier in the series
- First ovl commit just prepare and create ofs->casefold. The proper
  enablement is done in the last commit
- Rework ovl_casefold() consumer/free buffer logic out to the caller
- Replace `const char *aux` with `const char *c_name`
- Add pr_warn_ratelimited() for ovl_create_real() error
- Replace "filesystems" with "layers" in the commit messages
- Add "Testing" section to cover letter
v4: https://lore.kernel.org/r/20250813-tonyk-overlayfs-v4-0-357ccf2e12ad@igalia.com

Changes in v4:
- Split patch "ovl: Support case-insensitive lookup" and move patch that
  creates ofs->casefold to the begging of the series
- Merge patch "Store casefold name..." and "Create ovl_casefold()..."
- Make encoding restrictions apply just when casefold is enabled
- Rework set_d_op() with new helper
- Set encoding and encoding flags inside of ovl_get_layers()
- Rework how inode flags are set and checked
v3: https://lore.kernel.org/r/20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com

Changes in v3:
- Rebased on top of vfs-6.18.misc branch
- Added more guards for casefolding things inside of IS_ENABLED(UNICODE)
- Refactor the strncmp() patch to do a single kmalloc() per rb_tree operation
- Instead of casefolding the cache entry name everytime per strncmp(),
  casefold it once and reuse it for every strncmp().
- Created ovl_dentry_ci_operations to not override dentry ops set by
  ovl_dentry_operations
- Instead of setting encoding just when there's a upper layer, set it
  for any first layer (ofs->fs[0].sb), regardless of it being upper or
  not.
- Rewrote the patch that set inode flags
- Check if every dentry is consistent with the root dentry regarding
  casefold
v2: https://lore.kernel.org/r/20250805-tonyk-overlayfs-v2-0-0e54281da318@igalia.com

Changes in v2:
- Almost a full rewritten from the v1.
v1: https://lore.kernel.org/lkml/20250409-tonyk-overlayfs-v1-0-3991616fe9a3@igalia.com/

---
André Almeida (9):
      fs: Create sb_encoding() helper
      fs: Create sb_same_encoding() helper
      ovl: Prepare for mounting case-insensitive enabled layers
      ovl: Create ovl_casefold() to support casefolded strncmp()
      ovl: Ensure that all layers have the same encoding
      ovl: Set case-insensitive dentry operations for ovl sb
      ovl: Add S_CASEFOLD as part of the inode flag to be copied
      ovl: Check for casefold consistency when creating new dentries
      ovl: Support mounting case-insensitive enabled layers

 fs/overlayfs/copy_up.c   |   2 +-
 fs/overlayfs/dir.c       |   6 +++
 fs/overlayfs/inode.c     |   1 +
 fs/overlayfs/namei.c     |  17 +++----
 fs/overlayfs/overlayfs.h |   8 ++--
 fs/overlayfs/ovl_entry.h |   1 +
 fs/overlayfs/params.c    |  15 +++++--
 fs/overlayfs/params.h    |   1 +
 fs/overlayfs/readdir.c   | 115 +++++++++++++++++++++++++++++++++++++++--------
 fs/overlayfs/super.c     |  51 +++++++++++++++++++++
 fs/overlayfs/util.c      |   8 ++--
 include/linux/fs.h       |  27 ++++++++++-
 12 files changed, 213 insertions(+), 39 deletions(-)
---
base-commit: 0cc53520e68bea7fb80fdc6bdf8d226d1b6a98d9
change-id: 20250409-tonyk-overlayfs-591f5e4d407a

Best regards,
-- 
André Almeida <andrealmeid@igalia.com>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v5 1/9] fs: Create sb_encoding() helper
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 17:22 ` [PATCH v5 2/9] fs: Create sb_same_encoding() helper André Almeida
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

Filesystems that need to deal with the super block encoding need to use
a if IS_ENABLED(CONFIG_UNICODE) around it because this struct member is
not declared otherwise. In order to move this if/endif guards outside of
the filesytem code and make it simpler, create a new function that
returns the s_encoding member of struct super_block if Unicode is
enabled, and return NULL otherwise.

Suggested-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
Changes from v4:
- Move it to the begin of the series

Changes from v3:
- New patch
---
 include/linux/fs.h | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index d7ab4f96d7051f23246c1a16a2d09b1ffcd2d5de..43b3a7cf6750d3db3e5350908c95bc8a729db41a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3740,15 +3740,20 @@ static inline bool generic_ci_validate_strict_name(struct inode *dir, struct qst
 }
 #endif
 
-static inline bool sb_has_encoding(const struct super_block *sb)
+static inline struct unicode_map *sb_encoding(const struct super_block *sb)
 {
 #if IS_ENABLED(CONFIG_UNICODE)
-	return !!sb->s_encoding;
+	return sb->s_encoding;
 #else
-	return false;
+	return NULL;
 #endif
 }
 
+static inline bool sb_has_encoding(const struct super_block *sb)
+{
+	return !!sb_encoding(sb);
+}
+
 int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
 		unsigned int ia_valid);
 int setattr_prepare(struct mnt_idmap *, struct dentry *, struct iattr *);

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 2/9] fs: Create sb_same_encoding() helper
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
  2025-08-14 17:22 ` [PATCH v5 1/9] fs: Create sb_encoding() helper André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 17:22 ` [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers André Almeida
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

For cases where a file lookup can look in different filesystems (like in
overlayfs), both super blocks must have the same encoding and the same
flags. To help with that, create a sb_same_encoding() function.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
Changes from v4:
- Move it to the begin of the series

Changes from v3:
- Improve wording

Changes from v2:
- Simplify the code. Instead of `if (cond) return true`, just do `return
  cond`;
---
 include/linux/fs.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 43b3a7cf6750d3db3e5350908c95bc8a729db41a..ec867f112fd5fce7c1cceeb8598979972688d220 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3754,6 +3754,24 @@ static inline bool sb_has_encoding(const struct super_block *sb)
 	return !!sb_encoding(sb);
 }
 
+/*
+ * Compare if two super blocks have the same encoding and flags
+ */
+static inline bool sb_same_encoding(const struct super_block *sb1,
+				    const struct super_block *sb2)
+{
+#if IS_ENABLED(CONFIG_UNICODE)
+	if (sb1->s_encoding == sb2->s_encoding)
+		return true;
+
+	return (sb1->s_encoding && sb2->s_encoding &&
+	       (sb1->s_encoding->version == sb2->s_encoding->version) &&
+	       (sb1->s_encoding_flags == sb2->s_encoding_flags));
+#else
+	return true;
+#endif
+}
+
 int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
 		unsigned int ia_valid);
 int setattr_prepare(struct mnt_idmap *, struct dentry *, struct iattr *);

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
  2025-08-14 17:22 ` [PATCH v5 1/9] fs: Create sb_encoding() helper André Almeida
  2025-08-14 17:22 ` [PATCH v5 2/9] fs: Create sb_same_encoding() helper André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 18:47   ` Amir Goldstein
  2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

Prepare for mounting layers with case-insensitive dentries in order to
supporting such layers in overlayfs, while enforcing uniform casefold
layers.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes from v4:
- Move relaxation of dentry_weird to the last patch
- s/filesystems/layerss
- Commit now says "Prepare for" instead of "Support"
---
 fs/overlayfs/ovl_entry.h |  1 +
 fs/overlayfs/params.c    | 15 ++++++++++++---
 fs/overlayfs/params.h    |  1 +
 3 files changed, 14 insertions(+), 3 deletions(-)

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..17d2354ba88d92e1d9653e8cb1382d860a7329c5 100644
--- a/fs/overlayfs/params.c
+++ b/fs/overlayfs/params.c
@@ -277,16 +277,25 @@ 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 *ofs = fc->s_fs_info;
+	bool is_casefolded = ovl_dentry_casefolded(path->dentry);
 
 	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);
diff --git a/fs/overlayfs/params.h b/fs/overlayfs/params.h
index c96d939820211ddc63e265670a2aff60d95eec49..ffd53cdd84827cce827e8852f2de545f966ce60d 100644
--- a/fs/overlayfs/params.h
+++ b/fs/overlayfs/params.h
@@ -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);

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (2 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 18:59   ` Amir Goldstein
                     ` (2 more replies)
  2025-08-14 17:22 ` [PATCH v5 5/9] ovl: Ensure that all layers have the same encoding André Almeida
                   ` (5 subsequent siblings)
  9 siblings, 3 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

To add overlayfs support casefold layers, create a new function
ovl_casefold(), to be able to do case-insensitive strncmp().

ovl_casefold() allocates a new buffer and stores the casefolded version
of the string on it. If the allocation or the casefold operation fails,
fallback to use the original string.

The case-insentive name is then used in the rb-tree search/insertion
operation. If the name is found in the rb-tree, the name can be
discarded and the buffer is freed. If the name isn't found, it's then
stored at struct ovl_cache_entry to be used later.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes from v4:
 - Move the consumer/free buffer logic out to the caller
 - s/aux/c_name

Changes from v3:
 - Improve commit message text
 - s/OVL_NAME_LEN/NAME_MAX
 - drop #ifdef in favor of if(IS_ENABLED)
 - use new helper sb_encoding
 - merged patch "Store casefold name..." and "Create ovl_casefold()..."
 - Guard all the casefolding inside of IS_ENABLED(UNICODE)

Changes from v2:
- Refactor the patch to do a single kmalloc() per rb_tree operation
- Instead of casefolding the cache entry name everytime per strncmp(),
  casefold it once and reuse it for every strncmp().
---
 fs/overlayfs/readdir.c | 115 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 97 insertions(+), 18 deletions(-)

diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index b65cdfce31ce27172d28d879559f1008b9c87320..803ac6a7516d0156ae7793ee1ff884dbbf2e20b0 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -27,6 +27,8 @@ struct ovl_cache_entry {
 	bool is_upper;
 	bool is_whiteout;
 	bool check_xwhiteout;
+	const char *cf_name;
+	int cf_len;
 	char name[];
 };
 
@@ -45,6 +47,7 @@ struct ovl_readdir_data {
 	struct list_head *list;
 	struct list_head middle;
 	struct ovl_cache_entry *first_maybe_whiteout;
+	struct unicode_map *map;
 	int count;
 	int err;
 	bool is_upper;
@@ -66,6 +69,27 @@ static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
 	return rb_entry(n, struct ovl_cache_entry, node);
 }
 
+static int ovl_casefold(struct unicode_map *map, const char *str, int len, char **dst)
+{
+	const struct qstr qstr = { .name = str, .len = len };
+	int cf_len;
+
+	if (!IS_ENABLED(CONFIG_UNICODE) || !map || is_dot_dotdot(str, len))
+		return 0;
+
+	*dst = kmalloc(NAME_MAX, GFP_KERNEL);
+
+	if (dst) {
+		cf_len = utf8_casefold(map, &qstr, *dst, NAME_MAX);
+
+		if (cf_len > 0)
+			return cf_len;
+	}
+
+	kfree(*dst);
+	return 0;
+}
+
 static bool ovl_cache_entry_find_link(const char *name, int len,
 				      struct rb_node ***link,
 				      struct rb_node **parent)
@@ -79,7 +103,7 @@ static bool ovl_cache_entry_find_link(const char *name, int len,
 
 		*parent = *newp;
 		tmp = ovl_cache_entry_from_node(*newp);
-		cmp = strncmp(name, tmp->name, len);
+		cmp = strncmp(name, tmp->cf_name, tmp->cf_len);
 		if (cmp > 0)
 			newp = &tmp->node.rb_right;
 		else if (cmp < 0 || len < tmp->len)
@@ -101,7 +125,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
 	while (node) {
 		struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
 
-		cmp = strncmp(name, p->name, len);
+		cmp = strncmp(name, p->cf_name, p->cf_len);
 		if (cmp > 0)
 			node = p->node.rb_right;
 		else if (cmp < 0 || len < p->len)
@@ -145,13 +169,16 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd,
 
 static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
 						   const char *name, int len,
+						   const char *cf_name, int cf_len,
 						   u64 ino, unsigned int d_type)
 {
 	struct ovl_cache_entry *p;
 
 	p = kmalloc(struct_size(p, name, len + 1), GFP_KERNEL);
-	if (!p)
+	if (!p) {
+		kfree(cf_name);
 		return NULL;
+	}
 
 	memcpy(p->name, name, len);
 	p->name[len] = '\0';
@@ -167,6 +194,14 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
 	/* Defer check for overlay.whiteout to ovl_iterate() */
 	p->check_xwhiteout = rdd->in_xwhiteouts_dir && d_type == DT_REG;
 
+	if (cf_name && cf_name != name) {
+		p->cf_name = cf_name;
+		p->cf_len = cf_len;
+	} else {
+		p->cf_name = p->name;
+		p->cf_len = len;
+	}
+
 	if (d_type == DT_CHR) {
 		p->next_maybe_whiteout = rdd->first_maybe_whiteout;
 		rdd->first_maybe_whiteout = p;
@@ -174,48 +209,55 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
 	return p;
 }
 
-static bool ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
-				  const char *name, int len, u64 ino,
+/* Return 0 for found, 1 for added, <0 for error */
+static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
+				  const char *name, int len,
+				  const char *cf_name, int cf_len,
+				  u64 ino,
 				  unsigned int d_type)
 {
 	struct rb_node **newp = &rdd->root->rb_node;
 	struct rb_node *parent = NULL;
 	struct ovl_cache_entry *p;
 
-	if (ovl_cache_entry_find_link(name, len, &newp, &parent))
-		return true;
+	if (ovl_cache_entry_find_link(cf_name, cf_len, &newp, &parent))
+		return 0;
 
-	p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
+	p = ovl_cache_entry_new(rdd, name, len, cf_name, cf_len, ino, d_type);
 	if (p == NULL) {
 		rdd->err = -ENOMEM;
-		return false;
+		return -ENOMEM;
 	}
 
 	list_add_tail(&p->l_node, rdd->list);
 	rb_link_node(&p->node, parent, newp);
 	rb_insert_color(&p->node, rdd->root);
 
-	return true;
+	return 1;
 }
 
-static bool ovl_fill_lowest(struct ovl_readdir_data *rdd,
+/* Return 0 for found, 1 for added, <0 for error */
+static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
 			   const char *name, int namelen,
+			   const char *cf_name, int cf_len,
 			   loff_t offset, u64 ino, unsigned int d_type)
 {
 	struct ovl_cache_entry *p;
 
-	p = ovl_cache_entry_find(rdd->root, name, namelen);
+	p = ovl_cache_entry_find(rdd->root, cf_name, cf_len);
 	if (p) {
 		list_move_tail(&p->l_node, &rdd->middle);
+		return 0;
 	} else {
-		p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
+		p = ovl_cache_entry_new(rdd, name, namelen, cf_name, cf_len,
+					ino, d_type);
 		if (p == NULL)
 			rdd->err = -ENOMEM;
 		else
 			list_add_tail(&p->l_node, &rdd->middle);
 	}
 
-	return rdd->err == 0;
+	return rdd->err ?: 1;
 }
 
 void ovl_cache_free(struct list_head *list)
@@ -223,8 +265,11 @@ void ovl_cache_free(struct list_head *list)
 	struct ovl_cache_entry *p;
 	struct ovl_cache_entry *n;
 
-	list_for_each_entry_safe(p, n, list, l_node)
+	list_for_each_entry_safe(p, n, list, l_node) {
+		if (p->cf_name != p->name)
+			kfree(p->cf_name);
 		kfree(p);
+	}
 
 	INIT_LIST_HEAD(list);
 }
@@ -260,12 +305,38 @@ static bool ovl_fill_merge(struct dir_context *ctx, const char *name,
 {
 	struct ovl_readdir_data *rdd =
 		container_of(ctx, struct ovl_readdir_data, ctx);
+	struct ovl_fs *ofs = OVL_FS(rdd->dentry->d_sb);
+	char *cf_name = NULL;
+	int c_len = 0;
+	int ret;
+
+	const char *c_name = NULL;
+
+	if (ofs->casefold)
+		c_len = ovl_casefold(rdd->map, name, namelen, &cf_name);
+
+	if (c_len <= 0) {
+		c_name = name;
+		c_len = namelen;
+	} else {
+		c_name = cf_name;
+	}
 
 	rdd->count++;
 	if (!rdd->is_lowest)
-		return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type);
+		ret = ovl_cache_entry_add_rb(rdd, name, namelen, c_name, c_len, ino, d_type);
 	else
-		return ovl_fill_lowest(rdd, name, namelen, offset, ino, d_type);
+		ret = ovl_fill_lowest(rdd, name, namelen, c_name, c_len, offset, ino, d_type);
+
+	/*
+	 * If ret == 1, that means that c_name is being used as part of struct
+	 * ovl_cache_entry and will be freed at ovl_cache_free(). Otherwise,
+	 * c_name was found in the rb-tree so we can free it here.
+	 */
+	if (ret != 1 && c_name != name)
+		kfree(c_name);
+
+	return ret >= 0;
 }
 
 static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data *rdd)
@@ -357,12 +428,18 @@ static int ovl_dir_read_merged(struct dentry *dentry, struct list_head *list,
 		.list = list,
 		.root = root,
 		.is_lowest = false,
+		.map = NULL,
 	};
 	int idx, next;
 	const struct ovl_layer *layer;
+	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
 
 	for (idx = 0; idx != -1; idx = next) {
 		next = ovl_path_next(idx, dentry, &realpath, &layer);
+
+		if (ofs->casefold)
+			rdd.map = sb_encoding(realpath.dentry->d_sb);
+
 		rdd.is_upper = ovl_dentry_upper(dentry) == realpath.dentry;
 		rdd.in_xwhiteouts_dir = layer->has_xwhiteouts &&
 					ovl_dentry_has_xwhiteouts(dentry);
@@ -555,7 +632,7 @@ static bool ovl_fill_plain(struct dir_context *ctx, const char *name,
 		container_of(ctx, struct ovl_readdir_data, ctx);
 
 	rdd->count++;
-	p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
+	p = ovl_cache_entry_new(rdd, name, namelen, NULL, 0, ino, d_type);
 	if (p == NULL) {
 		rdd->err = -ENOMEM;
 		return false;
@@ -1023,6 +1100,8 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
 
 del_entry:
 		list_del(&p->l_node);
+		if (p->cf_name != p->name)
+			kfree(p->cf_name);
 		kfree(p);
 	}
 

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 5/9] ovl: Ensure that all layers have the same encoding
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (3 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 17:22 ` [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb André Almeida
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

When merging layers from different filesystems with casefold enabled,
all layers should use the same encoding version and have the same flags
to avoid any kind of incompatibility issues.

Also, set the encoding and the encoding flags for the ovl super block as
the same as used by the first valid layer.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
Changes from v3:
- Check this restriction just when casefold is enabled
- Create new helper ovl_set_encoding() and change the logic a bit
---
 fs/overlayfs/super.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index df85a76597e910d00323018f1d2cd720c5db921d..b1dbd3c79961094d00c7f99cc622e515d544d22f 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -991,6 +991,18 @@ static int ovl_get_data_fsid(struct ovl_fs *ofs)
 	return ofs->numfs;
 }
 
+/*
+ * Set the ovl sb encoding as the same one used by the first layer
+ */
+static void ovl_set_encoding(struct super_block *sb, struct super_block *fs_sb)
+{
+#if IS_ENABLED(CONFIG_UNICODE)
+	if (sb_has_encoding(fs_sb)) {
+		sb->s_encoding = fs_sb->s_encoding;
+		sb->s_encoding_flags = fs_sb->s_encoding_flags;
+	}
+#endif
+}
 
 static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
 			  struct ovl_fs_context *ctx, struct ovl_layer *layers)
@@ -1024,6 +1036,9 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
 	if (ovl_upper_mnt(ofs)) {
 		ofs->fs[0].sb = ovl_upper_mnt(ofs)->mnt_sb;
 		ofs->fs[0].is_lower = false;
+
+		if (ofs->casefold)
+			ovl_set_encoding(sb, ofs->fs[0].sb);
 	}
 
 	nr_merged_lower = ctx->nr - ctx->nr_data;
@@ -1083,6 +1098,16 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
 		l->name = NULL;
 		ofs->numlayer++;
 		ofs->fs[fsid].is_lower = true;
+
+		if (ofs->casefold) {
+			if (!ovl_upper_mnt(ofs) && !sb_has_encoding(sb))
+				ovl_set_encoding(sb, ofs->fs[fsid].sb);
+
+			if (!sb_has_encoding(sb) || !sb_same_encoding(sb, mnt->mnt_sb)) {
+				pr_err("all layers must have the same encoding\n");
+				return -EINVAL;
+			}
+		}
 	}
 
 	/*

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (4 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 5/9] ovl: Ensure that all layers have the same encoding André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-15 11:52   ` kernel test robot
  2025-08-14 17:22 ` [PATCH v5 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied André Almeida
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

For filesystems with encoding (i.e. with case-insensitive support), set
the dentry operations for the super block as ovl_dentry_ci_operations.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
Changes from v3:
- new helper ovl_set_d_op()
- encoding flags are now set in a step earlier

Changes from v2:
- Create ovl_dentry_ci_operations to not override dentry ops set by
  ovl_dentry_operations
- Create a new function for this
- Instead of setting encoding just when there's a upper layer, set it
  for any first layer (ofs->fs[0].sb), regardless of it being upper or
  not.
---
 fs/overlayfs/super.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index b1dbd3c79961094d00c7f99cc622e515d544d22f..a99c77802efa1a6d96c43019728d3517fccdc16a 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -161,6 +161,16 @@ static const struct dentry_operations ovl_dentry_operations = {
 	.d_weak_revalidate = ovl_dentry_weak_revalidate,
 };
 
+#if IS_ENABLED(CONFIG_UNICODE)
+static const struct dentry_operations ovl_dentry_ci_operations = {
+	.d_real = ovl_d_real,
+	.d_revalidate = ovl_dentry_revalidate,
+	.d_weak_revalidate = ovl_dentry_weak_revalidate,
+	.d_hash = generic_ci_d_hash,
+	.d_compare = generic_ci_d_compare,
+};
+#endif
+
 static struct kmem_cache *ovl_inode_cachep;
 
 static struct inode *ovl_alloc_inode(struct super_block *sb)
@@ -1332,6 +1342,19 @@ static struct dentry *ovl_get_root(struct super_block *sb,
 	return root;
 }
 
+static void ovl_set_d_op(struct super_block *sb)
+{
+	struct ovl_fs *ofs = sb->s_fs_info;
+
+#if IS_ENABLED(CONFIG_UNICODE)
+	if (ofs->casefold) {
+		set_default_d_op(sb, &ovl_dentry_ci_operations);
+		return;
+	}
+#endif
+	set_default_d_op(sb, &ovl_dentry_operations);
+}
+
 int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
 {
 	struct ovl_fs *ofs = sb->s_fs_info;
@@ -1443,6 +1466,8 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
 	if (IS_ERR(oe))
 		goto out_err;
 
+	ovl_set_d_op(sb);
+
 	/* If the upper fs is nonexistent, we mark overlayfs r/o too */
 	if (!ovl_upper_mnt(ofs))
 		sb->s_flags |= SB_RDONLY;

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (5 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 17:22 ` [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries André Almeida
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

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


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (6 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 18:54   ` Amir Goldstein
  2025-08-14 17:22 ` [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers André Almeida
  2025-08-14 17:30 ` [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
  9 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

In a overlayfs with casefold enabled, all new dentries should have
casefold enabled as well. Check this at ovl_create_real().

Signed-off-by: André Almeida <andrealmeid@igalia.com>
---
Changes from v4:
- Add pr_warn()

Changes from v3:
- New patch
---
 fs/overlayfs/dir.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 70b8687dc45e8e33079c865ae302ac58464224a6..88e888ed8696363d6cde39817f6c21e795f0760a 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -187,6 +187,12 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent,
 			/* mkdir is special... */
 			newdentry =  ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
 			err = PTR_ERR_OR_ZERO(newdentry);
+			/* expect to inherit casefolding from workdir/upperdir */
+			if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
+				pr_warn_ratelimited("dentry wrong casefold inheritance");
+				dput(newdentry);
+				err = -EINVAL;
+			}
 			break;
 
 		case S_IFCHR:

-- 
2.50.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (7 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries André Almeida
@ 2025-08-14 17:22 ` André Almeida
  2025-08-14 18:48   ` Amir Goldstein
  2025-08-14 17:30 ` [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
  9 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:22 UTC (permalink / raw)
  To: Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev, André Almeida

Drop the restriction for casefold dentries lookup to enable support for
case-insensitive layers in overlayfs.

Support case-insensitive layers with the condition that they should be
uniformly enabled across the stack and (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@igalia.com>
---
Changes from v4:
- Move the dentry_weird relaxation to this patch
- Reword the commit title and message

Changes from v3:
- New patch, splited from the patch that creates ofs->casefold
---
 fs/overlayfs/namei.c | 17 +++++++++--------
 fs/overlayfs/util.c  |  8 ++++----
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 76d6248b625e7c58e09685e421aef616aadea40a..e93bcc5727bcafdc18a499b47a7609fd41ecaec8 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 modified 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/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


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
                   ` (8 preceding siblings ...)
  2025-08-14 17:22 ` [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers André Almeida
@ 2025-08-14 17:30 ` André Almeida
  2025-08-14 19:06   ` Amir Goldstein
  9 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-14 17:30 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

Em 14/08/2025 14:22, André Almeida escreveu:
> Hi all,
> 
> We would like to support the usage of casefold layers with overlayfs to
> be used with container tools. This use case requires a simple setup,
> where every layer will have the same encoding setting (i.e. Unicode
> version and flags), using one upper and one lower layer.
> 

Amir,

I tried to run your xfstest for casefolded ovl[1] but I can see that it 
still requires some work. I tried to fix some of the TODO's but I didn't 
managed to mkfs the base fs with casefold enabled... but we might as 
well discuss this in a dedicated xfstest email thread if you want to 
send a RFC for the test.

[1] 
https://github.com/amir73il/xfstests/commit/03b3facf60e14cab9fc563ad54893563b4cb18e4 



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers
  2025-08-14 17:22 ` [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers André Almeida
@ 2025-08-14 18:47   ` Amir Goldstein
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Goldstein @ 2025-08-14 18:47 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> Prepare for mounting layers with case-insensitive dentries in order to
> supporting such layers in overlayfs, while enforcing uniform casefold
> layers.
>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> ---
> Changes from v4:
> - Move relaxation of dentry_weird to the last patch
> - s/filesystems/layerss
> - Commit now says "Prepare for" instead of "Support"
> ---
>  fs/overlayfs/ovl_entry.h |  1 +
>  fs/overlayfs/params.c    | 15 ++++++++++++---
>  fs/overlayfs/params.h    |  1 +
>  3 files changed, 14 insertions(+), 3 deletions(-)
>
> 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..17d2354ba88d92e1d9653e8cb1382d860a7329c5 100644
> --- a/fs/overlayfs/params.c
> +++ b/fs/overlayfs/params.c
> @@ -277,16 +277,25 @@ 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 *ofs = fc->s_fs_info;
> +       bool is_casefolded = ovl_dentry_casefolded(path->dentry);
>
>         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);
> diff --git a/fs/overlayfs/params.h b/fs/overlayfs/params.h
> index c96d939820211ddc63e265670a2aff60d95eec49..ffd53cdd84827cce827e8852f2de545f966ce60d 100644
> --- a/fs/overlayfs/params.h
> +++ b/fs/overlayfs/params.h
> @@ -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);
>
> --
> 2.50.1
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers
  2025-08-14 17:22 ` [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers André Almeida
@ 2025-08-14 18:48   ` Amir Goldstein
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Goldstein @ 2025-08-14 18:48 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> Drop the restriction for casefold dentries lookup to enable support for
> case-insensitive layers in overlayfs.
>
> Support case-insensitive layers with the condition that they should be
> uniformly enabled across the stack and (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@igalia.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>

> ---
> Changes from v4:
> - Move the dentry_weird relaxation to this patch
> - Reword the commit title and message
>
> Changes from v3:
> - New patch, splited from the patch that creates ofs->casefold
> ---
>  fs/overlayfs/namei.c | 17 +++++++++--------
>  fs/overlayfs/util.c  |  8 ++++----
>  2 files changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
> index 76d6248b625e7c58e09685e421aef616aadea40a..e93bcc5727bcafdc18a499b47a7609fd41ecaec8 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 modified 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/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
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries
  2025-08-14 17:22 ` [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries André Almeida
@ 2025-08-14 18:54   ` Amir Goldstein
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Goldstein @ 2025-08-14 18:54 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> In a overlayfs with casefold enabled, all new dentries should have
> casefold enabled as well. Check this at ovl_create_real().
>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> ---
> Changes from v4:
> - Add pr_warn()
>
> Changes from v3:
> - New patch
> ---
>  fs/overlayfs/dir.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index 70b8687dc45e8e33079c865ae302ac58464224a6..88e888ed8696363d6cde39817f6c21e795f0760a 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -187,6 +187,12 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent,
>                         /* mkdir is special... */
>                         newdentry =  ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
>                         err = PTR_ERR_OR_ZERO(newdentry);
> +                       /* expect to inherit casefolding from workdir/upperdir */
> +                       if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
> +                               pr_warn_ratelimited("dentry wrong casefold inheritance");

pr_warn_ratelimited("wrong inherited casefold (%pd2)\n", newdentry);

No need to report.
I can fix that on commit.

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


Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
@ 2025-08-14 18:59   ` Amir Goldstein
  2025-08-15 16:16   ` Amir Goldstein
  2025-08-17 14:33   ` Amir Goldstein
  2 siblings, 0 replies; 27+ messages in thread
From: Amir Goldstein @ 2025-08-14 18:59 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> To add overlayfs support casefold layers, create a new function
> ovl_casefold(), to be able to do case-insensitive strncmp().
>
> ovl_casefold() allocates a new buffer and stores the casefolded version
> of the string on it. If the allocation or the casefold operation fails,
> fallback to use the original string.
>
> The case-insentive name is then used in the rb-tree search/insertion
> operation. If the name is found in the rb-tree, the name can be
> discarded and the buffer is freed. If the name isn't found, it's then
> stored at struct ovl_cache_entry to be used later.
>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> ---
> Changes from v4:
>  - Move the consumer/free buffer logic out to the caller
>  - s/aux/c_name
>
> Changes from v3:
>  - Improve commit message text
>  - s/OVL_NAME_LEN/NAME_MAX
>  - drop #ifdef in favor of if(IS_ENABLED)
>  - use new helper sb_encoding
>  - merged patch "Store casefold name..." and "Create ovl_casefold()..."
>  - Guard all the casefolding inside of IS_ENABLED(UNICODE)
>
> Changes from v2:
> - Refactor the patch to do a single kmalloc() per rb_tree operation
> - Instead of casefolding the cache entry name everytime per strncmp(),
>   casefold it once and reuse it for every strncmp().
> ---
>  fs/overlayfs/readdir.c | 115 +++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 97 insertions(+), 18 deletions(-)
>
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index b65cdfce31ce27172d28d879559f1008b9c87320..803ac6a7516d0156ae7793ee1ff884dbbf2e20b0 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -27,6 +27,8 @@ struct ovl_cache_entry {
>         bool is_upper;
>         bool is_whiteout;
>         bool check_xwhiteout;
> +       const char *cf_name;
> +       int cf_len;
>         char name[];
>  };
>
> @@ -45,6 +47,7 @@ struct ovl_readdir_data {
>         struct list_head *list;
>         struct list_head middle;
>         struct ovl_cache_entry *first_maybe_whiteout;
> +       struct unicode_map *map;
>         int count;
>         int err;
>         bool is_upper;
> @@ -66,6 +69,27 @@ static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
>         return rb_entry(n, struct ovl_cache_entry, node);
>  }
>
> +static int ovl_casefold(struct unicode_map *map, const char *str, int len, char **dst)
> +{
> +       const struct qstr qstr = { .name = str, .len = len };
> +       int cf_len;
> +
> +       if (!IS_ENABLED(CONFIG_UNICODE) || !map || is_dot_dotdot(str, len))
> +               return 0;
> +
> +       *dst = kmalloc(NAME_MAX, GFP_KERNEL);
> +
> +       if (dst) {
> +               cf_len = utf8_casefold(map, &qstr, *dst, NAME_MAX);
> +
> +               if (cf_len > 0)
> +                       return cf_len;
> +       }
> +
> +       kfree(*dst);
> +       return 0;
> +}
> +
>  static bool ovl_cache_entry_find_link(const char *name, int len,
>                                       struct rb_node ***link,
>                                       struct rb_node **parent)
> @@ -79,7 +103,7 @@ static bool ovl_cache_entry_find_link(const char *name, int len,
>
>                 *parent = *newp;
>                 tmp = ovl_cache_entry_from_node(*newp);
> -               cmp = strncmp(name, tmp->name, len);
> +               cmp = strncmp(name, tmp->cf_name, tmp->cf_len);
>                 if (cmp > 0)
>                         newp = &tmp->node.rb_right;
>                 else if (cmp < 0 || len < tmp->len)
> @@ -101,7 +125,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
>         while (node) {
>                 struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
>
> -               cmp = strncmp(name, p->name, len);
> +               cmp = strncmp(name, p->cf_name, p->cf_len);
>                 if (cmp > 0)
>                         node = p->node.rb_right;
>                 else if (cmp < 0 || len < p->len)
> @@ -145,13 +169,16 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd,
>
>  static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
>                                                    const char *name, int len,
> +                                                  const char *cf_name, int cf_len,
>                                                    u64 ino, unsigned int d_type)
>  {
>         struct ovl_cache_entry *p;
>
>         p = kmalloc(struct_size(p, name, len + 1), GFP_KERNEL);
> -       if (!p)
> +       if (!p) {
> +               kfree(cf_name);

Not needed.
Caller will get -ENOMEM and will free c_name

No need to repost just for this I can fix on commit.

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

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-14 17:30 ` [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
@ 2025-08-14 19:06   ` Amir Goldstein
  2025-08-15 13:33     ` André Almeida
  0 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-14 19:06 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> Em 14/08/2025 14:22, André Almeida escreveu:
> > Hi all,
> >
> > We would like to support the usage of casefold layers with overlayfs to
> > be used with container tools. This use case requires a simple setup,
> > where every layer will have the same encoding setting (i.e. Unicode
> > version and flags), using one upper and one lower layer.
> >
>
> Amir,
>
> I tried to run your xfstest for casefolded ovl[1] but I can see that it
> still requires some work. I tried to fix some of the TODO's but I didn't
> managed to mkfs the base fs with casefold enabled...

When you write mkfs the base fs, I suspect that you are running
check -overlay or something.

This is not how this test should be run.
It should run as a normal test on ext4 or any other fs  that supports casefold.

When you run check -g casefold, the generic test generic/556 will
be run if the test fs supports casefold (e.g. ext4).

The new added test belongs to the same group and should run
if you run check -g casefold if the test fs supports casefold (e.g. ext4).

> but we might as
> well discuss this in a dedicated xfstest email thread if you want to
> send a RFC for the test.
>
> [1]
> https://github.com/amir73il/xfstests/commit/03b3facf60e14cab9fc563ad54893563b4cb18e4
>
>

Can you point me to a branch with your ovl patches, so I can pull it
for testing?

Feel free to fix the 2 minor review comments on v5 in your branch.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb
  2025-08-14 17:22 ` [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb André Almeida
@ 2025-08-15 11:52   ` kernel test robot
  0 siblings, 0 replies; 27+ messages in thread
From: kernel test robot @ 2025-08-15 11:52 UTC (permalink / raw)
  To: André Almeida, Miklos Szeredi, Amir Goldstein, Theodore Tso,
	Gabriel Krisman Bertazi
  Cc: llvm, oe-kbuild-all, linux-unionfs, linux-kernel, linux-fsdevel,
	Alexander Viro, Christian Brauner, Jan Kara, kernel-dev,
	André Almeida

Hi André,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 0cc53520e68bea7fb80fdc6bdf8d226d1b6a98d9]

url:    https://github.com/intel-lab-lkp/linux/commits/Andr-Almeida/fs-Create-sb_encoding-helper/20250815-013213
base:   0cc53520e68bea7fb80fdc6bdf8d226d1b6a98d9
patch link:    https://lore.kernel.org/r/20250814-tonyk-overlayfs-v5-6-c5b80a909cbd%40igalia.com
patch subject: [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb
config: i386-buildonly-randconfig-003-20250815 (https://download.01.org/0day-ci/archive/20250815/202508151941.VDMlemUG-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250815/202508151941.VDMlemUG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508151941.VDMlemUG-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> fs/overlayfs/super.c:1347:17: warning: unused variable 'ofs' [-Wunused-variable]
    1347 |         struct ovl_fs *ofs = sb->s_fs_info;
         |                        ^~~
   1 warning generated.


vim +/ofs +1347 fs/overlayfs/super.c

  1344	
  1345	static void ovl_set_d_op(struct super_block *sb)
  1346	{
> 1347		struct ovl_fs *ofs = sb->s_fs_info;
  1348	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-14 19:06   ` Amir Goldstein
@ 2025-08-15 13:33     ` André Almeida
  2025-08-15 13:50       ` Amir Goldstein
  0 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-15 13:33 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

Hi Amir,

On 8/14/25 21:06, Amir Goldstein wrote:
> On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
>> Em 14/08/2025 14:22, André Almeida escreveu:
>>> Hi all,
>>>
>>> We would like to support the usage of casefold layers with overlayfs to
>>> be used with container tools. This use case requires a simple setup,
>>> where every layer will have the same encoding setting (i.e. Unicode
>>> version and flags), using one upper and one lower layer.
>>>
>> Amir,
>>
>> I tried to run your xfstest for casefolded ovl[1] but I can see that it
>> still requires some work. I tried to fix some of the TODO's but I didn't
>> managed to mkfs the base fs with casefold enabled...
> When you write mkfs the base fs, I suspect that you are running
> check -overlay or something.
>
> This is not how this test should be run.
> It should run as a normal test on ext4 or any other fs  that supports casefold.
>
> When you run check -g casefold, the generic test generic/556 will
> be run if the test fs supports casefold (e.g. ext4).
>
> The new added test belongs to the same group and should run
> if you run check -g casefold if the test fs supports casefold (e.g. ext4).
>
I see, I used `check -overlay` indeed, thanks!

>> but we might as
>> well discuss this in a dedicated xfstest email thread if you want to
>> send a RFC for the test.
>>
>> [1]
>> https://github.com/amir73il/xfstests/commit/03b3facf60e14cab9fc563ad54893563b4cb18e4
>>
>>
> Can you point me to a branch with your ovl patches, so I can pull it
> for testing?

You can find my branch here, based on top of vfs.all: 
https://gitlab.freedesktop.org/andrealmeid/linux/-/commits/ovl_casefold

I fixed the following minor issues:

- 4/9: dropped the `kfree(cf_name);` - 6/9: fixed kernel robot warning 
`unused variable 'ofs'` - 8/9: change pr_warn_ratelimited() string

>
> Feel free to fix the 2 minor review comments on v5 in your branch.
>
> Thanks,
> Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-15 13:33     ` André Almeida
@ 2025-08-15 13:50       ` Amir Goldstein
  2025-08-17 15:03         ` Amir Goldstein
  0 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-15 13:50 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

On Fri, Aug 15, 2025 at 3:34 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> Hi Amir,
>
> On 8/14/25 21:06, Amir Goldstein wrote:
> > On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
> >> Em 14/08/2025 14:22, André Almeida escreveu:
> >>> Hi all,
> >>>
> >>> We would like to support the usage of casefold layers with overlayfs to
> >>> be used with container tools. This use case requires a simple setup,
> >>> where every layer will have the same encoding setting (i.e. Unicode
> >>> version and flags), using one upper and one lower layer.
> >>>
> >> Amir,
> >>
> >> I tried to run your xfstest for casefolded ovl[1] but I can see that it
> >> still requires some work. I tried to fix some of the TODO's but I didn't
> >> managed to mkfs the base fs with casefold enabled...
> > When you write mkfs the base fs, I suspect that you are running
> > check -overlay or something.
> >
> > This is not how this test should be run.
> > It should run as a normal test on ext4 or any other fs  that supports casefold.
> >
> > When you run check -g casefold, the generic test generic/556 will
> > be run if the test fs supports casefold (e.g. ext4).
> >
> > The new added test belongs to the same group and should run
> > if you run check -g casefold if the test fs supports casefold (e.g. ext4).
> >
> I see, I used `check -overlay` indeed, thanks!
>

Yeh that's a bit confusing I'll admit.
It's an overlayfs test that "does not run on overlayfs"
but requires extra overlayfs:

_exclude_fs overlay
_require_extra_fs overlay

Because it does the overlayfs mount itself.
That's the easiest way to test features (e.g. casefold) in basefs

You should also run check -overlay -g overlay/quick,
but that's only to verify your patches did not regress any
non-casefolded test.


> >> but we might as
> >> well discuss this in a dedicated xfstest email thread if you want to
> >> send a RFC for the test.
> >>
> >> [1]
> >> https://github.com/amir73il/xfstests/commit/03b3facf60e14cab9fc563ad54893563b4cb18e4
> >>
> >>
> > Can you point me to a branch with your ovl patches, so I can pull it
> > for testing?
>
> You can find my branch here, based on top of vfs.all:
> https://gitlab.freedesktop.org/andrealmeid/linux/-/commits/ovl_casefold
>
> I fixed the following minor issues:
>
> - 4/9: dropped the `kfree(cf_name);` - 6/9: fixed kernel robot warning
> `unused variable 'ofs'` - 8/9: change pr_warn_ratelimited() string
>

Cool. Let me know when the test is passing (regardless of TODOs).
I'll try to test it next week.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
  2025-08-14 18:59   ` Amir Goldstein
@ 2025-08-15 16:16   ` Amir Goldstein
  2025-08-15 16:53     ` André Almeida
  2025-08-17 14:33   ` Amir Goldstein
  2 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-15 16:16 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> To add overlayfs support casefold layers, create a new function
> ovl_casefold(), to be able to do case-insensitive strncmp().
>
> ovl_casefold() allocates a new buffer and stores the casefolded version
> of the string on it. If the allocation or the casefold operation fails,
> fallback to use the original string.
>
> The case-insentive name is then used in the rb-tree search/insertion
> operation. If the name is found in the rb-tree, the name can be
> discarded and the buffer is freed. If the name isn't found, it's then
> stored at struct ovl_cache_entry to be used later.
>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> ---
> Changes from v4:
>  - Move the consumer/free buffer logic out to the caller
>  - s/aux/c_name
>
> Changes from v3:
>  - Improve commit message text
>  - s/OVL_NAME_LEN/NAME_MAX
>  - drop #ifdef in favor of if(IS_ENABLED)
>  - use new helper sb_encoding
>  - merged patch "Store casefold name..." and "Create ovl_casefold()..."
>  - Guard all the casefolding inside of IS_ENABLED(UNICODE)
>
> Changes from v2:
> - Refactor the patch to do a single kmalloc() per rb_tree operation
> - Instead of casefolding the cache entry name everytime per strncmp(),
>   casefold it once and reuse it for every strncmp().
> ---
>  fs/overlayfs/readdir.c | 115 +++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 97 insertions(+), 18 deletions(-)
>
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index b65cdfce31ce27172d28d879559f1008b9c87320..803ac6a7516d0156ae7793ee1ff884dbbf2e20b0 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -27,6 +27,8 @@ struct ovl_cache_entry {
>         bool is_upper;
>         bool is_whiteout;
>         bool check_xwhiteout;
> +       const char *cf_name;
> +       int cf_len;
>         char name[];
>  };
>
> @@ -45,6 +47,7 @@ struct ovl_readdir_data {
>         struct list_head *list;
>         struct list_head middle;
>         struct ovl_cache_entry *first_maybe_whiteout;
> +       struct unicode_map *map;
>         int count;
>         int err;
>         bool is_upper;
> @@ -66,6 +69,27 @@ static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
>         return rb_entry(n, struct ovl_cache_entry, node);
>  }
>
> +static int ovl_casefold(struct unicode_map *map, const char *str, int len, char **dst)
> +{
> +       const struct qstr qstr = { .name = str, .len = len };
> +       int cf_len;
> +
> +       if (!IS_ENABLED(CONFIG_UNICODE) || !map || is_dot_dotdot(str, len))
> +               return 0;
> +
> +       *dst = kmalloc(NAME_MAX, GFP_KERNEL);
> +
> +       if (dst) {
> +               cf_len = utf8_casefold(map, &qstr, *dst, NAME_MAX);
> +
> +               if (cf_len > 0)
> +                       return cf_len;
> +       }
> +
> +       kfree(*dst);
> +       return 0;
> +}
> +
>  static bool ovl_cache_entry_find_link(const char *name, int len,
>                                       struct rb_node ***link,
>                                       struct rb_node **parent)
> @@ -79,7 +103,7 @@ static bool ovl_cache_entry_find_link(const char *name, int len,
>
>                 *parent = *newp;
>                 tmp = ovl_cache_entry_from_node(*newp);
> -               cmp = strncmp(name, tmp->name, len);
> +               cmp = strncmp(name, tmp->cf_name, tmp->cf_len);
>                 if (cmp > 0)
>                         newp = &tmp->node.rb_right;
>                 else if (cmp < 0 || len < tmp->len)
> @@ -101,7 +125,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
>         while (node) {
>                 struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
>
> -               cmp = strncmp(name, p->name, len);
> +               cmp = strncmp(name, p->cf_name, p->cf_len);
>                 if (cmp > 0)
>                         node = p->node.rb_right;
>                 else if (cmp < 0 || len < p->len)
> @@ -145,13 +169,16 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd,
>
>  static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
>                                                    const char *name, int len,
> +                                                  const char *cf_name, int cf_len,
>                                                    u64 ino, unsigned int d_type)
>  {
>         struct ovl_cache_entry *p;
>
>         p = kmalloc(struct_size(p, name, len + 1), GFP_KERNEL);
> -       if (!p)
> +       if (!p) {
> +               kfree(cf_name);
>                 return NULL;
> +       }
>
>         memcpy(p->name, name, len);
>         p->name[len] = '\0';
> @@ -167,6 +194,14 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
>         /* Defer check for overlay.whiteout to ovl_iterate() */
>         p->check_xwhiteout = rdd->in_xwhiteouts_dir && d_type == DT_REG;
>
> +       if (cf_name && cf_name != name) {
> +               p->cf_name = cf_name;
> +               p->cf_len = cf_len;
> +       } else {
> +               p->cf_name = p->name;
> +               p->cf_len = len;
> +       }
> +
>         if (d_type == DT_CHR) {
>                 p->next_maybe_whiteout = rdd->first_maybe_whiteout;
>                 rdd->first_maybe_whiteout = p;
> @@ -174,48 +209,55 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
>         return p;
>  }
>
> -static bool ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
> -                                 const char *name, int len, u64 ino,
> +/* Return 0 for found, 1 for added, <0 for error */
> +static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
> +                                 const char *name, int len,
> +                                 const char *cf_name, int cf_len,
> +                                 u64 ino,
>                                   unsigned int d_type)
>  {
>         struct rb_node **newp = &rdd->root->rb_node;
>         struct rb_node *parent = NULL;
>         struct ovl_cache_entry *p;
>
> -       if (ovl_cache_entry_find_link(name, len, &newp, &parent))
> -               return true;
> +       if (ovl_cache_entry_find_link(cf_name, cf_len, &newp, &parent))
> +               return 0;
>
> -       p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
> +       p = ovl_cache_entry_new(rdd, name, len, cf_name, cf_len, ino, d_type);
>         if (p == NULL) {
>                 rdd->err = -ENOMEM;
> -               return false;
> +               return -ENOMEM;
>         }
>
>         list_add_tail(&p->l_node, rdd->list);
>         rb_link_node(&p->node, parent, newp);
>         rb_insert_color(&p->node, rdd->root);
>
> -       return true;
> +       return 1;
>  }
>
> -static bool ovl_fill_lowest(struct ovl_readdir_data *rdd,
> +/* Return 0 for found, 1 for added, <0 for error */
> +static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
>                            const char *name, int namelen,
> +                          const char *cf_name, int cf_len,
>                            loff_t offset, u64 ino, unsigned int d_type)
>  {
>         struct ovl_cache_entry *p;
>
> -       p = ovl_cache_entry_find(rdd->root, name, namelen);
> +       p = ovl_cache_entry_find(rdd->root, cf_name, cf_len);
>         if (p) {
>                 list_move_tail(&p->l_node, &rdd->middle);
> +               return 0;
>         } else {
> -               p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
> +               p = ovl_cache_entry_new(rdd, name, namelen, cf_name, cf_len,
> +                                       ino, d_type);
>                 if (p == NULL)
>                         rdd->err = -ENOMEM;
>                 else
>                         list_add_tail(&p->l_node, &rdd->middle);
>         }
>
> -       return rdd->err == 0;
> +       return rdd->err ?: 1;
>  }
>
>  void ovl_cache_free(struct list_head *list)
> @@ -223,8 +265,11 @@ void ovl_cache_free(struct list_head *list)
>         struct ovl_cache_entry *p;
>         struct ovl_cache_entry *n;
>
> -       list_for_each_entry_safe(p, n, list, l_node)
> +       list_for_each_entry_safe(p, n, list, l_node) {
> +               if (p->cf_name != p->name)
> +                       kfree(p->cf_name);
>                 kfree(p);
> +       }
>
>         INIT_LIST_HEAD(list);
>  }
> @@ -260,12 +305,38 @@ static bool ovl_fill_merge(struct dir_context *ctx, const char *name,
>  {
>         struct ovl_readdir_data *rdd =
>                 container_of(ctx, struct ovl_readdir_data, ctx);
> +       struct ovl_fs *ofs = OVL_FS(rdd->dentry->d_sb);
> +       char *cf_name = NULL;
> +       int c_len = 0;
> +       int ret;
> +
> +       const char *c_name = NULL;
> +

Another nit:
Pls move up next to cf_name = NULL line in your branch

No need to repost.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-15 16:16   ` Amir Goldstein
@ 2025-08-15 16:53     ` André Almeida
  0 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-15 16:53 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On 8/15/25 13:16, Amir Goldstein wrote:
> On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>> To add overlayfs support casefold layers, create a new function
>> ovl_casefold(), to be able to do case-insensitive strncmp().
>>
>> ovl_casefold() allocates a new buffer and stores the casefolded version
>> of the string on it. If the allocation or the casefold operation fails,
>> fallback to use the original string.
>>
>> The case-insentive name is then used in the rb-tree search/insertion
>> operation. If the name is found in the rb-tree, the name can be
>> discarded and the buffer is freed. If the name isn't found, it's then
>> stored at struct ovl_cache_entry to be used later.
>>
>> Signed-off-by: André Almeida <andrealmeid@igalia.com>

[...]

>> @@ -260,12 +305,38 @@ static bool ovl_fill_merge(struct dir_context *ctx, const char *name,
>>   {
>>          struct ovl_readdir_data *rdd =
>>                  container_of(ctx, struct ovl_readdir_data, ctx);
>> +       struct ovl_fs *ofs = OVL_FS(rdd->dentry->d_sb);
>> +       char *cf_name = NULL;
>> +       int c_len = 0;
>> +       int ret;
>> +
>> +       const char *c_name = NULL;
>> +
> Another nit:
> Pls move up next to cf_name = NULL line in your branch
>
> No need to repost.

Done. Also joined int ret and int c_len to the same declaration;

>
> Thanks,
> Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
  2025-08-14 18:59   ` Amir Goldstein
  2025-08-15 16:16   ` Amir Goldstein
@ 2025-08-17 14:33   ` Amir Goldstein
  2025-08-22 14:07     ` André Almeida
  2 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-17 14:33 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> To add overlayfs support casefold layers, create a new function
> ovl_casefold(), to be able to do case-insensitive strncmp().
>
> ovl_casefold() allocates a new buffer and stores the casefolded version
> of the string on it. If the allocation or the casefold operation fails,
> fallback to use the original string.
>
> The case-insentive name is then used in the rb-tree search/insertion
> operation. If the name is found in the rb-tree, the name can be
> discarded and the buffer is freed. If the name isn't found, it's then
> stored at struct ovl_cache_entry to be used later.
>
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> ---
> Changes from v4:
>  - Move the consumer/free buffer logic out to the caller
>  - s/aux/c_name
>
> Changes from v3:
>  - Improve commit message text
>  - s/OVL_NAME_LEN/NAME_MAX
>  - drop #ifdef in favor of if(IS_ENABLED)
>  - use new helper sb_encoding
>  - merged patch "Store casefold name..." and "Create ovl_casefold()..."
>  - Guard all the casefolding inside of IS_ENABLED(UNICODE)
>
> Changes from v2:
> - Refactor the patch to do a single kmalloc() per rb_tree operation
> - Instead of casefolding the cache entry name everytime per strncmp(),
>   casefold it once and reuse it for every strncmp().
> ---
>  fs/overlayfs/readdir.c | 115 +++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 97 insertions(+), 18 deletions(-)
>
> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
> index b65cdfce31ce27172d28d879559f1008b9c87320..803ac6a7516d0156ae7793ee1ff884dbbf2e20b0 100644
> --- a/fs/overlayfs/readdir.c
> +++ b/fs/overlayfs/readdir.c
> @@ -27,6 +27,8 @@ struct ovl_cache_entry {
>         bool is_upper;
>         bool is_whiteout;
>         bool check_xwhiteout;
> +       const char *cf_name;
> +       int cf_len;

We should also change these member names to c_name
Because they are the "compare/canonicalized" name, which
may or may not be casefolded.

>         char name[];
>  };
>
> @@ -45,6 +47,7 @@ struct ovl_readdir_data {
>         struct list_head *list;
>         struct list_head middle;
>         struct ovl_cache_entry *first_maybe_whiteout;
> +       struct unicode_map *map;
>         int count;
>         int err;
>         bool is_upper;
> @@ -66,6 +69,27 @@ static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
>         return rb_entry(n, struct ovl_cache_entry, node);
>  }
>
> +static int ovl_casefold(struct unicode_map *map, const char *str, int len, char **dst)
> +{
> +       const struct qstr qstr = { .name = str, .len = len };
> +       int cf_len;
> +
> +       if (!IS_ENABLED(CONFIG_UNICODE) || !map || is_dot_dotdot(str, len))
> +               return 0;
> +
> +       *dst = kmalloc(NAME_MAX, GFP_KERNEL);
> +
> +       if (dst) {
> +               cf_len = utf8_casefold(map, &qstr, *dst, NAME_MAX);
> +
> +               if (cf_len > 0)
> +                       return cf_len;
> +       }
> +
> +       kfree(*dst);
> +       return 0;
> +}
> +
>  static bool ovl_cache_entry_find_link(const char *name, int len,
>                                       struct rb_node ***link,
>                                       struct rb_node **parent)
> @@ -79,7 +103,7 @@ static bool ovl_cache_entry_find_link(const char *name, int len,
>
>                 *parent = *newp;
>                 tmp = ovl_cache_entry_from_node(*newp);
> -               cmp = strncmp(name, tmp->name, len);
> +               cmp = strncmp(name, tmp->cf_name, tmp->cf_len);
>                 if (cmp > 0)
>                         newp = &tmp->node.rb_right;
>                 else if (cmp < 0 || len < tmp->len)

This looks like a bug - should be len < tmp->c_len

> @@ -101,7 +125,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
>         while (node) {
>                 struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
>
> -               cmp = strncmp(name, p->name, len);
> +               cmp = strncmp(name, p->cf_name, p->cf_len);
>                 if (cmp > 0)
>                         node = p->node.rb_right;
>                 else if (cmp < 0 || len < p->len)

Same here.

But it's not the only bug, because this patch regresses 3 fstests without
enabling any casefolding:

overlay/038 12s ...  [14:16:39] [14:16:50]- output mismatch (see
/results/overlay/results-large/overlay/038.out.bad)
    --- tests/overlay/038.out 2025-05-25 08:52:54.000000000 +0000
    +++ /results/overlay/results-large/overlay/038.out.bad 2025-08-17
14:16:50.549367654 +0000
    @@ -1,2 +1,3 @@
     QA output created by 038
    +Merged dir: Invalid d_ino reported for ..
     Silence is golden

overlay/041 11s ...  [14:16:54] [14:17:05]- output mismatch (see
/results/overlay/results-large/overlay/041.out.bad)
    --- tests/overlay/041.out 2025-05-25 08:52:54.000000000 +0000
    +++ /results/overlay/results-large/overlay/041.out.bad 2025-08-17
14:17:05.275206922 +0000
    @@ -1,2 +1,3 @@
     QA output created by 041
    +Merged dir: Invalid d_ino reported for ..
     Silence is golden

overlay/077 19s ...  [14:17:08][  107.348626] WARNING: CPU: 3 PID:
5414 at fs/overlayfs/readdir.c:677 ovl_dir_read_impure+0x178/0x1c0
[  107.354647] ---[ end trace 0000000000000000 ]---
[  107.399525] WARNING: CPU: 2 PID: 5415 at fs/overlayfs/readdir.c:677
ovl_dir_read_impure+0x178/0x1c0
[  107.406826] ---[ end trace 0000000000000000 ]---
_check_dmesg: something found in dmesg (see
/results/overlay/results-large/overlay/077.dmesg)
 [14:17:28]- output mismatch (see
/results/overlay/results-large/overlay/077.out.bad)
    --- tests/overlay/077.out 2025-05-25 08:52:54.000000000 +0000
    +++ /results/overlay/results-large/overlay/077.out.bad 2025-08-17
14:17:28.762250671 +0000
    @@ -1,2 +1,6 @@
     QA output created by 077
    +getdents: Input/output error
    +Missing created file in impure upper dir (see
/results/overlay/results-large/overlay/077.full for details)
    +getdents: Input/output error
    +Found unlinked file in impure upper dir (see
/results/overlay/results-large/overlay/077.full for details)
     Silence is golden

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-15 13:50       ` Amir Goldstein
@ 2025-08-17 15:03         ` Amir Goldstein
  2025-08-22 14:15           ` André Almeida
  0 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-17 15:03 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

On Fri, Aug 15, 2025 at 3:50 PM Amir Goldstein <amir73il@gmail.com> wrote:
>
> On Fri, Aug 15, 2025 at 3:34 PM André Almeida <andrealmeid@igalia.com> wrote:
> >
> > Hi Amir,
> >
> > On 8/14/25 21:06, Amir Goldstein wrote:
> > > On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
> > >> Em 14/08/2025 14:22, André Almeida escreveu:
> > >>> Hi all,
> > >>>
> > >>> We would like to support the usage of casefold layers with overlayfs to
> > >>> be used with container tools. This use case requires a simple setup,
> > >>> where every layer will have the same encoding setting (i.e. Unicode
> > >>> version and flags), using one upper and one lower layer.
> > >>>
> > >> Amir,
> > >>
> > >> I tried to run your xfstest for casefolded ovl[1] but I can see that it
> > >> still requires some work. I tried to fix some of the TODO's but I didn't
> > >> managed to mkfs the base fs with casefold enabled...
> > > When you write mkfs the base fs, I suspect that you are running
> > > check -overlay or something.
> > >
> > > This is not how this test should be run.
> > > It should run as a normal test on ext4 or any other fs  that supports casefold.
> > >
> > > When you run check -g casefold, the generic test generic/556 will
> > > be run if the test fs supports casefold (e.g. ext4).
> > >
> > > The new added test belongs to the same group and should run
> > > if you run check -g casefold if the test fs supports casefold (e.g. ext4).
> > >
> > I see, I used `check -overlay` indeed, thanks!
> >
>
> Yeh that's a bit confusing I'll admit.
> It's an overlayfs test that "does not run on overlayfs"
> but requires extra overlayfs:
>
> _exclude_fs overlay
> _require_extra_fs overlay
>
> Because it does the overlayfs mount itself.
> That's the easiest way to test features (e.g. casefold) in basefs
>

I tried to run the new test, which is able to mount an overlayfs
with layers with disabled casefolding with kernel 6.17-rc1.

It does not even succeed in passing this simple test with
your patches, so something is clearly off.

> You should also run check -overlay -g overlay/quick,
> but that's only to verify your patches did not regress any
> non-casefolded test.
>
>

My tests also indicate that there are several regressions, so your patches
must have changed code paths that should not have been changed.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp()
  2025-08-17 14:33   ` Amir Goldstein
@ 2025-08-22 14:07     ` André Almeida
  0 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-22 14:07 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, Gabriel Krisman Bertazi,
	linux-unionfs, linux-kernel, linux-fsdevel, Alexander Viro,
	Christian Brauner, Jan Kara, kernel-dev

Em 17/08/2025 11:33, Amir Goldstein escreveu:
> On Thu, Aug 14, 2025 at 7:22 PM André Almeida <andrealmeid@igalia.com> wrote:
>>
>> To add overlayfs support casefold layers, create a new function
>> ovl_casefold(), to be able to do case-insensitive strncmp().
>>
>> ovl_casefold() allocates a new buffer and stores the casefolded version
>> of the string on it. If the allocation or the casefold operation fails,
>> fallback to use the original string.
>>
>> The case-insentive name is then used in the rb-tree search/insertion
>> operation. If the name is found in the rb-tree, the name can be
>> discarded and the buffer is freed. If the name isn't found, it's then
>> stored at struct ovl_cache_entry to be used later.
>>
>> Signed-off-by: André Almeida <andrealmeid@igalia.com>
>> ---
>> Changes from v4:
>>   - Move the consumer/free buffer logic out to the caller
>>   - s/aux/c_name
>>
>> Changes from v3:
>>   - Improve commit message text
>>   - s/OVL_NAME_LEN/NAME_MAX
>>   - drop #ifdef in favor of if(IS_ENABLED)
>>   - use new helper sb_encoding
>>   - merged patch "Store casefold name..." and "Create ovl_casefold()..."
>>   - Guard all the casefolding inside of IS_ENABLED(UNICODE)
>>
>> Changes from v2:
>> - Refactor the patch to do a single kmalloc() per rb_tree operation
>> - Instead of casefolding the cache entry name everytime per strncmp(),
>>    casefold it once and reuse it for every strncmp().
>> ---
>>   fs/overlayfs/readdir.c | 115 +++++++++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 97 insertions(+), 18 deletions(-)
>>
>> diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
>> index b65cdfce31ce27172d28d879559f1008b9c87320..803ac6a7516d0156ae7793ee1ff884dbbf2e20b0 100644
>> --- a/fs/overlayfs/readdir.c
>> +++ b/fs/overlayfs/readdir.c
>> @@ -27,6 +27,8 @@ struct ovl_cache_entry {
>>          bool is_upper;
>>          bool is_whiteout;
>>          bool check_xwhiteout;
>> +       const char *cf_name;
>> +       int cf_len;
> 
> We should also change these member names to c_name
> Because they are the "compare/canonicalized" name, which
> may or may not be casefolded.
> 
>>          char name[];
>>   };
>>
>> @@ -45,6 +47,7 @@ struct ovl_readdir_data {
>>          struct list_head *list;
>>          struct list_head middle;
>>          struct ovl_cache_entry *first_maybe_whiteout;
>> +       struct unicode_map *map;
>>          int count;
>>          int err;
>>          bool is_upper;
>> @@ -66,6 +69,27 @@ static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
>>          return rb_entry(n, struct ovl_cache_entry, node);
>>   }
>>
>> +static int ovl_casefold(struct unicode_map *map, const char *str, int len, char **dst)
>> +{
>> +       const struct qstr qstr = { .name = str, .len = len };
>> +       int cf_len;
>> +
>> +       if (!IS_ENABLED(CONFIG_UNICODE) || !map || is_dot_dotdot(str, len))
>> +               return 0;
>> +
>> +       *dst = kmalloc(NAME_MAX, GFP_KERNEL);
>> +
>> +       if (dst) {
>> +               cf_len = utf8_casefold(map, &qstr, *dst, NAME_MAX);
>> +
>> +               if (cf_len > 0)
>> +                       return cf_len;
>> +       }
>> +
>> +       kfree(*dst);
>> +       return 0;
>> +}
>> +
>>   static bool ovl_cache_entry_find_link(const char *name, int len,
>>                                        struct rb_node ***link,
>>                                        struct rb_node **parent)
>> @@ -79,7 +103,7 @@ static bool ovl_cache_entry_find_link(const char *name, int len,
>>
>>                  *parent = *newp;
>>                  tmp = ovl_cache_entry_from_node(*newp);
>> -               cmp = strncmp(name, tmp->name, len);
>> +               cmp = strncmp(name, tmp->cf_name, tmp->cf_len);
>>                  if (cmp > 0)
>>                          newp = &tmp->node.rb_right;
>>                  else if (cmp < 0 || len < tmp->len)
> 
> This looks like a bug - should be len < tmp->c_len
> 
>> @@ -101,7 +125,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
>>          while (node) {
>>                  struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
>>
>> -               cmp = strncmp(name, p->name, len);
>> +               cmp = strncmp(name, p->cf_name, p->cf_len);
>>                  if (cmp > 0)
>>                          node = p->node.rb_right;
>>                  else if (cmp < 0 || len < p->len)
> 
> Same here.
> 
> But it's not the only bug, because this patch regresses 3 fstests without
> enabling any casefolding:
> 

That was due to the following change:

-               cmp = strncmp(name, p->name, len);
+               cmp = strncmp(name, p->cf_name, p->cf_len);

Keeping len (instead of p->cf_len) as the third argument fixed it. I 
will send a v6 with that and the other changes.

> overlay/038 12s ...  [14:16:39] [14:16:50]- output mismatch (see
> /results/overlay/results-large/overlay/038.out.bad)
>      --- tests/overlay/038.out 2025-05-25 08:52:54.000000000 +0000
>      +++ /results/overlay/results-large/overlay/038.out.bad 2025-08-17
> 14:16:50.549367654 +0000
>      @@ -1,2 +1,3 @@
>       QA output created by 038
>      +Merged dir: Invalid d_ino reported for ..
>       Silence is golden
> 
> overlay/041 11s ...  [14:16:54] [14:17:05]- output mismatch (see
> /results/overlay/results-large/overlay/041.out.bad)
>      --- tests/overlay/041.out 2025-05-25 08:52:54.000000000 +0000
>      +++ /results/overlay/results-large/overlay/041.out.bad 2025-08-17
> 14:17:05.275206922 +0000
>      @@ -1,2 +1,3 @@
>       QA output created by 041
>      +Merged dir: Invalid d_ino reported for ..
>       Silence is golden
> 
> overlay/077 19s ...  [14:17:08][  107.348626] WARNING: CPU: 3 PID:
> 5414 at fs/overlayfs/readdir.c:677 ovl_dir_read_impure+0x178/0x1c0
> [  107.354647] ---[ end trace 0000000000000000 ]---
> [  107.399525] WARNING: CPU: 2 PID: 5415 at fs/overlayfs/readdir.c:677
> ovl_dir_read_impure+0x178/0x1c0
> [  107.406826] ---[ end trace 0000000000000000 ]---
> _check_dmesg: something found in dmesg (see
> /results/overlay/results-large/overlay/077.dmesg)
>   [14:17:28]- output mismatch (see
> /results/overlay/results-large/overlay/077.out.bad)
>      --- tests/overlay/077.out 2025-05-25 08:52:54.000000000 +0000
>      +++ /results/overlay/results-large/overlay/077.out.bad 2025-08-17
> 14:17:28.762250671 +0000
>      @@ -1,2 +1,6 @@
>       QA output created by 077
>      +getdents: Input/output error
>      +Missing created file in impure upper dir (see
> /results/overlay/results-large/overlay/077.full for details)
>      +getdents: Input/output error
>      +Found unlinked file in impure upper dir (see
> /results/overlay/results-large/overlay/077.full for details)
>       Silence is golden
> 
> Thanks,
> Amir.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-17 15:03         ` Amir Goldstein
@ 2025-08-22 14:15           ` André Almeida
  2025-08-22 17:21             ` Amir Goldstein
  0 siblings, 1 reply; 27+ messages in thread
From: André Almeida @ 2025-08-22 14:15 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

Em 17/08/2025 12:03, Amir Goldstein escreveu:
> On Fri, Aug 15, 2025 at 3:50 PM Amir Goldstein <amir73il@gmail.com> wrote:
>>
>> On Fri, Aug 15, 2025 at 3:34 PM André Almeida <andrealmeid@igalia.com> wrote:
>>>
>>> Hi Amir,
>>>
>>> On 8/14/25 21:06, Amir Goldstein wrote:
>>>> On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
>>>>> Em 14/08/2025 14:22, André Almeida escreveu:
>>>>>> Hi all,
>>>>>>
>>>>>> We would like to support the usage of casefold layers with overlayfs to
>>>>>> be used with container tools. This use case requires a simple setup,
>>>>>> where every layer will have the same encoding setting (i.e. Unicode
>>>>>> version and flags), using one upper and one lower layer.
>>>>>>
>>>>> Amir,
>>>>>
>>>>> I tried to run your xfstest for casefolded ovl[1] but I can see that it
>>>>> still requires some work. I tried to fix some of the TODO's but I didn't
>>>>> managed to mkfs the base fs with casefold enabled...
>>>> When you write mkfs the base fs, I suspect that you are running
>>>> check -overlay or something.
>>>>
>>>> This is not how this test should be run.
>>>> It should run as a normal test on ext4 or any other fs  that supports casefold.
>>>>
>>>> When you run check -g casefold, the generic test generic/556 will
>>>> be run if the test fs supports casefold (e.g. ext4).
>>>>
>>>> The new added test belongs to the same group and should run
>>>> if you run check -g casefold if the test fs supports casefold (e.g. ext4).
>>>>
>>> I see, I used `check -overlay` indeed, thanks!
>>>
>>
>> Yeh that's a bit confusing I'll admit.
>> It's an overlayfs test that "does not run on overlayfs"
>> but requires extra overlayfs:
>>
>> _exclude_fs overlay
>> _require_extra_fs overlay
>>
>> Because it does the overlayfs mount itself.
>> That's the easiest way to test features (e.g. casefold) in basefs
>>
> 
> I tried to run the new test, which is able to mount an overlayfs
> with layers with disabled casefolding with kernel 6.17-rc1.
> 
> It does not even succeed in passing this simple test with
> your patches, so something is clearly off.

Apart from the other changes I had done for v6, I also had to change the 
test itself. The directories need to be empty to set the +F attribute, 
so I had to do this change:

--- a/tests/generic/999
+++ b/tests/generic/999
@@ -104,6 +104,9 @@ mount_overlay $lowerdir >>$seqres.full
  ls $merge/casefold/subdir |& _filter_scratch
  unmount_overlay

+# workdir needs to be empty to set casefold attribute
+rm -rf $workdir/*
+
  _casefold_set_attr $upperdir >>$seqres.full
  _casefold_set_attr $workdir >>$seqres.full

@@ -112,7 +115,10 @@ mount_overlay $lowerdir >>$seqres.full 2>&1 && \
         echo "Overlayfs mount with casefold enabled upperdir should 
have failed" && \
         unmount_overlay

+# lowerdir needs to be empty to set casefold attribute
+rm -rf $lowerdir/*
  _casefold_set_attr $lowerdir >>$seqres.full
+mkdir $casefolddir

  # Try to mount an overlay with casefold enabled layers.
  # On kernels older than v6.18 expect failure and skip the rest of the test

> 
>> You should also run check -overlay -g overlay/quick,
>> but that's only to verify your patches did not regress any
>> non-casefolded test.
>>
>>
> 
> My tests also indicate that there are several regressions, so your patches
> must have changed code paths that should not have been changed.
> 
> Thanks,
> Amir.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-22 14:15           ` André Almeida
@ 2025-08-22 17:21             ` Amir Goldstein
  2025-08-22 17:39               ` André Almeida
  0 siblings, 1 reply; 27+ messages in thread
From: Amir Goldstein @ 2025-08-22 17:21 UTC (permalink / raw)
  To: André Almeida
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

On Fri, Aug 22, 2025 at 4:16 PM André Almeida <andrealmeid@igalia.com> wrote:
>
> Em 17/08/2025 12:03, Amir Goldstein escreveu:
> > On Fri, Aug 15, 2025 at 3:50 PM Amir Goldstein <amir73il@gmail.com> wrote:
> >>
> >> On Fri, Aug 15, 2025 at 3:34 PM André Almeida <andrealmeid@igalia.com> wrote:
> >>>
> >>> Hi Amir,
> >>>
> >>> On 8/14/25 21:06, Amir Goldstein wrote:
> >>>> On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
> >>>>> Em 14/08/2025 14:22, André Almeida escreveu:
> >>>>>> Hi all,
> >>>>>>
> >>>>>> We would like to support the usage of casefold layers with overlayfs to
> >>>>>> be used with container tools. This use case requires a simple setup,
> >>>>>> where every layer will have the same encoding setting (i.e. Unicode
> >>>>>> version and flags), using one upper and one lower layer.
> >>>>>>
> >>>>> Amir,
> >>>>>
> >>>>> I tried to run your xfstest for casefolded ovl[1] but I can see that it
> >>>>> still requires some work. I tried to fix some of the TODO's but I didn't
> >>>>> managed to mkfs the base fs with casefold enabled...
> >>>> When you write mkfs the base fs, I suspect that you are running
> >>>> check -overlay or something.
> >>>>
> >>>> This is not how this test should be run.
> >>>> It should run as a normal test on ext4 or any other fs  that supports casefold.
> >>>>
> >>>> When you run check -g casefold, the generic test generic/556 will
> >>>> be run if the test fs supports casefold (e.g. ext4).
> >>>>
> >>>> The new added test belongs to the same group and should run
> >>>> if you run check -g casefold if the test fs supports casefold (e.g. ext4).
> >>>>
> >>> I see, I used `check -overlay` indeed, thanks!
> >>>
> >>
> >> Yeh that's a bit confusing I'll admit.
> >> It's an overlayfs test that "does not run on overlayfs"
> >> but requires extra overlayfs:
> >>
> >> _exclude_fs overlay
> >> _require_extra_fs overlay
> >>
> >> Because it does the overlayfs mount itself.
> >> That's the easiest way to test features (e.g. casefold) in basefs
> >>
> >
> > I tried to run the new test, which is able to mount an overlayfs
> > with layers with disabled casefolding with kernel 6.17-rc1.
> >
> > It does not even succeed in passing this simple test with
> > your patches, so something is clearly off.
>
> Apart from the other changes I had done for v6, I also had to change the
> test itself. The directories need to be empty to set the +F attribute,
> so I had to do this change:

Nice, so I suppose this test is passing with v6. I will try it.
Can you help to complete the TODO:

# TODO: test non-casefold subdir and casefold disabled after mount
The test now ends with the ofs->casefold == true mount,
but we need to test the error conditions same as the test cases
for ofs->casefold == false:

1. Casefold disabled after mount
2. Casefold disabled lower subdir

Those test cases are designed to trigger the "wrong parent casefold"
and "wrong child casefold" lookup warnings.

If you have an idea how to trigger the "wrong inherited casefold"
warning that would be nice.

Technically, test can delete the whiteout file inside $workdir/work
and remove casefold from $workdir/work and then trigger a copy up.
It may work. I am not sure if deleting the whietout file from work dir
is going to break something though.

Thanks,
Amir.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v5 0/9] ovl: Enable support for casefold layers
  2025-08-22 17:21             ` Amir Goldstein
@ 2025-08-22 17:39               ` André Almeida
  0 siblings, 0 replies; 27+ messages in thread
From: André Almeida @ 2025-08-22 17:39 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Miklos Szeredi, Theodore Tso, linux-unionfs, linux-kernel,
	linux-fsdevel, Alexander Viro, Christian Brauner, Jan Kara,
	kernel-dev, Gabriel Krisman Bertazi

Em 22/08/2025 14:21, Amir Goldstein escreveu:
> On Fri, Aug 22, 2025 at 4:16 PM André Almeida <andrealmeid@igalia.com> wrote:
>>
>> Em 17/08/2025 12:03, Amir Goldstein escreveu:
>>> On Fri, Aug 15, 2025 at 3:50 PM Amir Goldstein <amir73il@gmail.com> wrote:
>>>>
>>>> On Fri, Aug 15, 2025 at 3:34 PM André Almeida <andrealmeid@igalia.com> wrote:
>>>>>
>>>>> Hi Amir,
>>>>>
>>>>> On 8/14/25 21:06, Amir Goldstein wrote:
>>>>>> On Thu, Aug 14, 2025 at 7:30 PM André Almeida <andrealmeid@igalia.com> wrote:
>>>>>>> Em 14/08/2025 14:22, André Almeida escreveu:
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> We would like to support the usage of casefold layers with overlayfs to
>>>>>>>> be used with container tools. This use case requires a simple setup,
>>>>>>>> where every layer will have the same encoding setting (i.e. Unicode
>>>>>>>> version and flags), using one upper and one lower layer.
>>>>>>>>
>>>>>>> Amir,
>>>>>>>
>>>>>>> I tried to run your xfstest for casefolded ovl[1] but I can see that it
>>>>>>> still requires some work. I tried to fix some of the TODO's but I didn't
>>>>>>> managed to mkfs the base fs with casefold enabled...
>>>>>> When you write mkfs the base fs, I suspect that you are running
>>>>>> check -overlay or something.
>>>>>>
>>>>>> This is not how this test should be run.
>>>>>> It should run as a normal test on ext4 or any other fs  that supports casefold.
>>>>>>
>>>>>> When you run check -g casefold, the generic test generic/556 will
>>>>>> be run if the test fs supports casefold (e.g. ext4).
>>>>>>
>>>>>> The new added test belongs to the same group and should run
>>>>>> if you run check -g casefold if the test fs supports casefold (e.g. ext4).
>>>>>>
>>>>> I see, I used `check -overlay` indeed, thanks!
>>>>>
>>>>
>>>> Yeh that's a bit confusing I'll admit.
>>>> It's an overlayfs test that "does not run on overlayfs"
>>>> but requires extra overlayfs:
>>>>
>>>> _exclude_fs overlay
>>>> _require_extra_fs overlay
>>>>
>>>> Because it does the overlayfs mount itself.
>>>> That's the easiest way to test features (e.g. casefold) in basefs
>>>>
>>>
>>> I tried to run the new test, which is able to mount an overlayfs
>>> with layers with disabled casefolding with kernel 6.17-rc1.
>>>
>>> It does not even succeed in passing this simple test with
>>> your patches, so something is clearly off.
>>
>> Apart from the other changes I had done for v6, I also had to change the
>> test itself. The directories need to be empty to set the +F attribute,
>> so I had to do this change:
> 
> Nice, so I suppose this test is passing with v6. I will try it.
> Can you help to complete the TODO:
> 

Yes, I will handle that next week.

Thanks!

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2025-08-22 17:39 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-14 17:22 [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
2025-08-14 17:22 ` [PATCH v5 1/9] fs: Create sb_encoding() helper André Almeida
2025-08-14 17:22 ` [PATCH v5 2/9] fs: Create sb_same_encoding() helper André Almeida
2025-08-14 17:22 ` [PATCH v5 3/9] ovl: Prepare for mounting case-insensitive enabled layers André Almeida
2025-08-14 18:47   ` Amir Goldstein
2025-08-14 17:22 ` [PATCH v5 4/9] ovl: Create ovl_casefold() to support casefolded strncmp() André Almeida
2025-08-14 18:59   ` Amir Goldstein
2025-08-15 16:16   ` Amir Goldstein
2025-08-15 16:53     ` André Almeida
2025-08-17 14:33   ` Amir Goldstein
2025-08-22 14:07     ` André Almeida
2025-08-14 17:22 ` [PATCH v5 5/9] ovl: Ensure that all layers have the same encoding André Almeida
2025-08-14 17:22 ` [PATCH v5 6/9] ovl: Set case-insensitive dentry operations for ovl sb André Almeida
2025-08-15 11:52   ` kernel test robot
2025-08-14 17:22 ` [PATCH v5 7/9] ovl: Add S_CASEFOLD as part of the inode flag to be copied André Almeida
2025-08-14 17:22 ` [PATCH v5 8/9] ovl: Check for casefold consistency when creating new dentries André Almeida
2025-08-14 18:54   ` Amir Goldstein
2025-08-14 17:22 ` [PATCH v5 9/9] ovl: Support mounting case-insensitive enabled layers André Almeida
2025-08-14 18:48   ` Amir Goldstein
2025-08-14 17:30 ` [PATCH v5 0/9] ovl: Enable support for casefold layers André Almeida
2025-08-14 19:06   ` Amir Goldstein
2025-08-15 13:33     ` André Almeida
2025-08-15 13:50       ` Amir Goldstein
2025-08-17 15:03         ` Amir Goldstein
2025-08-22 14:15           ` André Almeida
2025-08-22 17:21             ` Amir Goldstein
2025-08-22 17:39               ` André Almeida

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).