Commit 236f4532 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull misc vfs updates from Al Viro:

 - bmap series from cmaiolino

 - getting rid of convolutions in copy_mount_options() (use a couple of
   copy_from_user() instead of the __get_user() crap)

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  saner copy_mount_options()
  fibmap: Reject negative block numbers
  fibmap: Use bmap instead of ->bmap method in ioctl_fibmap
  ecryptfs: drop direct calls to ->bmap
  cachefiles: drop direct usage of ->bmap method.
  fs: Enable bmap() function to properly return errors
parents 99593330 12efec56
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -364,7 +364,7 @@ static int read_page(struct file *file, unsigned long index,
	int ret = 0;
	struct inode *inode = file_inode(file);
	struct buffer_head *bh;
	sector_t block;
	sector_t block, blk_cur;

	pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
		 (unsigned long long)index << PAGE_SHIFT);
@@ -375,17 +375,21 @@ static int read_page(struct file *file, unsigned long index,
		goto out;
	}
	attach_page_buffers(page, bh);
	block = index << (PAGE_SHIFT - inode->i_blkbits);
	blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
	while (bh) {
		block = blk_cur;

		if (count == 0)
			bh->b_blocknr = 0;
		else {
			bh->b_blocknr = bmap(inode, block);
			if (bh->b_blocknr == 0) {
				/* Cannot use this file! */
			ret = bmap(inode, &block);
			if (ret || !block) {
				ret = -EINVAL;
				bh->b_blocknr = 0;
				goto out;
			}

			bh->b_blocknr = block;
			bh->b_bdev = inode->i_sb->s_bdev;
			if (count < (1<<inode->i_blkbits))
				count = 0;
@@ -399,7 +403,7 @@ static int read_page(struct file *file, unsigned long index,
			set_buffer_mapped(bh);
			submit_bh(REQ_OP_READ, 0, bh);
		}
		block++;
		blk_cur++;
		bh = bh->b_this_page;
	}
	page->index = index;
+14 −13
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
	struct cachefiles_object *object;
	struct cachefiles_cache *cache;
	struct inode *inode;
	sector_t block0, block;
	sector_t block;
	unsigned shift;
	int ret;

@@ -412,7 +412,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,

	inode = d_backing_inode(object->backer);
	ASSERT(S_ISREG(inode->i_mode));
	ASSERT(inode->i_mapping->a_ops->bmap);
	ASSERT(inode->i_mapping->a_ops->readpages);

	/* calculate the shift required to use bmap */
@@ -428,12 +427,14 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
	 *   enough for this as it doesn't indicate errors, but it's all we've
	 *   got for the moment
	 */
	block0 = page->index;
	block0 <<= shift;
	block = page->index;
	block <<= shift;

	ret = bmap(inode, &block);
	ASSERT(ret < 0);

	block = inode->i_mapping->a_ops->bmap(inode->i_mapping, block0);
	_debug("%llx -> %llx",
	       (unsigned long long) block0,
	       (unsigned long long) (page->index << shift),
	       (unsigned long long) block);

	if (block) {
@@ -711,7 +712,6 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,

	inode = d_backing_inode(object->backer);
	ASSERT(S_ISREG(inode->i_mode));
	ASSERT(inode->i_mapping->a_ops->bmap);
	ASSERT(inode->i_mapping->a_ops->readpages);

	/* calculate the shift required to use bmap */
@@ -728,7 +728,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,

	ret = space ? -ENODATA : -ENOBUFS;
	list_for_each_entry_safe(page, _n, pages, lru) {
		sector_t block0, block;
		sector_t block;

		/* we assume the absence or presence of the first block is a
		 * good enough indication for the page as a whole
@@ -736,13 +736,14 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
		 *   good enough for this as it doesn't indicate errors, but
		 *   it's all we've got for the moment
		 */
		block0 = page->index;
		block0 <<= shift;
		block = page->index;
		block <<= shift;

		ret = bmap(inode, &block);
		ASSERT(!ret);

		block = inode->i_mapping->a_ops->bmap(inode->i_mapping,
						      block0);
		_debug("%llx -> %llx",
		       (unsigned long long) block0,
		       (unsigned long long) (page->index << shift),
		       (unsigned long long) block);

		if (block) {
+6 −10
Original line number Diff line number Diff line
@@ -524,16 +524,12 @@ out:

static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
{
	int rc = 0;
	struct inode *inode;
	struct inode *lower_inode;

	inode = (struct inode *)mapping->host;
	lower_inode = ecryptfs_inode_to_lower(inode);
	if (lower_inode->i_mapping->a_ops->bmap)
		rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping,
							 block);
	return rc;
	struct inode *lower_inode = ecryptfs_inode_to_lower(mapping->host);
	int ret = bmap(lower_inode, &block);

	if (ret)
		return 0;
	return block;
}

const struct address_space_operations ecryptfs_aops = {
+11 −5
Original line number Diff line number Diff line
@@ -3666,12 +3666,16 @@ static int check_swap_activate(struct swap_info_struct *sis,
			page_no < sis->max) {
		unsigned block_in_page;
		sector_t first_block;
		sector_t block = 0;
		int	 err = 0;

		cond_resched();

		first_block = bmap(inode, probe_block);
		if (first_block == 0)
		block = probe_block;
		err = bmap(inode, &block);
		if (err || !block)
			goto bad_bmap;
		first_block = block;

		/*
		 * It must be PAGE_SIZE aligned on-disk
@@ -3683,11 +3687,13 @@ static int check_swap_activate(struct swap_info_struct *sis,

		for (block_in_page = 1; block_in_page < blocks_per_page;
					block_in_page++) {
			sector_t block;

			block = bmap(inode, probe_block + block_in_page);
			if (block == 0)
			block = probe_block + block_in_page;
			err = bmap(inode, &block);

			if (err || !block)
				goto bad_bmap;

			if (block != first_block + block_in_page) {
				/* Discontiguity */
				probe_block++;
+19 −13
Original line number Diff line number Diff line
@@ -1599,25 +1599,31 @@ retry:
}
EXPORT_SYMBOL(iput);

#ifdef CONFIG_BLOCK
/**
 *	bmap	- find a block number in a file
 *	@inode: inode of file
 *	@block: block to find
 *	@inode:  inode owning the block number being requested
 *	@block: pointer containing the block to find
 *
 *	Returns the block number on the device holding the inode that
 *	is the disk block number for the block of the file requested.
 *	That is, asked for block 4 of inode 1 the function will return the
 *	disk block relative to the disk start that holds that block of the
 *	file.
 *	Replaces the value in *block with the block number on the device holding
 *	corresponding to the requested block number in the file.
 *	That is, asked for block 4 of inode 1 the function will replace the
 *	4 in *block, with disk block relative to the disk start that holds that
 *	block of the file.
 *
 *	Returns -EINVAL in case of error, 0 otherwise. If mapping falls into a
 *	hole, returns 0 and *block is also set to 0.
 */
sector_t bmap(struct inode *inode, sector_t block)
int bmap(struct inode *inode, sector_t *block)
{
	sector_t res = 0;
	if (inode->i_mapping->a_ops->bmap)
		res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);
	return res;
	if (!inode->i_mapping->a_ops->bmap)
		return -EINVAL;

	*block = inode->i_mapping->a_ops->bmap(inode->i_mapping, *block);
	return 0;
}
EXPORT_SYMBOL(bmap);
#endif

/*
 * With relative atime, only update atime if the previous atime is
Loading