From: "Darrick J. Wong" djwong@kernel.org
[ Upstream commit e03463d247ddac66e71143468373df3d74a3a6bd ]
Hoist the block size validation code to bdev_validate_blocksize so that we can call it from filesystems that don't care about the bdev pagecache manipulations of set_blocksize.
Signed-off-by: Darrick J. Wong djwong@kernel.org Reviewed-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/174543795720.4139148.840349813093799165.stgit@frog... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bdev.c | 33 +++++++++++++++++++++++++++------ include/linux/blkdev.h | 1 + 2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c index 06b8cab31d759..e5af18bc43082 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -150,18 +150,39 @@ static void set_init_blocksize(struct block_device *bdev) BD_INODE(bdev)->i_blkbits = blksize_bits(bsize); }
-int set_blocksize(struct file *file, int size) +/** + * bdev_validate_blocksize - check that this block size is acceptable + * @bdev: blockdevice to check + * @block_size: block size to check + * + * For block device users that do not use buffer heads or the block device + * page cache, make sure that this block size can be used with the device. + * + * Return: On success zero is returned, negative error code on failure. + */ +int bdev_validate_blocksize(struct block_device *bdev, int block_size) { - struct inode *inode = file->f_mapping->host; - struct block_device *bdev = I_BDEV(inode); - - if (blk_validate_block_size(size)) + if (blk_validate_block_size(block_size)) return -EINVAL;
/* Size cannot be smaller than the size supported by the device */ - if (size < bdev_logical_block_size(bdev)) + if (block_size < bdev_logical_block_size(bdev)) return -EINVAL;
+ return 0; +} +EXPORT_SYMBOL_GPL(bdev_validate_blocksize); + +int set_blocksize(struct file *file, int size) +{ + struct inode *inode = file->f_mapping->host; + struct block_device *bdev = I_BDEV(inode); + int ret; + + ret = bdev_validate_blocksize(bdev, size); + if (ret) + return ret; + if (!file->private_data) return -EINVAL;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d37751789bf58..ef98bcca7f5f7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1593,6 +1593,7 @@ static inline void bio_end_io_acct(struct bio *bio, unsigned long start_time) return bio_end_io_acct_remapped(bio, start_time, bio->bi_bdev); }
+int bdev_validate_blocksize(struct block_device *bdev, int block_size); int set_blocksize(struct file *file, int size);
int lookup_bdev(const char *pathname, dev_t *dev);