Commit 5ad8b6ad authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'pull-set_blocksize' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs blocksize updates from Al Viro:
 "This gets rid of bogus set_blocksize() uses, switches it over
  to be based on a 'struct file *' and verifies that the caller
  has the device opened exclusively"

* tag 'pull-set_blocksize' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  make set_blocksize() fail unless block device is opened exclusive
  set_blocksize(): switch to passing struct file *
  btrfs_get_bdev_and_sb(): call set_blocksize() only for exclusive opens
  swsusp: don't bother with setting block size
  zram: don't bother with reopening - just use O_EXCL for open
  swapon(2): open swap with O_EXCL
  swapon(2)/swapoff(2): don't bother with block size
  pktcdvd: sort set_blocksize() calls out
  bcache_register(): don't bother with set_blocksize()
parents db3d841a d18a8679
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1134,3 +1134,10 @@ superblock of the main block device, i.e., the one stored in sb->s_bdev. Block
device freezing now works for any block device owned by a given superblock, not
just the main block device. The get_active_super() helper and bd_fsfreeze_sb
pointer are gone.

---

**mandatory**

set_blocksize() takes opened struct file instead of struct block_device now
and it *must* be opened exclusive.
+10 −4
Original line number Diff line number Diff line
@@ -144,8 +144,11 @@ static void set_init_blocksize(struct block_device *bdev)
	bdev->bd_inode->i_blkbits = blksize_bits(bsize);
}

int set_blocksize(struct block_device *bdev, int size)
int set_blocksize(struct file *file, int size)
{
	struct inode *inode = file->f_mapping->host;
	struct block_device *bdev = I_BDEV(inode);

	/* Size must be a power of two, and between 512 and PAGE_SIZE */
	if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
		return -EINVAL;
@@ -154,10 +157,13 @@ int set_blocksize(struct block_device *bdev, int size)
	if (size < bdev_logical_block_size(bdev))
		return -EINVAL;

	if (!file->private_data)
		return -EINVAL;

	/* Don't change the size if it is same as current */
	if (bdev->bd_inode->i_blkbits != blksize_bits(size)) {
	if (inode->i_blkbits != blksize_bits(size)) {
		sync_blockdev(bdev);
		bdev->bd_inode->i_blkbits = blksize_bits(size);
		inode->i_blkbits = blksize_bits(size);
		kill_bdev(bdev);
	}
	return 0;
@@ -167,7 +173,7 @@ EXPORT_SYMBOL(set_blocksize);

int sb_set_blocksize(struct super_block *sb, int size)
{
	if (set_blocksize(sb->s_bdev, size))
	if (set_blocksize(sb->s_bdev_file, size))
		return 0;
	/* If we get here, we know size is power of two
	 * and it's value is between 512 and PAGE_SIZE */
+12 −9
Original line number Diff line number Diff line
@@ -503,11 +503,14 @@ static int compat_hdio_getgeo(struct block_device *bdev,
#endif

/* set the logical block size */
static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
static int blkdev_bszset(struct file *file, blk_mode_t mode,
		int __user *argp)
{
	// this one might be file_inode(file)->i_rdev - a rare valid
	// use of file_inode() for those.
	dev_t dev = I_BDEV(file->f_mapping->host)->bd_dev;
	struct file *excl_file;
	int ret, n;
	struct file *file;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
@@ -517,13 +520,13 @@ static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
		return -EFAULT;

	if (mode & BLK_OPEN_EXCL)
		return set_blocksize(bdev, n);
		return set_blocksize(file, n);

	file = bdev_file_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
	if (IS_ERR(file))
	excl_file = bdev_file_open_by_dev(dev, mode, &dev, NULL);
	if (IS_ERR(excl_file))
		return -EBUSY;
	ret = set_blocksize(bdev, n);
	fput(file);
	ret = set_blocksize(excl_file, n);
	fput(excl_file);
	return ret;
}

@@ -652,7 +655,7 @@ long blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
		return put_int(argp, block_size(bdev));
	case BLKBSZSET:
		return blkdev_bszset(bdev, mode, argp);
		return blkdev_bszset(file, mode, argp);
	case BLKGETSIZE64:
		return put_u64(argp, bdev_nr_bytes(bdev));

@@ -712,7 +715,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
		return put_int(argp, bdev_logical_block_size(bdev));
	case BLKBSZSET_32:
		return blkdev_bszset(bdev, mode, argp);
		return blkdev_bszset(file, mode, argp);
	case BLKGETSIZE64_32:
		return put_u64(argp, bdev_nr_bytes(bdev));

+1 −6
Original line number Diff line number Diff line
@@ -2215,6 +2215,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, bool write)
		}
		dev_info(ddev, "%lukB available on disc\n", lba << 1);
	}
	set_blocksize(bdev_file, CD_FRAMESIZE);

	return 0;

@@ -2278,11 +2279,6 @@ static int pkt_open(struct gendisk *disk, blk_mode_t mode)
		ret = pkt_open_dev(pd, mode & BLK_OPEN_WRITE);
		if (ret)
			goto out_dec;
		/*
		 * needed here as well, since ext2 (among others) may change
		 * the blocksize at mount time
		 */
		set_blocksize(disk->part0, CD_FRAMESIZE);
	}
	mutex_unlock(&ctl_mutex);
	mutex_unlock(&pktcdvd_mutex);
