From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB2A921D00D; Fri, 8 Aug 2025 20:59:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686762; cv=none; b=BZUbWNN+RAd86xjpoxszzS9ISGYPrQV6VIGANdt5JeA4y8EfPfOd1x3FDOsaeF21joc+zkoHiVO+A0HBLhmdXE0+XpDON1jzcOH1S6Jk/ACR3aixWsJMcJYu6lHQKX6gFxq385MUsdMzuW9sRUp4CU0koortqDSIPdwgwwJBaec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686762; c=relaxed/simple; bh=lts1u80SMMqa4/xe940q6JwSTiF+tO19ClFEbfS7cyo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j7b7/YmFYUCJAgONUVzpK6aSs4TKNzrYZ5jmjBDBAx9BGrmlqLZmNoUENCrRcwLqql8c1691LI2QFqqKwngwEl5PzPT4tlfYCAXq6fqsQjxEEOySsSduCsoBx3FB/n88PvIFt4wKmwIosM+MqjQWQwd1EtUInBGe853C6N28HIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=JoeyDXpD; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="JoeyDXpD" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=I3x2BitoREkICs8gzrBGPPrHzXqLRXwM+o5AKkH5M1I=; b=JoeyDXpDULr2w9e0KvI9CJkMwn T881InFYWW9bLjWhlXEXjL4ot7JrvOrjCyry50+fA4WPbbXo2hE3xKqtGmjjzj/s5VGDr8RWw4+cR t0bLpRlLQ4XrBxYwLE0Vc5eBjN2iQD/5jY9iYJkbAeL/bY65wgWn4owCAclIztdXWbuOL7567Ls4z LfSqNdsjqfhfVg15dZn6uW9/vv5BAf5whofIyq0e4gJ6LaYThJgPLtcAHMs2YKULi/Wz5ZyuN25hc nCoxNkbx3Ig4PcaVYWc5Edv2cBM+iTbnOPQcr35MSnyNjUCYVfKKLiF7NyMnlOLK+IRdxEWmiR++h XIwlsJMQ==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBG-00BiQh-Mx; Fri, 08 Aug 2025 22:59:14 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:43 -0300 Subject: [PATCH RFC v3 1/7] ovl: Store casefold name for case-insentive dentries Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-1-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 In order to make case-insentive mounting points work, overlayfs needs the casefolded version of its dentries so the search and insertion in the struct ovl_readdir_data's red-black compares the dentry names in a case-insentive fashion. If a dentry is casefolded, compute and store it's casefolded name and it's Unicode map. If utf8_casefold() fails, set it's name pointer as NULL so it can be ignored and fallback to the original name. Signed-off-by: Andr=C3=A9 Almeida --- Changes from v3: - Guard all the casefolding inside of IS_ENABLED(UNICODE) --- fs/overlayfs/readdir.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index b65cdfce31ce27172d28d879559f1008b9c87320..2f42fec97f76c2000f76e15c609= 75db567b2c6d6 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -16,6 +16,8 @@ #include #include "overlayfs.h" =20 +#define OVL_NAME_LEN 255 + struct ovl_cache_entry { unsigned int len; unsigned int type; @@ -27,6 +29,8 @@ struct ovl_cache_entry { bool is_upper; bool is_whiteout; bool check_xwhiteout; + char *cf_name; + int cf_len; char name[]; }; =20 @@ -45,6 +49,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; @@ -166,6 +171,31 @@ static struct ovl_cache_entry *ovl_cache_entry_new(str= uct ovl_readdir_data *rdd, p->is_whiteout =3D false; /* Defer check for overlay.whiteout to ovl_iterate() */ p->check_xwhiteout =3D rdd->in_xwhiteouts_dir && d_type =3D=3D DT_REG; + p->cf_name =3D NULL; + p->cf_len =3D 0; + +#if IS_ENABLED(CONFIG_UNICODE) + if (rdd->map && !is_dot_dotdot(name, len)) { + const struct qstr str =3D { .name =3D name, .len =3D len }; + int ret; + + p->cf_name =3D kmalloc(OVL_NAME_LEN, GFP_KERNEL); + + if (!p->cf_name) { + kfree(p); + return NULL; + } + + ret =3D utf8_casefold(rdd->map, &str, p->cf_name, OVL_NAME_LEN); + + if (ret < 0) { + kfree(p->cf_name); + p->cf_name =3D NULL; + } else { + p->cf_len =3D ret; + } + } +#endif =20 if (d_type =3D=3D DT_CHR) { p->next_maybe_whiteout =3D rdd->first_maybe_whiteout; @@ -223,8 +253,10 @@ void ovl_cache_free(struct list_head *list) struct ovl_cache_entry *p; struct ovl_cache_entry *n; =20 - list_for_each_entry_safe(p, n, list, l_node) + list_for_each_entry_safe(p, n, list, l_node) { + kfree(p->cf_name); kfree(p); + } =20 INIT_LIST_HEAD(list); } @@ -357,12 +389,19 @@ static int ovl_dir_read_merged(struct dentry *dentry,= struct list_head *list, .list =3D list, .root =3D root, .is_lowest =3D false, + .map =3D NULL, }; int idx, next; const struct ovl_layer *layer; =20 for (idx =3D 0; idx !=3D -1; idx =3D next) { next =3D ovl_path_next(idx, dentry, &realpath, &layer); + +#if IS_ENABLED(CONFIG_UNICODE) + if (ovl_dentry_casefolded(realpath.dentry)) + rdd.map =3D realpath.dentry->d_sb->s_encoding; +#endif + rdd.is_upper =3D ovl_dentry_upper(dentry) =3D=3D realpath.dentry; rdd.in_xwhiteouts_dir =3D layer->has_xwhiteouts && ovl_dentry_has_xwhiteouts(dentry); --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D25E524679F; Fri, 8 Aug 2025 20:59:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686764; cv=none; b=CvCv7Pofo71Kv2x156roGODUXOTsBoUjwQDsawlaSzDm/stLKkQl1gPRkaLv0BTNis8fFI0hpblcB3XuSsU2dSWhfr3aXubZYiHpA1yVsm95B5uSuuLa8ek/mlzo5BmN32fd9+Or9kZ7CVAE/DB1c4SZQdvVi7OEcERAWniJzsg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686764; c=relaxed/simple; bh=u3dVlKVgCIToDkks6TwPSnBHVCtdx+U9LZIfDBQnw/Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n2cnsr/7q5IBCAoXy1xnd4ZXkTg4Ix3ANR4Z9BFgnokWCfg7tsUFVeYe2K+XYi/gTkGFEODZGGJlcCIYpkpcoLf1cg3p1IONJeNzeZ/8j7I7n1DlpTJUj9RCjTkp15juayGAyzFA5Ywm1uAUQ2hEX8R0PfrT3BS2Q3wXCw9ue+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=X9UeX77y; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="X9UeX77y" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Lg9awdomZOsISya3sAyiL8R37JeVM+GS4Ptv56M4avs=; b=X9UeX77yU+KxevR+nY/dqEKZ+g a09nvP6FyVFLz/OvOiz4ZcWbmBS4tcOje8GMn3kLcq+D68laQiHXdeQFymHNSRxvmqsoz/uBdapxF dcDZdBcJBpM5PDOmW7jIj6d1W0y4XU5gjv7APnT/zkB+jajLkZOaOOwVmZDlCdUlmV7u6E5k6Hxkq JzLThdbCCAuJ3RCfDHMlEP8Bnwou1ef+yckTxMU00U+wdF44yqonkJmA6Kse1NDnuLG4FOPO7SXUr WeIabbD13HArdwug2PJc7MFjVQGBNiTUBF1zzygO03EBOkt97v0egyTDelmVQtz2Gcf+8X8BOHyPF NbEypaqA==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBJ-00BiQh-H8; Fri, 08 Aug 2025 22:59:17 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:44 -0300 Subject: [PATCH RFC v3 2/7] ovl: Create ovl_casefold() to support casefolded strncmp() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-2-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 To add overlayfs support casefold filesystems, 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 caller of the function is responsible of freeing the buffer. The other string to be compared is casefolded in a previous step and stored at `struct ovl_cache_entry` member `char *cf_name`. Finally, set the strncmp() parameters to the casefold versions of the names to achieve case-insensitive support. For the non-casefold names, nothing changes and the rb_tree search/insert functions just ignores this change. Signed-off-by: Andr=C3=A9 Almeida --- 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 | 92 +++++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 2f42fec97f76c2000f76e15c60975db567b2c6d6..422f991393dfae12bcacf326414= b7ee19e486ac8 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -71,20 +71,58 @@ static struct ovl_cache_entry *ovl_cache_entry_from_nod= e(struct rb_node *n) return rb_entry(n, struct ovl_cache_entry, node); } =20 +static int ovl_casefold(struct unicode_map *map, const char *str, int len,= char **dst) +{ +#if IS_ENABLED(CONFIG_UNICODE) + const struct qstr qstr =3D { .name =3D str, .len =3D len }; + int cf_len; + + if (!map || is_dot_dotdot(str, len)) + return -1; + + *dst =3D kmalloc(OVL_NAME_LEN, GFP_KERNEL); + + if (dst) { + cf_len =3D utf8_casefold(map, &qstr, *dst, OVL_NAME_LEN); + + if (cf_len > 0) + return cf_len; + } +#endif + + return -1; +} + static bool ovl_cache_entry_find_link(const char *name, int len, struct rb_node ***link, - struct rb_node **parent) + struct rb_node **parent, + struct unicode_map *map) { + int ret; + char *dst =3D NULL; bool found =3D false; + const char *str =3D name; struct rb_node **newp =3D *link; =20 + ret =3D ovl_casefold(map, name, len, &dst); + + if (ret > 0) { + str =3D dst; + len =3D ret; + } + while (!found && *newp) { int cmp; + char *aux; struct ovl_cache_entry *tmp; =20 *parent =3D *newp; + tmp =3D ovl_cache_entry_from_node(*newp); - cmp =3D strncmp(name, tmp->name, len); + + aux =3D tmp->cf_name ? tmp->cf_name : tmp->name; + + cmp =3D strncmp(str, aux, len); if (cmp > 0) newp =3D &tmp->node.rb_right; else if (cmp < 0 || len < tmp->len) @@ -94,27 +132,50 @@ static bool ovl_cache_entry_find_link(const char *name= , int len, } *link =3D newp; =20 + kfree(dst); + return found; } =20 static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root, - const char *name, int len) + const char *name, int len, + struct unicode_map *map) { struct rb_node *node =3D root->rb_node; - int cmp; + struct ovl_cache_entry *p; + const char *str =3D name; + bool found =3D false; + char *dst =3D NULL; + int cmp, ret; + + ret =3D ovl_casefold(map, name, len, &dst); + + if (ret > 0) { + str =3D dst; + len =3D ret; + } + + while (!found && node) { + char *aux; =20 - while (node) { - struct ovl_cache_entry *p =3D ovl_cache_entry_from_node(node); + p =3D ovl_cache_entry_from_node(node); =20 - cmp =3D strncmp(name, p->name, len); + aux =3D p->cf_name ? p->cf_name : p->name; + + cmp =3D strncmp(str, aux, len); if (cmp > 0) node =3D p->node.rb_right; else if (cmp < 0 || len < p->len) node =3D p->node.rb_left; else - return p; + found =3D true; } =20 + kfree(dst); + + if (found) + return p; + return NULL; } =20 @@ -212,7 +273,7 @@ static bool ovl_cache_entry_add_rb(struct ovl_readdir_d= ata *rdd, struct rb_node *parent =3D NULL; struct ovl_cache_entry *p; =20 - if (ovl_cache_entry_find_link(name, len, &newp, &parent)) + if (ovl_cache_entry_find_link(name, len, &newp, &parent, rdd->map)) return true; =20 p =3D ovl_cache_entry_new(rdd, name, len, ino, d_type); @@ -234,7 +295,7 @@ static bool ovl_fill_lowest(struct ovl_readdir_data *rd= d, { struct ovl_cache_entry *p; =20 - p =3D ovl_cache_entry_find(rdd->root, name, namelen); + p =3D ovl_cache_entry_find(rdd->root, name, namelen, rdd->map); if (p) { list_move_tail(&p->l_node, &rdd->middle); } else { @@ -640,7 +701,8 @@ static int ovl_dir_read_impure(const struct path *path,= struct list_head *list, struct rb_node *parent =3D NULL; =20 if (WARN_ON(ovl_cache_entry_find_link(p->name, p->len, - &newp, &parent))) + &newp, &parent, + rdd.map))) return -EIO; =20 rb_link_node(&p->node, parent, newp); @@ -701,6 +763,7 @@ struct ovl_readdir_translate { struct dir_context *orig_ctx; struct ovl_dir_cache *cache; struct dir_context ctx; + struct unicode_map *map; u64 parent_ino; int fsid; int xinobits; @@ -721,7 +784,7 @@ static bool ovl_fill_real(struct dir_context *ctx, cons= t char *name, } else if (rdt->cache) { struct ovl_cache_entry *p; =20 - p =3D ovl_cache_entry_find(&rdt->cache->root, name, namelen); + p =3D ovl_cache_entry_find(&rdt->cache->root, name, namelen, rdt->map); if (p) ino =3D p->ino; } else if (rdt->xinobits) { @@ -763,11 +826,16 @@ static int ovl_iterate_real(struct file *file, struct= dir_context *ctx) .orig_ctx =3D ctx, .xinobits =3D ovl_xino_bits(ofs), .xinowarn =3D ovl_xino_warn(ofs), + .map =3D NULL, }; =20 if (rdt.xinobits && lower_layer) rdt.fsid =3D lower_layer->fsid; =20 +#if IS_ENABLED(CONFIG_UNICODE) + rdt.map =3D dir->d_sb->s_encoding; +#endif + if (OVL_TYPE_MERGE(ovl_path_type(dir->d_parent))) { struct kstat stat; struct path statpath =3D file->f_path; --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77E5F25524C; Fri, 8 Aug 2025 20:59:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686767; cv=none; b=JOjHHHzDu2QBJ+6+JAIRiECfPXMUg1mpMbN1hZjtPpFqzyxSfz+NE5xgEYZq0zqxRKFJGLHRUAkFPN4TDW5UdhUubqJPvh8SblTpGIML7aH6mNkmmEfS2OEEyeCM+BoML8AiPJAaZJGbclGxl2q3PrW6ZqbQZM8jxnSuxJMp50U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686767; c=relaxed/simple; bh=djAE3+KTca4H0eGN3gMcAVWEOhSzFrqAZXDBcHDsMas=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j3q8ptuyDhuUxcJvQ7mp+0zxFUvBlT+DmzDcD7KbdyFTdy2dbvxp/4LgQmMMYVkQB1UEAa2WVdRc8Xxeimv8fBJygP3z1Uhrdej1g0EhfEz+ERVT5ehKC1tu06sO7nwY6sSi+bIKIXoYwj1i9TfQc4eQSX9DKhUOa6SzGYWkKQo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=T3FmJROP; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="T3FmJROP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=llr4kRx4/thM8+LDGQQkN5Et657lWBPXda6h0VtAk0s=; b=T3FmJROPEPMn9k5CrK+rgT6I1S VltSXpa1gx9wgjKsv0ArizWzl7KZRmZMSe6s1CHSWkEMaSap9P8zkFzMTeC1bKBc35tkTqdwMwRrm V2VYJ9Q8z8icALu85Wbr/GSsdQ1mP6NOulla7T7i5xQufGHqqVhXB2dspuDMzxe9TahC53+DQv2n/ 7fW8NW90S09nweLjuisZlPMZO5ZptXC6cmFrBafKCc6QHqOwAjXhwsEu7W1QUkntM2ePO77M39KDK Hkfw/t8uC2jtZc+pQDZ56b5tuSlxNtQaqXj64vhi2dUpgx622h5jFYuUsTB96sUxvhNEgVViAXVkR UXNb9TkQ==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBM-00BiQh-BE; Fri, 08 Aug 2025 22:59:20 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:45 -0300 Subject: [PATCH RFC v3 3/7] fs: Create sb_same_encoding() helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-3-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 For cases where a file lookup can go to different mount points (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=C3=A9 Almeida Reviewed-by: Amir Goldstein --- Changes from v2: - Simplify the code. Instead of `if (cond) return true`, just do `return cond`; --- include/linux/fs.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index db49a17376d124785b87dd7f35672fc6e5434f47..d1fe69f233c046a960a60072d5a= c3f6286d32c17 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3746,6 +3746,25 @@ static inline bool sb_has_encoding(const struct supe= r_block *sb) #endif } =20 +/* + * 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 =3D=3D sb2->s_encoding) + return true; + + return (sb1->s_encoding && sb2->s_encoding && + (sb1->s_encoding->version =3D=3D sb2->s_encoding->version) && + (sb1->s_encoding_flags =3D=3D 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 *); --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E6F125C6F3; Fri, 8 Aug 2025 20:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686770; cv=none; b=SfTo58CaVDp+ANz4mIHBjSPZZEPNQTdlWVgro5GG96U3xa66JDy1K+cwOSCv9wCwCyFvYpL8QeFdZ8mKClLxCv0eTCIZawKuCBdV3VCwoBZEUN+QxDqkoG0EZ6CUrHSXOoFGxDmTNk85e6bFYBMp4lx37EQxG8Cbb51qK6dyw3Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686770; c=relaxed/simple; bh=q1lbE9HSCF1yjwRx8M5o+xiG7oe2jBvw8fhVmn5mcYY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZNTi2/WffW1Ay8mH7AHs+p1I69+EvmE9auZ5Dl1Gu09TGqOFZ9+jkxx8ZsJvbJDjyJb+1tmLmdtow3tLoj48bik6fjtSnlfxuN6f5lc7782mh47pBfcV8tvq9gOfZO8qqqPPDF3vWdLaC8w2Osfp9cIYzwCzGJUEqMzv3swIsMY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=aVvmi+wL; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="aVvmi+wL" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=zSQ8Tf8QHrXG591Xmuim+Lx3lqmCvhyjmipeObN9FzE=; b=aVvmi+wL00KjkyRw6GPTcULgiI UF5ODTwrhIERfLW/kCA/5Cc1uCBatPnK5a2nQM42J4nRKU2sv/p6JZIIYtabU9i3g4BXpqJajtFFm 1teu2OTZ/VM2exwbQVxEs12iurCcn4Ez0C+VYQ8W8ywUX78fKPgzk2LdZoLXN+bQsLGejqC1mj/Z6 r23k7UhI35t8Oh3EZIn4aut/nCXxT3Mb1mGW3JATp0b60OGfohtWj0jI4nsczA1kS4NCdnOjaPFP9 0RccrWHoQ2NKd7S32s6SRLl0Z3wcwx9QK3j3Joy4bWz3/lkxafj+kPGAtVukA+QYLNoL5XxPABMLc 4Nu/OWVQ==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBP-00BiQh-5G; Fri, 08 Aug 2025 22:59:23 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:46 -0300 Subject: [PATCH RFC v3 4/7] ovl: Ensure that all mount points have the same encoding Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-4-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 When mounting different mount points with casefold support, they should use the same encoding version and have the same flags to avoid any kind of incompatibility issues. Signed-off-by: Andr=C3=A9 Almeida --- fs/overlayfs/super.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index df85a76597e910d00323018f1d2cd720c5db921d..bcb7f5dbf9a32e4aa09bc41596b= e443851e21200 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -998,6 +998,7 @@ static int ovl_get_layers(struct super_block *sb, struc= t ovl_fs *ofs, int err; unsigned int i; size_t nr_merged_lower; + struct super_block *sb1 =3D NULL; =20 ofs->fs =3D kcalloc(ctx->nr + 2, sizeof(struct ovl_sb), GFP_KERNEL); if (ofs->fs =3D=3D NULL) @@ -1024,6 +1025,8 @@ static int ovl_get_layers(struct super_block *sb, str= uct ovl_fs *ofs, if (ovl_upper_mnt(ofs)) { ofs->fs[0].sb =3D ovl_upper_mnt(ofs)->mnt_sb; ofs->fs[0].is_lower =3D false; + + sb1 =3D ofs->fs[0].sb; } =20 nr_merged_lower =3D ctx->nr - ctx->nr_data; @@ -1067,6 +1070,9 @@ static int ovl_get_layers(struct super_block *sb, str= uct ovl_fs *ofs, return err; } =20 + if (!sb1) + sb1 =3D mnt->mnt_sb; + /* * Make lower layers R/O. That way fchmod/fchown on lower file * will fail instead of modifying lower fs. @@ -1083,6 +1089,11 @@ static int ovl_get_layers(struct super_block *sb, st= ruct ovl_fs *ofs, l->name =3D NULL; ofs->numlayer++; ofs->fs[fsid].is_lower =3D true; + + if (!sb_same_encoding(sb1, mnt->mnt_sb)) { + pr_err("all layers must have the same encoding\n"); + return -EINVAL; + } } =20 /* --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF64C26158B; Fri, 8 Aug 2025 20:59:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686772; cv=none; b=P2M845m+zRCGj+uXv6JCkJU0E4bWRtFOyRK7IG/6bmPPiG8KC79nTIPO7g/z9exOw2/5CX9lg2UCfiSzQR3HXqcNHr3I20WZgYTB6Mfr76fl0e5oCpzQ7fG03xG221SkXq3QHbWHifCSFT/x+/ZVfwtajWH4TYC2mtMk/u9PREE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686772; c=relaxed/simple; bh=fy8xsI1SEtvN4pr6TFHlkqqIM9qnDZghXCr72Z2ASO8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cIz6/w0rug6TDavW66FOs8xv23nBzM6RitWcMo1tt/e4KokolH7SFZuOdKDpsatmozL2j/Far85zMaZ4QmO9h6TNk7Q/fNnvfxopbFm9u5cqAsGp5e4wBJfJgbAnlbG4BDs9HhTf3Awetc+74ManhqtKPVX0U780UlAdx/IUtTg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=EIFLRqdK; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="EIFLRqdK" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=m++wzPv9esK/TfLsYxA34OVU87Ffj0HBY/IuPLEhzOA=; b=EIFLRqdKLC0X4u2jlzEDwW1JVm lkgluv+Um/0JpXRCsxBlo7XJ6YTsN1Nq6VysYPvISunpoKI45jfEcKZrU0J5+14QSew5GFe7nOMg1 7PpwkuYZPkWSuHNlNXofwm7yL5dQ8S/cQprs0YAjKeC8vnUPJM4uEhqjgUoA60q5PhssCKZwvszc2 as9FvfDUppJFa62lVv8FmR1zAJ+QXQcIoWdT6qqN6d67/wgVif9qYsnrz9XYfVgq5dUUaU9zWI396 5zUM2tjqg1r6XaG+uILGFivpAyKK0IGNnGz1Wsle2O4YEuPUG2lj+d1GhUL/t9qQ9y8x81jXkRhCq z1KD8vZQ==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBR-00BiQh-Vf; Fri, 08 Aug 2025 22:59:26 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:47 -0300 Subject: [PATCH RFC v3 5/7] ovl: Set case-insensitive dentry operations for ovl sb Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-5-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 For filesystems with encoding (i.e. with case-insensitive support), set the dentry operations for the super block as ovl_dentry_ci_operations. Also, use the first layer encoding as the ovl super block encoding. Signed-off-by: Andr=C3=A9 Almeida --- 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 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index bcb7f5dbf9a32e4aa09bc41596be443851e21200..68091bf8368a880d62d94255526= 13497d6e90b6b 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -161,6 +161,16 @@ static const struct dentry_operations ovl_dentry_opera= tions =3D { .d_weak_revalidate =3D ovl_dentry_weak_revalidate, }; =20 +#if IS_ENABLED(CONFIG_UNICODE) +static const struct dentry_operations ovl_dentry_ci_operations =3D { + .d_real =3D ovl_d_real, + .d_revalidate =3D ovl_dentry_revalidate, + .d_weak_revalidate =3D ovl_dentry_weak_revalidate, + .d_hash =3D generic_ci_d_hash, + .d_compare =3D generic_ci_d_compare, +}; +#endif + static struct kmem_cache *ovl_inode_cachep; =20 static struct inode *ovl_alloc_inode(struct super_block *sb) @@ -1318,6 +1328,21 @@ static struct dentry *ovl_get_root(struct super_bloc= k *sb, return root; } =20 +/* + * Set the ovl sb encoding as the same one used by the first layer + */ +static void ovl_set_sb_ci_ops(struct super_block *ovl_sb, struct super_blo= ck *fs_sb) +{ +#if IS_ENABLED(CONFIG_UNICODE) + if (sb_has_encoding(fs_sb)) { + ovl_sb->s_encoding =3D fs_sb->s_encoding; + ovl_sb->s_encoding_flags =3D fs_sb->s_encoding_flags; + } + + set_default_d_op(ovl_sb, &ovl_dentry_ci_operations); +#endif +} + int ovl_fill_super(struct super_block *sb, struct fs_context *fc) { struct ovl_fs *ofs =3D sb->s_fs_info; @@ -1423,12 +1448,15 @@ int ovl_fill_super(struct super_block *sb, struct f= s_context *fc) =20 sb->s_stack_depth =3D upper_sb->s_stack_depth; sb->s_time_gran =3D upper_sb->s_time_gran; + } oe =3D ovl_get_lowerstack(sb, ctx, ofs, layers); err =3D PTR_ERR(oe); if (IS_ERR(oe)) goto out_err; =20 + ovl_set_sb_ci_ops(sb, ofs->fs[0].sb); + /* If the upper fs is nonexistent, we mark overlayfs r/o too */ if (!ovl_upper_mnt(ofs)) sb->s_flags |=3D SB_RDONLY; --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E64EF284B36; Fri, 8 Aug 2025 20:59:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686775; cv=none; b=IMBNlN0PKXTbE1RIRumV7VUSdNNJsb6GrRmS9l5plBgcsNAm10wGP+6xiQXO5qCv5cYSFyOF6izjduItqHHaY9papzzFWVXklC3d5PFOnr9CllgOyhzAtkU/wqef2CyVyozG2diXq3hqIYloWDdqqF6uHh3q/7DOgwGkU6OpE2I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686775; c=relaxed/simple; bh=bEyQbg6R1kJB0oUzkrNONklZ6LLiDcLYZ8kKhCpu1lQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dgxLyJB+bXwdXu3p/jRQnEwRY0AhAGQygdKAwlT5YX7a/UGlr2Cwbg+mmYIEwwKLkZNMGKhZM7qjzliQuT2p2igalqCa+AxY7BOsWsZs/5atTHC2/75FmRtk+/QR9Se6LgVQU08IDy2Rf4V3GQjH/MwI+FscPkh+2QtZskCe6z8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=fQXa4fw8; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="fQXa4fw8" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GHI81D+kXndW/mWzdJKZDgD5mhBdjY+srQPntrHrfVY=; b=fQXa4fw8D6UztZlMCUWL6ezRgV e9FxJOBSACftIH4tJE4oSBAkEr8hTS0cRf1Ogd4aQCGSNv1WRRTy5F7kZ8Q+KrADEjtnp2WliLyZP 9AHtQIKFvdoYwcp1KuMO9UrHruOeHsBkT5h3MGxEhsNgbwXds/a7+VNzzzazlruP2oIVUC7kdIJWN /5qfN3XUUzQlZTCAlHM7LtA6/U21SC7vBT7CaOWc/ahubLE6zRUEcrZdXiJFC+VJs4m5idYwAAM7Q hDiTnux7RnONZp14ey/F7FjnbkiovKw3Mh/bOF2OB/Zb5LJKHlyvKg8fn8VoIAqjnflqYGO+5NOT5 ns5cgRTw==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBU-00BiQh-Pq; Fri, 08 Aug 2025 22:59:28 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:48 -0300 Subject: [PATCH RFC v3 6/7] ovl: Add S_CASEFOLD as part of the inode flag to be copied Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-6-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 To keep ovl's inodes consistent with their real inodes, add the S_CASEFOLD flag as part of the flags that need to be copied. Signed-off-by: Andr=C3=A9 Almeida --- 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/overlayfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index bb0d7ded8e763a4a7a6fc506d966ed2f3bdb4f06..8a9a67d2933173c61b0fa0af563= 4d91e092e00b2 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -822,7 +822,7 @@ struct inode *ovl_get_inode(struct super_block *sb, void ovl_copyattr(struct inode *to); =20 /* vfs inode flags copied from real to ovl inode */ -#define OVL_COPY_I_FLAGS_MASK (S_SYNC | S_NOATIME | S_APPEND | S_IMMUTABLE) +#define OVL_COPY_I_FLAGS_MASK (S_SYNC | S_NOATIME | S_APPEND | S_IMMUTABLE= | S_CASEFOLD) /* vfs inode flags read from overlay.protattr xattr to ovl inode */ #define OVL_PROT_I_FLAGS_MASK (S_APPEND | S_IMMUTABLE) =20 --=20 2.50.1 From nobody Sun Oct 5 03:38:53 2025 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFFC5242D78; Fri, 8 Aug 2025 20:59:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.97.179.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686778; cv=none; b=oPHftiE4oG9sVo//ciKBLhpupTeQ7tzeFlmw7HWerL1RQPnrbqDfPLr0N4eRBMXS6Z2AP1MjF7wgy1eqUP6YqT84kN2cO6fWRMexL0SJGuPJEMqPvNgmXedeB44WSZecqdzzG5i7nTP6pwaJqUhtDnJ3pZcTSqKv5xA0Jt5ViCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754686778; c=relaxed/simple; bh=3j//bm9wrCCu/luOkjMaWoCCo3aMUVnc2+JWWKJ7n7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SksDCpMusl4kEnLGAXPJXc5NBJ1JxnQIhsKvAGXlSuB67hGk+u/T2vNjmAN6UOd21hClWsyFx+KA8hSo8gh6+bjqsoBEgYSRDRrCDK/uafOHrAw/DwXajnc5EVmm7Uvu26H64+iz1Hl9Pe8d1Dw9U8DnZ27YsaDj4FtaMiobwKs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=ULwmOTti; arc=none smtp.client-ip=213.97.179.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="ULwmOTti" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=r2xKDwZZxr802QgfDROUhXUb+UwSwmSz5Q4cP/5SKJI=; b=ULwmOTtiPDusUAEe4bhfX2R49n gkaqfjarpBteTrzodMqHMXQi/Oaz2ymiG0j+M7ETBfVCed62VdaGEAHAXLMe7JjHd1Zel0x9QIcW6 NC10FmMzkj7pARLS5CAp/rzx/TCsScQy2UjIwAhjMK3UWPRqHhnBXOuZ3an/UvJ4RPGPqeUKONGeW 8X8FkGTNPV1W/XYU9AsOXEsw6O+jDLQOWAckSBu2vTOekCYlFgy0HoxAGI/JfwxPC7r9YulPMYkzV nQRF3HBZMYsAzfL99y18zum7rek/CsHGjOIY2iTQcYpcN3Is8V3kffgsgpoKApdBnacIYD6/cAURN pzIU/kbA==; Received: from [152.250.7.37] (helo=[192.168.15.100]) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1ukUBX-00BiQh-K9; Fri, 08 Aug 2025 22:59:31 +0200 From: =?utf-8?q?Andr=C3=A9_Almeida?= Date: Fri, 08 Aug 2025 17:58:49 -0300 Subject: [PATCH RFC v3 7/7] ovl: Support case-insensitive lookup Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250808-tonyk-overlayfs-v3-7-30f9be426ba8@igalia.com> References: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> In-Reply-To: <20250808-tonyk-overlayfs-v3-0-30f9be426ba8@igalia.com> To: Miklos Szeredi , Amir Goldstein , Theodore Tso , Gabriel Krisman Bertazi Cc: linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , kernel-dev@igalia.com, =?utf-8?q?Andr=C3=A9_Almeida?= X-Mailer: b4 0.14.2 Drop the restriction for casefold dentries to enable support for case-insensitive filesystems in overlayfs. Support case-insensitive filesystems with the condition that they should be uniformly enabled across the stack and the layers (i.e. if the root mount dir has casefold enabled, so should all the dirs bellow for every layer). Signed-off-by: Andr=C3=A9 Almeida --- Changes from v2: - Create new ovl_fs flag, bool casefold - Check if casefolded dentry is consistent with the root dentry --- fs/overlayfs/namei.c | 17 +++++++++-------- fs/overlayfs/ovl_entry.h | 1 + fs/overlayfs/params.c | 7 ++----- fs/overlayfs/util.c | 8 ++++---- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 76d6248b625e7c58e09685e421aef616aadea40a..08b34e52b36f93d4da09e4d13b5= 1d23dc99ca6d6 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -239,13 +239,14 @@ static int ovl_lookup_single(struct dentry *base, str= uct ovl_lookup_data *d, char val; =20 /* - * 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 enabled case folding on a + * directory on underlying layer, the warranty of the ovl stack is + * voided. */ - if (ovl_dentry_casefolded(base)) { - warn =3D "case folded parent"; + if (ofs->casefold !=3D ovl_dentry_casefolded(base)) { + warn =3D "parent wrong casefold"; err =3D -ESTALE; goto out_warn; } @@ -259,8 +260,8 @@ static int ovl_lookup_single(struct dentry *base, struc= t ovl_lookup_data *d, goto out_err; } =20 - if (ovl_dentry_casefolded(this)) { - warn =3D "case folded child"; + if (ofs->casefold !=3D ovl_dentry_casefolded(this)) { + warn =3D "child wrong casefold"; err =3D -EREMOTE; goto out_warn; } diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index 4c1bae935ced274f93a0d23fe10d34455e226ec4..1d4828dbcf7ac4ba9657221e601= bbf79d970d225 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; }; =20 /* Number of lower layers, not including data-only layers */ diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index f4e7fff909ac49e2f8c58a76273426c1158a7472..afa1c29515a9729bfe88c8166da= 4aefa6cddc5a5 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -277,16 +277,13 @@ 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 =3D fc->fs_private; + struct ovl_fs *ovl =3D fc->s_fs_info; =20 if (!d_is_dir(path->dentry)) return invalfc(fc, "%s is not a directory", name); =20 - /* - * Allow filesystems that are case-folding capable but deny composing - * ovl stack from case-folded directories. - */ if (ovl_dentry_casefolded(path->dentry)) - return invalfc(fc, "case-insensitive directory on %s not supported", nam= e); + ovl->casefold =3D true; =20 if (ovl_dentry_weird(path->dentry)) return invalfc(fc, "filesystem on %s not supported", name); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index a33115e7384c129c543746326642813add63f060..7a6ee058568283453350153c172= 0c35e11ad4d1b 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -210,11 +210,11 @@ bool ovl_dentry_weird(struct dentry *dentry) return true; =20 /* - * 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; =20 return dentry->d_flags & (DCACHE_OP_HASH | DCACHE_OP_COMPARE); } --=20 2.50.1