fs/overlayfs/namei.c | 11 ++++++----- fs/overlayfs/overlayfs.h | 2 +- fs/overlayfs/ovl_entry.h | 1 + fs/overlayfs/params.c | 5 +++-- fs/overlayfs/readdir.c | 32 +++++++++++++++++++++----------- fs/overlayfs/util.c | 12 +++++++----- 6 files changed, 39 insertions(+), 24 deletions(-)
Hi all, We would like to support the usage of casefold filesystems with overlayfs. This patchset do some of the work needed for that, but I'm sure there are more places that need to be tweaked so please share your feedback for this work. * Implementation The most obvious place that required change was the strncmp() inside of ovl_cache_entry_find(), that I managed to convert to use d_same_name(), that will then call the generic_ci_d_compare function if it's set for the dentry. There are more strncmp() around ovl, but I would rather hear feedback about this approach first than already implementing this around the code. * Testing I used tmpfs to create a small ovl like this: sudo mount -t tmpfs -o casefold tmpfs mnt/ cd mnt/ mkdir dir chattr +F dir cd dir/ mkdir upper lower mkdir lower/A lower/b lower/c mkdir upper/a upper/b upper/d mkdir merged work sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work, merged ls /tmp/mnt/dir/merged/ a b c d And ovl is respecting the equivalent names. `a` points to a merged dir between `A` and `a`, but giving that upperdir has a lowercase `a`, this is the name displayed here. Thanks, André --- André Almeida (3): ovl: Make ovl_cache_entry_find support casefold ovl: Make ovl_dentry_weird() accept casefold dentries ovl: Enable support for casefold filesystems fs/overlayfs/namei.c | 11 ++++++----- fs/overlayfs/overlayfs.h | 2 +- fs/overlayfs/ovl_entry.h | 1 + fs/overlayfs/params.c | 5 +++-- fs/overlayfs/readdir.c | 32 +++++++++++++++++++++----------- fs/overlayfs/util.c | 12 +++++++----- 6 files changed, 39 insertions(+), 24 deletions(-) --- base-commit: a24588245776dafc227243a01bfbeb8a59bafba9 change-id: 20250409-tonyk-overlayfs-591f5e4d407a Best regards, -- André Almeida <andrealmeid@igalia.com>
On Wed, Apr 9, 2025 at 5:01 PM André Almeida <andrealmeid@igalia.com> wrote: > > Hi all, > > We would like to support the usage of casefold filesystems with > overlayfs. This patchset do some of the work needed for that, but I'm > sure there are more places that need to be tweaked so please share your > feedback for this work. > > * Implementation > > The most obvious place that required change was the strncmp() inside of > ovl_cache_entry_find(), that I managed to convert to use d_same_name(), That's a very niche part of overlayfs where comparison of names matter. Please look very closely at ovl_lookup() and how an overlay entry stack is composed from several layers including the option to redirect to different names via redirect xattr, so there is really very much to deal with other than readdir. I suggest that you start with a design proposal of how you intend to tackle this task and what are your requirements? Any combination of casefold supported layers? Thanks, Amir. > that will then call the generic_ci_d_compare function if it's set for > the dentry. There are more strncmp() around ovl, but I would rather hear > feedback about this approach first than already implementing this around > the code. > > * Testing > > I used tmpfs to create a small ovl like this: > > sudo mount -t tmpfs -o casefold tmpfs mnt/ > cd mnt/ > mkdir dir > chattr +F dir > cd dir/ > mkdir upper lower > mkdir lower/A lower/b lower/c > mkdir upper/a upper/b upper/d > mkdir merged work > sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work, merged > ls /tmp/mnt/dir/merged/ > a b c d > > And ovl is respecting the equivalent names. `a` points to a merged dir > between `A` and `a`, but giving that upperdir has a lowercase `a`, this > is the name displayed here. > > Thanks, > André > > --- > André Almeida (3): > ovl: Make ovl_cache_entry_find support casefold > ovl: Make ovl_dentry_weird() accept casefold dentries > ovl: Enable support for casefold filesystems > > fs/overlayfs/namei.c | 11 ++++++----- > fs/overlayfs/overlayfs.h | 2 +- > fs/overlayfs/ovl_entry.h | 1 + > fs/overlayfs/params.c | 5 +++-- > fs/overlayfs/readdir.c | 32 +++++++++++++++++++++----------- > fs/overlayfs/util.c | 12 +++++++----- > 6 files changed, 39 insertions(+), 24 deletions(-) > --- > base-commit: a24588245776dafc227243a01bfbeb8a59bafba9 > change-id: 20250409-tonyk-overlayfs-591f5e4d407a > > Best regards, > -- > André Almeida <andrealmeid@igalia.com> >
André Almeida <andrealmeid@igalia.com> writes: > Hi all, > > We would like to support the usage of casefold filesystems with > overlayfs. This patchset do some of the work needed for that, but I'm > sure there are more places that need to be tweaked so please share your > feedback for this work. I didn't look the patches yet, but this is going to be quite tricky. For a start, consider the semantics when mixing volumes with different case settings for lower/upper/work directories. And that could be any setting, such as whether the directory has +F, the encoding version and the encoding flags (strict mode). Any mismatch will look bonkers and you want to forbid the mount. Consider upperdir is case-sensitive but lowerdir is not. In this case, I suspect the case-exact name would be hidden by the upper, but the inexact-case would still resolve from the lower when it shouldn't, and can't be raised again. If we have the other way around, the upper will hide more than one file from the lower and it is a matter of luck which file we are getting. In addition, if we have a case-insensitive on top of a case-sensitive, there is no way we can do the case-insensitive lookup on the lower without doing a sequential search across the entire directory. Then it is again a matter of luck which file we are getting. The issue can appear even on the same volume, since case-insensitiveness is actually per-directory and can be flipped when a directory is empty. If something like the below is possible, we are in the same situation again: mkdir lower/ci chattr +F lower/ci touch lower/ci/BLA mount -o overlay none upperdir=upper,lowerdir=lower,workdir=work merged rm -r merged/ci/BLA // creates a whiteout in upper // merged looks empty and should be allowed to drop +F chattr -F merged/ci So we'd also need to always forbid clearing the +F attribute and perhaps forbid it from ever being set on the merged directory. We also want to require the encoding version and flags to match. > * Implementation > > The most obvious place that required change was the strncmp() inside of > ovl_cache_entry_find(), that I managed to convert to use d_same_name(), > that will then call the generic_ci_d_compare function if it's set for > the dentry. There are more strncmp() around ovl, but I would rather hear > feedback about this approach first than already implementing this around > the code. I'd suggest marking it as an RFC since it is not a functional implementation yet, IIUC. >> * Testing > sudo mount -t tmpfs -o casefold tmpfs mnt/ > cd mnt/ > mkdir dir > chattr +F dir > cd dir/ > mkdir upper lower > mkdir lower/A lower/b lower/c > mkdir upper/a upper/b upper/d > mkdir merged work > sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work, merged > ls /tmp/mnt/dir/merged/ > a b c d > > And ovl is respecting the equivalent names. `a` points to a merged dir > between `A` and `a`, but giving that upperdir has a lowercase `a`, this > is the name displayed here. Did you try fstests generic/556? It might require some work to make it run over ovl, but it will exercise several cases that are quite hard to spot. -- Gabriel Krisman Bertazi
Hi Gabriel! Em 09/04/2025 13:52, Gabriel Krisman Bertazi escreveu: > André Almeida <andrealmeid@igalia.com> writes: > >> Hi all, >> >> We would like to support the usage of casefold filesystems with >> overlayfs. This patchset do some of the work needed for that, but I'm >> sure there are more places that need to be tweaked so please share your >> feedback for this work. > > I didn't look the patches yet, but this is going to be quite tricky. > For a start, consider the semantics when mixing volumes with different > case settings for lower/upper/work directories. And that could be any > setting, such as whether the directory has +F, the encoding version and > the encoding flags (strict mode). Any mismatch will look bonkers and > you want to forbid the mount. > > Consider upperdir is case-sensitive but lowerdir is not. In this case, > I suspect the case-exact name would be hidden by the upper, but the > inexact-case would still resolve from the lower when it shouldn't, and > can't be raised again. If we have the other way around, the upper > will hide more than one file from the lower and it is a matter of luck > which file we are getting. > > In addition, if we have a case-insensitive on top of a case-sensitive, > there is no way we can do the case-insensitive lookup on the lower > without doing a sequential search across the entire directory. Then it > is again a matter of luck which file we are getting. > > The issue can appear even on the same volume, since case-insensitiveness > is actually per-directory and can be flipped when a directory is empty. > If something like the below is possible, we are in the same situation > again: > > mkdir lower/ci > chattr +F lower/ci > touch lower/ci/BLA > mount -o overlay none upperdir=upper,lowerdir=lower,workdir=work merged > rm -r merged/ci/BLA // creates a whiteout in upper > // merged looks empty and should be allowed to drop +F > chattr -F merged/ci > > So we'd also need to always forbid clearing the +F attribute and perhaps > forbid it from ever being set on the merged directory. We also want to > require the encoding version and flags to match. > Thank you for the prompt response. I agree with you, for the next version I will implement such restrictions. I think it will be better to start with very restrict possibilities and then slowly dropping then, if they prove to be not problematic. >> * Implementation >> >> The most obvious place that required change was the strncmp() inside of >> ovl_cache_entry_find(), that I managed to convert to use d_same_name(), >> that will then call the generic_ci_d_compare function if it's set for >> the dentry. There are more strncmp() around ovl, but I would rather hear >> feedback about this approach first than already implementing this around >> the code. > > I'd suggest marking it as an RFC since it is not a functional > implementation yet, IIUC. > Ops, you are right, I forgot to tag it as such. >>> * Testing >> sudo mount -t tmpfs -o casefold tmpfs mnt/ >> cd mnt/ >> mkdir dir >> chattr +F dir >> cd dir/ >> mkdir upper lower >> mkdir lower/A lower/b lower/c >> mkdir upper/a upper/b upper/d >> mkdir merged work >> sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work, merged >> ls /tmp/mnt/dir/merged/ >> a b c d >> >> And ovl is respecting the equivalent names. `a` points to a merged dir >> between `A` and `a`, but giving that upperdir has a lowercase `a`, this >> is the name displayed here. > > Did you try fstests generic/556? It might require some work to make it > run over ovl, but it will exercise several cases that are quite > hard to spot. > > I haven't tried, I'm not sure which directory should I point to fstests to use for the test, the merged one?
© 2016 - 2025 Red Hat, Inc.