@@ -2526,7 +2522,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
	__module_get(THIS_MODULE);

	pd->bdev_file = bdev_file;
	set_blocksize(file_bdev(bdev_file), CD_FRAMESIZE);

	atomic_set(&pd->cdrw.pending_bios, 0);
	pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->disk->disk_name);
+7 −22
Original line number Diff line number Diff line
@@ -426,11 +426,10 @@ static void reset_bdev(struct zram *zram)
	if (!zram->backing_dev)
		return;

	fput(zram->bdev_file);
	/* hope filp_close flush all of IO */
	filp_close(zram->backing_dev, NULL);
	zram->backing_dev = NULL;
	zram->bdev_file = NULL;
	zram->bdev = NULL;
	zram->disk->fops = &zram_devops;
	kvfree(zram->bitmap);
	zram->bitmap = NULL;
@@ -473,10 +472,8 @@ static ssize_t backing_dev_store(struct device *dev,
	size_t sz;
	struct file *backing_dev = NULL;
	struct inode *inode;
	struct address_space *mapping;
	unsigned int bitmap_sz;
	unsigned long nr_pages, *bitmap = NULL;
	struct file *bdev_file = NULL;
	int err;
	struct zram *zram = dev_to_zram(dev);

@@ -497,15 +494,14 @@ static ssize_t backing_dev_store(struct device *dev,
	if (sz > 0 && file_name[sz - 1] == '\n')
		file_name[sz - 1] = 0x00;

	backing_dev = filp_open(file_name, O_RDWR|O_LARGEFILE, 0);
	backing_dev = filp_open(file_name, O_RDWR | O_LARGEFILE | O_EXCL, 0);
	if (IS_ERR(backing_dev)) {
		err = PTR_ERR(backing_dev);
		backing_dev = NULL;
		goto out;
	}

	mapping = backing_dev->f_mapping;
	inode = mapping->host;
	inode = backing_dev->f_mapping->host;

	/* Support only block device in this moment */
	if (!S_ISBLK(inode->i_mode)) {
@@ -513,14 +509,6 @@ static ssize_t backing_dev_store(struct device *dev,
		goto out;
	}

	bdev_file = bdev_file_open_by_dev(inode->i_rdev,
				BLK_OPEN_READ | BLK_OPEN_WRITE, zram, NULL);
	if (IS_ERR(bdev_file)) {
		err = PTR_ERR(bdev_file);
		bdev_file = NULL;
		goto out;
	}

	nr_pages = i_size_read(inode) >> PAGE_SHIFT;
	bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long);
	bitmap = kvzalloc(bitmap_sz, GFP_KERNEL);
@@ -531,7 +519,7 @@ static ssize_t backing_dev_store(struct device *dev,

	reset_bdev(zram);

	zram->bdev_file = bdev_file;
	zram->bdev = I_BDEV(inode);
	zram->backing_dev = backing_dev;
	zram->bitmap = bitmap;
	zram->nr_pages = nr_pages;
@@ -544,9 +532,6 @@ static ssize_t backing_dev_store(struct device *dev,
out:
	kvfree(bitmap);

	if (bdev_file)
		fput(bdev_file);

	if (backing_dev)
		filp_close(backing_dev, NULL);

@@ -587,7 +572,7 @@ static void read_from_bdev_async(struct zram *zram, struct page *page,
{
	struct bio *bio;

	bio = bio_alloc(file_bdev(zram->bdev_file), 1, parent->bi_opf, GFP_NOIO);
	bio = bio_alloc(zram->bdev, 1, parent->bi_opf, GFP_NOIO);
	bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9);
	__bio_add_page(bio, page, PAGE_SIZE, 0);
	bio_chain(bio, parent);
@@ -703,7 +688,7 @@ static ssize_t writeback_store(struct device *dev,
			continue;
		}

		bio_init(&bio, file_bdev(zram->bdev_file), &bio_vec, 1,
		bio_init(&bio, zram->bdev, &bio_vec, 1,
			 REQ_OP_WRITE | REQ_SYNC);
		bio.bi_iter.bi_sector = blk_idx * (PAGE_SIZE >> 9);
		__bio_add_page(&bio, page, PAGE_SIZE, 0);
@@ -785,7 +770,7 @@ static void zram_sync_read(struct work_struct *work)
	struct bio_vec bv;
	struct bio bio;

	bio_init(&bio, file_bdev(zw->zram->bdev_file), &bv, 1, REQ_OP_READ);
	bio_init(&bio, zw->zram->bdev, &bv, 1, REQ_OP_READ);
	bio.bi_iter.bi_sector = zw->entry * (PAGE_SIZE >> 9);
	__bio_add_page(&bio, zw->page, PAGE_SIZE, 0);
	zw->error = submit_bio_wait(&bio);
Loading