mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
fs: move the bdex_statx call to vfs_getattr_nosec
Currently bdex_statx is only called from the very high-level vfs_statx_path function, and thus bypassing it for in-kernel calls to vfs_getattr or vfs_getattr_nosec. This breaks querying the block ѕize of the underlying device in the loop driver and also is a pitfall for any other new kernel caller. Move the call into the lowest level helper to ensure all callers get the right results. Fixes:2d985f8c6b
("vfs: support STATX_DIOALIGN on block devices") Fixes:f4774e92aa
("loop: take the file system minimum dio alignment into account") Reported-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/20250417064042.712140-1-hch@lst.de Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
58db1c3cd0
commit
777d0961ff
3 changed files with 22 additions and 19 deletions
|
@ -1272,8 +1272,7 @@ void sync_bdevs(bool wait)
|
|||
/*
|
||||
* Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices.
|
||||
*/
|
||||
void bdev_statx(struct path *path, struct kstat *stat,
|
||||
u32 request_mask)
|
||||
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
|
||||
{
|
||||
struct inode *backing_inode;
|
||||
struct block_device *bdev;
|
||||
|
|
30
fs/stat.c
30
fs/stat.c
|
@ -204,12 +204,25 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
|
|||
STATX_ATTR_DAX);
|
||||
|
||||
idmap = mnt_idmap(path->mnt);
|
||||
if (inode->i_op->getattr)
|
||||
return inode->i_op->getattr(idmap, path, stat,
|
||||
request_mask,
|
||||
query_flags);
|
||||
if (inode->i_op->getattr) {
|
||||
int ret;
|
||||
|
||||
ret = inode->i_op->getattr(idmap, path, stat, request_mask,
|
||||
query_flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
generic_fillattr(idmap, request_mask, inode, stat);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a block device inode, override the filesystem attributes
|
||||
* with the block device specific parameters that need to be obtained
|
||||
* from the bdev backing inode.
|
||||
*/
|
||||
if (S_ISBLK(stat->mode))
|
||||
bdev_statx(path, stat, request_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_getattr_nosec);
|
||||
|
@ -295,15 +308,6 @@ static int vfs_statx_path(struct path *path, int flags, struct kstat *stat,
|
|||
if (path_mounted(path))
|
||||
stat->attributes |= STATX_ATTR_MOUNT_ROOT;
|
||||
stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;
|
||||
|
||||
/*
|
||||
* If this is a block device inode, override the filesystem
|
||||
* attributes with the block device specific parameters that need to be
|
||||
* obtained from the bdev backing inode.
|
||||
*/
|
||||
if (S_ISBLK(stat->mode))
|
||||
bdev_statx(path, stat, request_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1685,7 +1685,7 @@ int sync_blockdev(struct block_device *bdev);
|
|||
int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend);
|
||||
int sync_blockdev_nowait(struct block_device *bdev);
|
||||
void sync_bdevs(bool wait);
|
||||
void bdev_statx(struct path *, struct kstat *, u32);
|
||||
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask);
|
||||
void printk_all_partitions(void);
|
||||
int __init early_lookup_bdev(const char *pathname, dev_t *dev);
|
||||
#else
|
||||
|
@ -1703,7 +1703,7 @@ static inline int sync_blockdev_nowait(struct block_device *bdev)
|
|||
static inline void sync_bdevs(bool wait)
|
||||
{
|
||||
}
|
||||
static inline void bdev_statx(struct path *path, struct kstat *stat,
|
||||
static inline void bdev_statx(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue