Skip to content

Commit 777d096

Browse files
Christoph Hellwigbrauner
authored andcommitted
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: 2d985f8 ("vfs: support STATX_DIOALIGN on block devices") Fixes: f4774e9 ("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>
1 parent 58db1c3 commit 777d096

File tree

3 files changed

+22
-19
lines changed

3 files changed

+22
-19
lines changed

block/bdev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,8 +1272,7 @@ void sync_bdevs(bool wait)
12721272
/*
12731273
* Handle STATX_{DIOALIGN, WRITE_ATOMIC} for block devices.
12741274
*/
1275-
void bdev_statx(struct path *path, struct kstat *stat,
1276-
u32 request_mask)
1275+
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask)
12771276
{
12781277
struct inode *backing_inode;
12791278
struct block_device *bdev;

fs/stat.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,25 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
204204
STATX_ATTR_DAX);
205205

206206
idmap = mnt_idmap(path->mnt);
207-
if (inode->i_op->getattr)
208-
return inode->i_op->getattr(idmap, path, stat,
209-
request_mask,
210-
query_flags);
207+
if (inode->i_op->getattr) {
208+
int ret;
209+
210+
ret = inode->i_op->getattr(idmap, path, stat, request_mask,
211+
query_flags);
212+
if (ret)
213+
return ret;
214+
} else {
215+
generic_fillattr(idmap, request_mask, inode, stat);
216+
}
217+
218+
/*
219+
* If this is a block device inode, override the filesystem attributes
220+
* with the block device specific parameters that need to be obtained
221+
* from the bdev backing inode.
222+
*/
223+
if (S_ISBLK(stat->mode))
224+
bdev_statx(path, stat, request_mask);
211225

212-
generic_fillattr(idmap, request_mask, inode, stat);
213226
return 0;
214227
}
215228
EXPORT_SYMBOL(vfs_getattr_nosec);
@@ -295,15 +308,6 @@ static int vfs_statx_path(struct path *path, int flags, struct kstat *stat,
295308
if (path_mounted(path))
296309
stat->attributes |= STATX_ATTR_MOUNT_ROOT;
297310
stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;
298-
299-
/*
300-
* If this is a block device inode, override the filesystem
301-
* attributes with the block device specific parameters that need to be
302-
* obtained from the bdev backing inode.
303-
*/
304-
if (S_ISBLK(stat->mode))
305-
bdev_statx(path, stat, request_mask);
306-
307311
return 0;
308312
}
309313

include/linux/blkdev.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,7 +1685,7 @@ int sync_blockdev(struct block_device *bdev);
16851685
int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend);
16861686
int sync_blockdev_nowait(struct block_device *bdev);
16871687
void sync_bdevs(bool wait);
1688-
void bdev_statx(struct path *, struct kstat *, u32);
1688+
void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask);
16891689
void printk_all_partitions(void);
16901690
int __init early_lookup_bdev(const char *pathname, dev_t *dev);
16911691
#else
@@ -1703,8 +1703,8 @@ static inline int sync_blockdev_nowait(struct block_device *bdev)
17031703
static inline void sync_bdevs(bool wait)
17041704
{
17051705
}
1706-
static inline void bdev_statx(struct path *path, struct kstat *stat,
1707-
u32 request_mask)
1706+
static inline void bdev_statx(const struct path *path, struct kstat *stat,
1707+
u32 request_mask)
17081708
{
17091709
}
17101710
static inline void printk_all_partitions(void)

0 commit comments

Comments
 (0)