@@ -152,27 +152,65 @@ static void set_init_blocksize(struct block_device *bdev)
152152 get_order (bsize ));
153153}
154154
155- int set_blocksize (struct file * file , int size )
155+ /**
156+ * bdev_validate_blocksize - check that this block size is acceptable
157+ * @bdev: blockdevice to check
158+ * @block_size: block size to check
159+ *
160+ * For block device users that do not use buffer heads or the block device
161+ * page cache, make sure that this block size can be used with the device.
162+ *
163+ * Return: On success zero is returned, negative error code on failure.
164+ */
165+ int bdev_validate_blocksize (struct block_device * bdev , int block_size )
156166{
157- struct inode * inode = file -> f_mapping -> host ;
158- struct block_device * bdev = I_BDEV (inode );
159-
160- if (blk_validate_block_size (size ))
167+ if (blk_validate_block_size (block_size ))
161168 return - EINVAL ;
162169
163170 /* Size cannot be smaller than the size supported by the device */
164- if (size < bdev_logical_block_size (bdev ))
171+ if (block_size < bdev_logical_block_size (bdev ))
165172 return - EINVAL ;
166173
174+ return 0 ;
175+ }
176+ EXPORT_SYMBOL_GPL (bdev_validate_blocksize );
177+
178+ int set_blocksize (struct file * file , int size )
179+ {
180+ struct inode * inode = file -> f_mapping -> host ;
181+ struct block_device * bdev = I_BDEV (inode );
182+ int ret ;
183+
184+ ret = bdev_validate_blocksize (bdev , size );
185+ if (ret )
186+ return ret ;
187+
167188 if (!file -> private_data )
168189 return - EINVAL ;
169190
170191 /* Don't change the size if it is same as current */
171192 if (inode -> i_blkbits != blksize_bits (size )) {
193+ /*
194+ * Flush and truncate the pagecache before we reconfigure the
195+ * mapping geometry because folio sizes are variable now. If a
196+ * reader has already allocated a folio whose size is smaller
197+ * than the new min_order but invokes readahead after the new
198+ * min_order becomes visible, readahead will think there are
199+ * "zero" blocks per folio and crash. Take the inode and
200+ * invalidation locks to avoid racing with
201+ * read/write/fallocate.
202+ */
203+ inode_lock (inode );
204+ filemap_invalidate_lock (inode -> i_mapping );
205+
172206 sync_blockdev (bdev );
207+ kill_bdev (bdev );
208+
173209 inode -> i_blkbits = blksize_bits (size );
174210 mapping_set_folio_min_order (inode -> i_mapping , get_order (size ));
175211 kill_bdev (bdev );
212+ filemap_invalidate_unlock (inode -> i_mapping );
213+ inode_unlock (inode );
176214 }
177215 return 0 ;
178216}
@@ -777,13 +815,13 @@ static void blkdev_put_part(struct block_device *part)
777815 blkdev_put_whole (whole );
778816}
779817
780- struct block_device * blkdev_get_no_open (dev_t dev )
818+ struct block_device * blkdev_get_no_open (dev_t dev , bool autoload )
781819{
782820 struct block_device * bdev ;
783821 struct inode * inode ;
784822
785823 inode = ilookup (blockdev_superblock , dev );
786- if (!inode && IS_ENABLED (CONFIG_BLOCK_LEGACY_AUTOLOAD )) {
824+ if (!inode && autoload && IS_ENABLED (CONFIG_BLOCK_LEGACY_AUTOLOAD )) {
787825 blk_request_module (dev );
788826 inode = ilookup (blockdev_superblock , dev );
789827 if (inode )
@@ -1005,7 +1043,7 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
10051043 if (ret )
10061044 return ERR_PTR (ret );
10071045
1008- bdev = blkdev_get_no_open (dev );
1046+ bdev = blkdev_get_no_open (dev , true );
10091047 if (!bdev )
10101048 return ERR_PTR (- ENXIO );
10111049
@@ -1275,18 +1313,15 @@ void sync_bdevs(bool wait)
12751313void bdev_statx (struct path * path , struct kstat * stat ,
12761314 u32 request_mask )
12771315{
1278- struct inode * backing_inode ;
12791316 struct block_device * bdev ;
12801317
1281- backing_inode = d_backing_inode (path -> dentry );
1282-
12831318 /*
1284- * Note that backing_inode is the inode of a block device node file,
1285- * not the block device's internal inode. Therefore it is *not* valid
1286- * to use I_BDEV() here; the block device has to be looked up by i_rdev
1319+ * Note that d_backing_inode() returns the block device node inode, not
1320+ * the block device's internal inode. Therefore it is *not* valid to
1321+ * use I_BDEV() here; the block device has to be looked up by i_rdev
12871322 * instead.
12881323 */
1289- bdev = blkdev_get_no_open (backing_inode -> i_rdev );
1324+ bdev = blkdev_get_no_open (d_backing_inode ( path -> dentry ) -> i_rdev , false );
12901325 if (!bdev )
12911326 return ;
12921327
0 commit comments