Re: [PATCH v3 3/3] fs: store real path instead of fake path in backing file f_path
From: Al Viro <viro@zeniv.linux.org.uk>
Date: 2023-10-10 18:21:54
Also in:
linux-fsdevel, linux-integrity, linux-unionfs
On Tue, Oct 10, 2023 at 08:57:21PM +0300, Amir Goldstein wrote:
On Tue, Oct 10, 2023 at 8:41 PM Al Viro [off-list ref] wrote:quoted
On Tue, Oct 10, 2023 at 05:55:04PM +0100, Al Viro wrote:quoted
On Tue, Oct 10, 2023 at 03:34:45PM +0200, Miklos Szeredi wrote:quoted
On Tue, 10 Oct 2023 at 15:17, Amir Goldstein [off-list ref] wrote:quoted
Sorry, you asked about ovl mount. To me it makes sense that if users observe ovl paths in writable mapped memory, that ovl should not be remounted RO. Anyway, I don't see a good reason to allow remount RO for ovl in that case. Is there?Agreed. But is preventing remount RO important enough to warrant special casing of backing file in generic code? I'm not convinced either way...You definitely want to guarantee that remounting filesystem r/o prevents the changes of visible contents; it's not just POSIX, it's a fairly basic common assumption about any local filesystems.Incidentally, could we simply keep a reference to original struct file instead of messing with path? The only caller of backing_file_open() gets &file->f_path as user_path; how about passing file instead, and having backing_file_open() do get_file() on it and stash the sucker into your object? And have put_file_access() do if (unlikely(file->f_mode & FMODE_BACKING)) fput(backing_file(file)->file); in the end. No need to mess with write access in any special way and it's closer to the semantics we have for normal mmap(), after all - it keeps the file we'd passed to it open as long as mapping is there. Comments?Seems good to me. It also shrinks backing_file by one pointer. I think this patch can be an extra one after "fs: store real path instead of fake path in backing file f_path" Instead of changing storing of real_path to storing orig file in one change? If there are no objections, I will write it up.
Actually, now that I'd looked at it a bit more... Look:
we don't need to do *anything* in put_file_access(); just
make file_free()
if (unlikely(f->f_mode & FMODE_BACKING))
fput(backing_file(f)->user_file);
instead of conditional path_put(). That + change of open_backing_file()
prototype + get_file() in there pretty much eliminates the work done
in 1/3 - you don't need to mess with {get,put}_file_write_access()
at all.
I'd start with this:
struct file *vm_user_file(struct vm_area_struct *vma)
{
return vma->vm_file;
}
+ replace file = vma->vm_file; with file = vm_user_file(vma) in
the places affected by your 2/3. That's the first (obviously
safe) commit. Then the change of backing_file_open() combined
with making vm_user_file() do this:
file = vma->vm_file;
if (file && unlikely(file->f_mode & FMODE_BACKING))
file = backing_file(file)->user_file;
return file;
Voila. Two-commit series, considerably smaller than your
variant...