linux/fs/overlayfs
Miklos Szeredi 5cffa333a2 ovl: fix filattr copy-up failure
commit 5b0a414d06 upstream.

This regression can be reproduced with ntfs-3g and overlayfs:

  mkdir lower upper work overlay
  dd if=/dev/zero of=ntfs.raw bs=1M count=2
  mkntfs -F ntfs.raw
  mount ntfs.raw lower
  touch lower/file.txt
  mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work - overlay
  mv overlay/file.txt overlay/file2.txt

mv fails and (misleadingly) prints

  mv: cannot move 'overlay/file.txt' to a subdirectory of itself, 'overlay/file2.txt'

The reason is that ovl_copy_fileattr() is triggered due to S_NOATIME being
set on all inodes (by fuse) regardless of fileattr.

ovl_copy_fileattr() tries to retrieve file attributes from lower file, but
that fails because filesystem does not support this ioctl (this should fail
with ENOTTY, but ntfs-3g return EINVAL instead).  This failure is
propagated to origial operation (in this case rename) that triggered the
copy-up.

The fix is to ignore ENOTTY and EINVAL errors from fileattr_get() in copy
up.  This also requires turning the internal ENOIOCTLCMD into ENOTTY.

As a further measure to prevent unnecessary failures, only try the
fileattr_get/set on upper if there are any flags to copy up.

Side note: a number of filesystems set S_NOATIME (and sometimes other inode
flags) irrespective of fileattr flags.  This causes unnecessary calls
during copy up, which might lead to a performance issue, especially if
latency is high.  To fix this, the kernel would need to differentiate
between the two cases.  E.g. introduce SB_NOATIME_UPDATE, a per-sb variant
of S_NOATIME.  SB_NOATIME doesn't work, because that's interpreted as
"filesystem doesn't store an atime attribute"

Reported-and-tested-by: Kevin Locke <kevin@kevinlocke.name>
Fixes: 72db82115d ("ovl: copy up sync/noatime fileattr flags")
Cc: <stable@vger.kernel.org> # v5.15
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-18 19:16:04 +01:00
..
Kconfig docs: fix broken references to text files 2020-04-20 15:35:59 -06:00
Makefile treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
copy_up.c ovl: fix filattr copy-up failure 2021-11-18 19:16:04 +01:00
dir.c ovl: fix missing negative dentry check in ovl_rename() 2021-09-24 21:00:31 +02:00
export.c ovl: fix uninitialized pointer read in ovl_lookup_real_one() 2021-08-10 10:21:30 +02:00
file.c ovl: fix use after free in struct ovl_aio_req 2021-11-18 19:16:04 +01:00
inode.c ovl: fix filattr copy-up failure 2021-11-18 19:16:04 +01:00
namei.c ovl: relax lookup error on mismatch origin ftype 2021-08-17 11:47:44 +02:00
overlayfs.h vfs: add rcu argument to ->get_acl() callback 2021-08-18 22:08:24 +02:00
ovl_entry.h ovl: implement volatile-specific fsync error behaviour 2021-01-28 10:22:48 +01:00
readdir.c ovl: skip stale entries in merge dir cache iteration 2021-08-10 10:21:30 +02:00
super.c ovl: add ovl_allow_offline_changes() helper 2021-08-17 11:47:44 +02:00
util.c ovl: consistent behavior for immutable/append-only inodes 2021-08-17 11:47:43 +02:00