All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Carlos Maiolino <cmaiolino@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, hch@lst.de, sandeen@redhat.com,
	david@fromorbit.com
Subject: Re: [PATCH 1/3] fs: Enable bmap() function to properly return errors
Date: Mon, 17 Sep 2018 13:55:41 -0700	[thread overview]
Message-ID: <20180917205541.GA4591@magnolia> (raw)
In-Reply-To: <20180912122536.31977-2-cmaiolino@redhat.com>

On Wed, Sep 12, 2018 at 02:25:34PM +0200, Carlos Maiolino wrote:
> By now, bmap() will either return the physical block number related to
> the requested file offset or 0 in case of error or the requested offset
> maps into a hole.
> This patch makes the needed changes to enable bmap() to proper return
> errors, using the return value as an error return, and now, a pointer
> must be passed to bmap() to be filled with the mapped physical block.
> 
> It will change the behavior of bmap() on return:
> 
> - negative value in case of error
> - zero on success or if map fell into a hole
> 
> In case of a hole, the *block will be zero too
> 
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
> 
> P.S. Since this is a prep patch, by now, the only error return is -EINVAL if
> ->bmap doesn't exist.
> 
>  drivers/md/md-bitmap.c | 16 ++++++++++------
>  fs/inode.c             | 30 +++++++++++++++++-------------
>  fs/jbd2/journal.c      | 22 +++++++++++++++-------
>  include/linux/fs.h     |  2 +-
>  mm/page_io.c           | 11 +++++++----
>  5 files changed, 50 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
> index 2fc8c113977f..0bbd55f45b25 100644
> --- a/drivers/md/md-bitmap.c
> +++ b/drivers/md/md-bitmap.c
> @@ -363,7 +363,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);
> @@ -374,17 +374,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;
> @@ -398,7 +402,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;
> diff --git a/fs/inode.c b/fs/inode.c
> index 41812a3e829e..99154ce81cd9 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -1577,21 +1577,25 @@ EXPORT_SYMBOL(iput);
>  
>  /**
>   *	bmap	- find a block number in a file
> - *	@inode: inode of file
> - *	@block: 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.
> + *	@inode:  inode owning the block number being requested
> + *	@*block: pointer containing the block to find
> + *
> + *	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);

Hm.  Could we change the aops ->bmap interface to return negative error
codes too?

Also... ioctl_fibmap blindly copies the bottom 32 bits of *block out to
userspace without checking for overflows.  Shouldn't that also be
changed?

--D

> +	return 0;
>  }
>  EXPORT_SYMBOL(bmap);
>  
> diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
> index 8ef6b6daaa7a..7acaf6f55404 100644
> --- a/fs/jbd2/journal.c
> +++ b/fs/jbd2/journal.c
> @@ -814,18 +814,23 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
>  {
>  	int err = 0;
>  	unsigned long long ret;
> +	sector_t block = 0;
>  
>  	if (journal->j_inode) {
> -		ret = bmap(journal->j_inode, blocknr);
> -		if (ret)
> -			*retp = ret;
> -		else {
> +		block = blocknr;
> +		ret = bmap(journal->j_inode, &block);
> +
> +		if (ret || !block) {
>  			printk(KERN_ALERT "%s: journal block not found "
>  					"at offset %lu on %s\n",
>  			       __func__, blocknr, journal->j_devname);
>  			err = -EIO;
>  			__journal_abort_soft(journal, err);
> +
> +		} else {
> +			*retp = block;
>  		}
> +
>  	} else {
>  		*retp = blocknr; /* +journal->j_blk_offset */
>  	}
> @@ -1251,11 +1256,14 @@ journal_t *jbd2_journal_init_dev(struct block_device *bdev,
>  journal_t *jbd2_journal_init_inode(struct inode *inode)
>  {
>  	journal_t *journal;
> +	sector_t blocknr;
>  	char *p;
> -	unsigned long long blocknr;
> +	int err = 0;
> +
> +	blocknr = 0;
> +	err = bmap(inode, &blocknr);
>  
> -	blocknr = bmap(inode, 0);
> -	if (!blocknr) {
> +	if (err || !blocknr) {
>  		pr_err("%s: Cannot locate journal superblock\n",
>  			__func__);
>  		return NULL;
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index bf0cad65b9b7..15a79f67ad87 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2762,7 +2762,7 @@ static inline ssize_t generic_write_sync(struct kiocb *iocb, ssize_t count)
>  extern void emergency_sync(void);
>  extern void emergency_remount(void);
>  #ifdef CONFIG_BLOCK
> -extern sector_t bmap(struct inode *, sector_t);
> +extern int bmap(struct inode *, sector_t *);
>  #endif
>  extern int notify_change(struct dentry *, struct iattr *, struct inode **);
>  extern int inode_permission(struct inode *, int);
> diff --git a/mm/page_io.c b/mm/page_io.c
> index aafd19ec1db4..994c996414c3 100644
> --- a/mm/page_io.c
> +++ b/mm/page_io.c
> @@ -177,8 +177,9 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
>  
>  		cond_resched();
>  
> -		first_block = bmap(inode, probe_block);
> -		if (first_block == 0)
> +		first_block = probe_block;
> +		ret = bmap(inode, &first_block);
> +		if (ret || !first_block)
>  			goto bad_bmap;
>  
>  		/*
> @@ -193,9 +194,11 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
>  					block_in_page++) {
>  			sector_t block;
>  
> -			block = bmap(inode, probe_block + block_in_page);
> -			if (block == 0)
> +			block = probe_block + block_in_page;
> +			ret = bmap(inode, &block);
> +			if (ret || !block)
>  				goto bad_bmap;
> +
>  			if (block != first_block + block_in_page) {
>  				/* Discontiguity */
>  				probe_block++;
> -- 
> 2.14.4
> 

  parent reply	other threads:[~2018-09-18  2:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-12 12:25 [PATCH 0/3] Replace direct ->bmap calls by bmap() with error support Carlos Maiolino
2018-09-12 12:25 ` [PATCH 1/3] fs: Enable bmap() function to properly return errors Carlos Maiolino
2018-09-14 13:23   ` Christoph Hellwig
2018-09-14 18:48     ` Carlos Maiolino
2018-09-17 20:55   ` Darrick J. Wong [this message]
2018-09-18  6:00     ` Carlos Maiolino
2018-09-12 12:25 ` [PATCH 2/3] cachefiles: drop direct usage of ->bmap method Carlos Maiolino
2018-09-14 13:23   ` Christoph Hellwig
2018-09-14 18:56     ` Carlos Maiolino
2018-09-12 12:25 ` [PATCH 3/3] ecryptfs: drop direct calls to ->bmap Carlos Maiolino
2018-09-14 13:26   ` Christoph Hellwig
2018-09-14 18:47     ` Carlos Maiolino
2018-09-17 11:04   ` [PATCH 3/3 V2] " Carlos Maiolino

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180917205541.GA4591@magnolia \
    --to=darrick.wong@oracle.com \
    --cc=cmaiolino@redhat.com \
    --cc=david@fromorbit.com \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.