* [PATCH 2/5] kill getname_statx_lookup_flags()
2024-11-12 20:25 ` [PATCH 1/5] io_statx_prep(): use getname_uflags() Al Viro
@ 2024-11-12 20:25 ` Al Viro
2024-11-13 10:20 ` Christian Brauner
2024-11-12 20:25 ` [PATCH 3/5] fs/stat.c: switch to CLASS(fd_raw) Al Viro
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Al Viro @ 2024-11-12 20:25 UTC (permalink / raw)
To: linux-fsdevel; +Cc: viro, Christian Brauner, Jan Kara, Jens Axboe
LOOKUP_EMPTY is ignored by the only remaining user, and without
that 'getname_' prefix makes no sense.
Remove LOOKUP_EMPTY part, rename to statx_lookup_flags() and make
static. It most likely is _not_ statx() specific, either, but
that's the next step.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/internal.h | 1 -
fs/stat.c | 6 ++----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/fs/internal.h b/fs/internal.h
index 8c1b7acbbe8f..8cf42b327e5e 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -246,7 +246,6 @@ int open_namespace(struct ns_common *ns);
* fs/stat.c:
*/
-int getname_statx_lookup_flags(int flags);
int do_statx(int dfd, struct filename *filename, unsigned int flags,
unsigned int mask, struct statx __user *buffer);
int do_statx_fd(int fd, unsigned int flags, unsigned int mask,
diff --git a/fs/stat.c b/fs/stat.c
index b74831dc7ae6..4e8698fa932f 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -231,7 +231,7 @@ int vfs_fstat(int fd, struct kstat *stat)
return error;
}
-int getname_statx_lookup_flags(int flags)
+static int statx_lookup_flags(int flags)
{
int lookup_flags = 0;
@@ -239,8 +239,6 @@ int getname_statx_lookup_flags(int flags)
lookup_flags |= LOOKUP_FOLLOW;
if (!(flags & AT_NO_AUTOMOUNT))
lookup_flags |= LOOKUP_AUTOMOUNT;
- if (flags & AT_EMPTY_PATH)
- lookup_flags |= LOOKUP_EMPTY;
return lookup_flags;
}
@@ -301,7 +299,7 @@ static int vfs_statx(int dfd, struct filename *filename, int flags,
struct kstat *stat, u32 request_mask)
{
struct path path;
- unsigned int lookup_flags = getname_statx_lookup_flags(flags);
+ unsigned int lookup_flags = statx_lookup_flags(flags);
int error;
if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 3/5] fs/stat.c: switch to CLASS(fd_raw)
2024-11-12 20:25 ` [PATCH 1/5] io_statx_prep(): use getname_uflags() Al Viro
2024-11-12 20:25 ` [PATCH 2/5] kill getname_statx_lookup_flags() Al Viro
@ 2024-11-12 20:25 ` Al Viro
2024-11-13 10:20 ` Christian Brauner
2024-11-12 20:25 ` [PATCH 4/5] fs: Simplify getattr interface function checking AT_GETATTR_NOSEC flag Al Viro
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Al Viro @ 2024-11-12 20:25 UTC (permalink / raw)
To: linux-fsdevel; +Cc: viro, Christian Brauner, Jan Kara, Jens Axboe
... and use fd_empty() consistently
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/stat.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/fs/stat.c b/fs/stat.c
index 4e8698fa932f..855b995ad09b 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -220,15 +220,10 @@ EXPORT_SYMBOL(vfs_getattr);
*/
int vfs_fstat(int fd, struct kstat *stat)
{
- struct fd f;
- int error;
-
- f = fdget_raw(fd);
- if (!fd_file(f))
+ CLASS(fd_raw, f)(fd);
+ if (fd_empty(f))
return -EBADF;
- error = vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);
- fdput(f);
- return error;
+ return vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);
}
static int statx_lookup_flags(int flags)
@@ -275,7 +270,7 @@ static int vfs_statx_fd(int fd, int flags, struct kstat *stat,
u32 request_mask)
{
CLASS(fd_raw, f)(fd);
- if (!fd_file(f))
+ if (fd_empty(f))
return -EBADF;
return vfs_statx_path(&fd_file(f)->f_path, flags, stat, request_mask);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 4/5] fs: Simplify getattr interface function checking AT_GETATTR_NOSEC flag
2024-11-12 20:25 ` [PATCH 1/5] io_statx_prep(): use getname_uflags() Al Viro
2024-11-12 20:25 ` [PATCH 2/5] kill getname_statx_lookup_flags() Al Viro
2024-11-12 20:25 ` [PATCH 3/5] fs/stat.c: switch to CLASS(fd_raw) Al Viro
@ 2024-11-12 20:25 ` Al Viro
2024-11-13 10:22 ` Christian Brauner
2024-11-12 20:25 ` [PATCH 5/5] libfs: kill empty_dir_getattr() Al Viro
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Al Viro @ 2024-11-12 20:25 UTC (permalink / raw)
To: linux-fsdevel
Cc: viro, Christian Brauner, Jan Kara, Jens Axboe, Stefan Berger,
Tyler Hicks, ecryptfs, Miklos Szeredi, Amir Goldstein,
linux-unionfs
From: Stefan Berger <stefanb@linux.ibm.com>
Commit 8a924db2d7b5 ("fs: Pass AT_GETATTR_NOSEC flag to getattr interface
function")' introduced the AT_GETATTR_NOSEC flag to ensure that the
call paths only call vfs_getattr_nosec if it is set instead of vfs_getattr.
Now, simplify the getattr interface functions of filesystems where the flag
AT_GETATTR_NOSEC is checked.
There is only a single caller of inode_operations getattr function and it
is located in fs/stat.c in vfs_getattr_nosec. The caller there is the only
one from which the AT_GETATTR_NOSEC flag is passed from.
Two filesystems are checking this flag in .getattr and the flag is always
passed to them unconditionally from only vfs_getattr_nosec:
- ecryptfs: Simplify by always calling vfs_getattr_nosec in
ecryptfs_getattr. From there the flag is passed to no other
function and this function is not called otherwise.
- overlayfs: Simplify by always calling vfs_getattr_nosec in
ovl_getattr. From there the flag is passed to no other
function and this function is not called otherwise.
The query_flags in vfs_getattr_nosec will mask-out AT_GETATTR_NOSEC from
any caller using AT_STATX_SYNC_TYPE as mask so that the flag is not
important inside this function. Also, since no filesystem is checking the
flag anymore, remove the flag entirely now, including the BUG_ON check that
never triggered.
The net change of the changes here combined with the original commit is
that ecryptfs and overlayfs do not call vfs_getattr but only
vfs_getattr_nosec.
Fixes: 8a924db2d7b5 ("fs: Pass AT_GETATTR_NOSEC flag to getattr interface function")
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Closes: https://lore.kernel.org/linux-fsdevel/20241101011724.GN1350452@ZenIV/T/#u
Cc: Tyler Hicks <code@tyhicks.com>
Cc: ecryptfs@vger.kernel.org
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: linux-unionfs@vger.kernel.org
Cc: Christian Brauner <brauner@kernel.org>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ecryptfs/inode.c | 12 ++----------
fs/overlayfs/inode.c | 10 +++++-----
fs/overlayfs/overlayfs.h | 8 --------
fs/stat.c | 5 +----
include/uapi/linux/fcntl.h | 4 ----
5 files changed, 8 insertions(+), 31 deletions(-)
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 5ed1e4cf6c0b..644e973d5a77 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -1008,14 +1008,6 @@ static int ecryptfs_getattr_link(struct mnt_idmap *idmap,
return rc;
}
-static int ecryptfs_do_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags)
-{
- if (flags & AT_GETATTR_NOSEC)
- return vfs_getattr_nosec(path, stat, request_mask, flags);
- return vfs_getattr(path, stat, request_mask, flags);
-}
-
static int ecryptfs_getattr(struct mnt_idmap *idmap,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
@@ -1024,8 +1016,8 @@ static int ecryptfs_getattr(struct mnt_idmap *idmap,
struct kstat lower_stat;
int rc;
- rc = ecryptfs_do_getattr(ecryptfs_dentry_to_lower_path(dentry),
- &lower_stat, request_mask, flags);
+ rc = vfs_getattr_nosec(ecryptfs_dentry_to_lower_path(dentry),
+ &lower_stat, request_mask, flags);
if (!rc) {
fsstack_copy_attr_all(d_inode(dentry),
ecryptfs_inode_to_lower(d_inode(dentry)));
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 35fd3e3e1778..8b31f44c12cd 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -170,7 +170,7 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
type = ovl_path_real(dentry, &realpath);
old_cred = ovl_override_creds(dentry->d_sb);
- err = ovl_do_getattr(&realpath, stat, request_mask, flags);
+ err = vfs_getattr_nosec(&realpath, stat, request_mask, flags);
if (err)
goto out;
@@ -195,8 +195,8 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
(!is_dir ? STATX_NLINK : 0);
ovl_path_lower(dentry, &realpath);
- err = ovl_do_getattr(&realpath, &lowerstat, lowermask,
- flags);
+ err = vfs_getattr_nosec(&realpath, &lowerstat, lowermask,
+ flags);
if (err)
goto out;
@@ -248,8 +248,8 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path,
ovl_path_lowerdata(dentry, &realpath);
if (realpath.dentry) {
- err = ovl_do_getattr(&realpath, &lowerdatastat,
- lowermask, flags);
+ err = vfs_getattr_nosec(&realpath, &lowerdatastat,
+ lowermask, flags);
if (err)
goto out;
} else {
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 0bfe35da4b7b..910dbbb2bb7b 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -412,14 +412,6 @@ static inline bool ovl_open_flags_need_copy_up(int flags)
return ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC));
}
-static inline int ovl_do_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags)
-{
- if (flags & AT_GETATTR_NOSEC)
- return vfs_getattr_nosec(path, stat, request_mask, flags);
- return vfs_getattr(path, stat, request_mask, flags);
-}
-
/* util.c */
int ovl_get_write_access(struct dentry *dentry);
void ovl_put_write_access(struct dentry *dentry);
diff --git a/fs/stat.c b/fs/stat.c
index 855b995ad09b..011d2160b7af 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -165,7 +165,7 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
if (inode->i_op->getattr)
return inode->i_op->getattr(idmap, path, stat,
request_mask,
- query_flags | AT_GETATTR_NOSEC);
+ query_flags);
generic_fillattr(idmap, request_mask, inode, stat);
return 0;
@@ -198,9 +198,6 @@ int vfs_getattr(const struct path *path, struct kstat *stat,
{
int retval;
- if (WARN_ON_ONCE(query_flags & AT_GETATTR_NOSEC))
- return -EPERM;
-
retval = security_inode_getattr(path);
if (retval)
return retval;
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
index 87e2dec79fea..a40833bf2855 100644
--- a/include/uapi/linux/fcntl.h
+++ b/include/uapi/linux/fcntl.h
@@ -154,8 +154,4 @@
usable with open_by_handle_at(2). */
#define AT_HANDLE_MNT_ID_UNIQUE 0x001 /* Return the u64 unique mount ID. */
-#if defined(__KERNEL__)
-#define AT_GETATTR_NOSEC 0x80000000
-#endif
-
#endif /* _UAPI_LINUX_FCNTL_H */
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 5/5] libfs: kill empty_dir_getattr()
2024-11-12 20:25 ` [PATCH 1/5] io_statx_prep(): use getname_uflags() Al Viro
` (2 preceding siblings ...)
2024-11-12 20:25 ` [PATCH 4/5] fs: Simplify getattr interface function checking AT_GETATTR_NOSEC flag Al Viro
@ 2024-11-12 20:25 ` Al Viro
2024-11-13 10:22 ` Christian Brauner
2024-11-13 10:20 ` [PATCH 1/5] io_statx_prep(): use getname_uflags() Christian Brauner
2024-11-13 14:07 ` Jens Axboe
5 siblings, 1 reply; 12+ messages in thread
From: Al Viro @ 2024-11-12 20:25 UTC (permalink / raw)
To: linux-fsdevel; +Cc: viro, Christian Brauner, Jan Kara, Jens Axboe
It's used only to initialize ->getattr in one inode_operations instance
(empty_dir_inode_operations) and its behaviour had always been equivalent
to what we get with NULL ->getattr.
Just remove that initializer, along with empty_dir_getattr() itself.
While we are at it, the same instance has ->permission initialized to
generic_permission, which is what NULL ->permission ends up doing.
Again, no point keeping it.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/libfs.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c
index 46966fd8bcf9..12f5185f3fa9 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1711,15 +1711,6 @@ static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry,
return ERR_PTR(-ENOENT);
}
-static int empty_dir_getattr(struct mnt_idmap *idmap,
- const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int query_flags)
-{
- struct inode *inode = d_inode(path->dentry);
- generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
- return 0;
-}
-
static int empty_dir_setattr(struct mnt_idmap *idmap,
struct dentry *dentry, struct iattr *attr)
{
@@ -1733,9 +1724,7 @@ static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t siz
static const struct inode_operations empty_dir_inode_operations = {
.lookup = empty_dir_lookup,
- .permission = generic_permission,
.setattr = empty_dir_setattr,
- .getattr = empty_dir_getattr,
.listxattr = empty_dir_listxattr,
};
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread