On Wed, Apr 23, 2025 at 04:43:06PM +0200, Greg Kroah-Hartman wrote:
6.14-stable review patch. If anyone has any objections, please let me know.
You might want to hold this patch (for 6.14 and 6.12) until "devtmpfs: don't use vfs_getattr_nosec to query i_mode" lands, since (AFAICT) it's needed to fix a hang introduced by this patch.
(Unless that's already queued for stable, but afaict it isn't)
--D
From: Christoph Hellwig hch@lst.de
[ Upstream commit 777d0961ff95b26d5887fdae69900374364976f3 ]
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: 2d985f8c6b91 ("vfs: support STATX_DIOALIGN on block devices") Fixes: f4774e92aab8 ("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 Signed-off-by: Sasha Levin sashal@kernel.org
block/bdev.c | 3 +-- fs/stat.c | 32 ++++++++++++++++++-------------- include/linux/blkdev.h | 6 +++--- 3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c index 9d73a8fbf7f99..e5147cab21b21 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -1268,8 +1268,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; diff --git a/fs/stat.c b/fs/stat.c index f13308bfdc983..3d9222807214a 100644 --- a/fs/stat.c +++ b/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);
- generic_fillattr(idmap, request_mask, inode, stat); 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;
} diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d37751789bf58..38fc78501ef2d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1664,7 +1664,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 @@ -1682,8 +1682,8 @@ 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,
u32 request_mask)
+static inline void bdev_statx(const struct path *path, struct kstat *stat,
u32 request_mask)
{ } static inline void printk_all_partitions(void) -- 2.39.5