diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 82 | 
1 files changed, 42 insertions, 40 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ef3c98c527c1..556c93060606 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -842,13 +842,12 @@ retry:  				NULL, EXTENT_LOCKED | EXTENT_DELALLOC,  				PAGE_UNLOCK | PAGE_CLEAR_DIRTY |  				PAGE_SET_WRITEBACK); -		ret = btrfs_submit_compressed_write(inode, +		if (btrfs_submit_compressed_write(inode,  				    async_extent->start,  				    async_extent->ram_size,  				    ins.objectid,  				    ins.offset, async_extent->pages, -				    async_extent->nr_pages); -		if (ret) { +				    async_extent->nr_pages)) {  			struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;  			struct page *p = async_extent->pages[0];  			const u64 start = async_extent->start; @@ -1901,11 +1900,11 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,   * At IO completion time the cums attached on the ordered extent record   * are inserted into the btree   */ -static int __btrfs_submit_bio_start(struct inode *inode, struct bio *bio, -				    int mirror_num, unsigned long bio_flags, -				    u64 bio_offset) +static blk_status_t __btrfs_submit_bio_start(struct inode *inode, +		struct bio *bio, int mirror_num, unsigned long bio_flags, +		u64 bio_offset)  { -	int ret = 0; +	blk_status_t ret = 0;  	ret = btrfs_csum_one_bio(inode, bio, 0, 0);  	BUG_ON(ret); /* -ENOMEM */ @@ -1920,16 +1919,16 @@ static int __btrfs_submit_bio_start(struct inode *inode, struct bio *bio,   * At IO completion time the cums attached on the ordered extent record   * are inserted into the btree   */ -static int __btrfs_submit_bio_done(struct inode *inode, struct bio *bio, -			  int mirror_num, unsigned long bio_flags, -			  u64 bio_offset) +static blk_status_t __btrfs_submit_bio_done(struct inode *inode, +		struct bio *bio, int mirror_num, unsigned long bio_flags, +		u64 bio_offset)  {  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -	int ret; +	blk_status_t ret;  	ret = btrfs_map_bio(fs_info, bio, mirror_num, 1);  	if (ret) { -		bio->bi_error = ret; +		bio->bi_status = ret;  		bio_endio(bio);  	}  	return ret; @@ -1939,14 +1938,14 @@ static int __btrfs_submit_bio_done(struct inode *inode, struct bio *bio,   * extent_io.c submission hook. This does the right thing for csum calculation   * on write, or reading the csums from the tree before a read   */ -static int btrfs_submit_bio_hook(struct inode *inode, struct bio *bio, +static blk_status_t btrfs_submit_bio_hook(struct inode *inode, struct bio *bio,  			  int mirror_num, unsigned long bio_flags,  			  u64 bio_offset)  {  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_root *root = BTRFS_I(inode)->root;  	enum btrfs_wq_endio_type metadata = BTRFS_WQ_ENDIO_DATA; -	int ret = 0; +	blk_status_t ret = 0;  	int skip_sum;  	int async = !atomic_read(&BTRFS_I(inode)->sync_writers); @@ -1991,8 +1990,8 @@ mapit:  	ret = btrfs_map_bio(fs_info, bio, mirror_num, 0);  out: -	if (ret < 0) { -		bio->bi_error = ret; +	if (ret) { +		bio->bi_status = ret;  		bio_endio(bio);  	}  	return ret; @@ -8037,7 +8036,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)  	struct bio_vec *bvec;  	int i; -	if (bio->bi_error) +	if (bio->bi_status)  		goto end;  	ASSERT(bio->bi_vcnt == 1); @@ -8116,7 +8115,7 @@ static void btrfs_retry_endio(struct bio *bio)  	int ret;  	int i; -	if (bio->bi_error) +	if (bio->bi_status)  		goto end;  	uptodate = 1; @@ -8141,8 +8140,8 @@ end:  	bio_put(bio);  } -static int __btrfs_subio_endio_read(struct inode *inode, -				    struct btrfs_io_bio *io_bio, int err) +static blk_status_t __btrfs_subio_endio_read(struct inode *inode, +		struct btrfs_io_bio *io_bio, blk_status_t err)  {  	struct btrfs_fs_info *fs_info;  	struct bio_vec *bvec; @@ -8184,7 +8183,7 @@ try_again:  				io_bio->mirror_num,  				btrfs_retry_endio, &done);  		if (ret) { -			err = ret; +			err = errno_to_blk_status(ret);  			goto next;  		} @@ -8211,8 +8210,8 @@ next:  	return err;  } -static int btrfs_subio_endio_read(struct inode *inode, -				  struct btrfs_io_bio *io_bio, int err) +static blk_status_t btrfs_subio_endio_read(struct inode *inode, +		struct btrfs_io_bio *io_bio, blk_status_t err)  {  	bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; @@ -8232,7 +8231,7 @@ static void btrfs_endio_direct_read(struct bio *bio)  	struct inode *inode = dip->inode;  	struct bio *dio_bio;  	struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); -	int err = bio->bi_error; +	blk_status_t err = bio->bi_status;  	if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)  		err = btrfs_subio_endio_read(inode, io_bio, err); @@ -8243,11 +8242,11 @@ static void btrfs_endio_direct_read(struct bio *bio)  	kfree(dip); -	dio_bio->bi_error = bio->bi_error; -	dio_end_io(dio_bio, bio->bi_error); +	dio_bio->bi_status = bio->bi_status; +	dio_end_io(dio_bio);  	if (io_bio->end_io) -		io_bio->end_io(io_bio, err); +		io_bio->end_io(io_bio, blk_status_to_errno(err));  	bio_put(bio);  } @@ -8299,20 +8298,20 @@ static void btrfs_endio_direct_write(struct bio *bio)  	struct bio *dio_bio = dip->dio_bio;  	__endio_write_update_ordered(dip->inode, dip->logical_offset, -				     dip->bytes, !bio->bi_error); +				     dip->bytes, !bio->bi_status);  	kfree(dip); -	dio_bio->bi_error = bio->bi_error; -	dio_end_io(dio_bio, bio->bi_error); +	dio_bio->bi_status = bio->bi_status; +	dio_end_io(dio_bio);  	bio_put(bio);  } -static int __btrfs_submit_bio_start_direct_io(struct inode *inode, +static blk_status_t __btrfs_submit_bio_start_direct_io(struct inode *inode,  				    struct bio *bio, int mirror_num,  				    unsigned long bio_flags, u64 offset)  { -	int ret; +	blk_status_t ret;  	ret = btrfs_csum_one_bio(inode, bio, offset, 1);  	BUG_ON(ret); /* -ENOMEM */  	return 0; @@ -8321,7 +8320,7 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode,  static void btrfs_end_dio_bio(struct bio *bio)  {  	struct btrfs_dio_private *dip = bio->bi_private; -	int err = bio->bi_error; +	blk_status_t err = bio->bi_status;  	if (err)  		btrfs_warn(BTRFS_I(dip->inode)->root->fs_info, @@ -8351,7 +8350,7 @@ static void btrfs_end_dio_bio(struct bio *bio)  	if (dip->errors) {  		bio_io_error(dip->orig_bio);  	} else { -		dip->dio_bio->bi_error = 0; +		dip->dio_bio->bi_status = 0;  		bio_endio(dip->orig_bio);  	}  out: @@ -8368,14 +8367,14 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,  	return bio;  } -static inline int btrfs_lookup_and_bind_dio_csum(struct inode *inode, +static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode,  						 struct btrfs_dio_private *dip,  						 struct bio *bio,  						 u64 file_offset)  {  	struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);  	struct btrfs_io_bio *orig_io_bio = btrfs_io_bio(dip->orig_bio); -	int ret; +	blk_status_t ret;  	/*  	 * We load all the csum data we need when we submit @@ -8406,7 +8405,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_dio_private *dip = bio->bi_private;  	bool write = bio_op(bio) == REQ_OP_WRITE; -	int ret; +	blk_status_t ret;  	if (async_submit)  		async_submit = !atomic_read(&BTRFS_I(inode)->sync_writers); @@ -8649,7 +8648,7 @@ free_ordered:  	 * callbacks - they require an allocated dip and a clone of dio_bio.  	 */  	if (io_bio && dip) { -		io_bio->bi_error = -EIO; +		io_bio->bi_status = BLK_STS_IOERR;  		bio_endio(io_bio);  		/*  		 * The end io callbacks free our dip, do the final put on io_bio @@ -8668,12 +8667,12 @@ free_ordered:  			unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,  			      file_offset + dio_bio->bi_iter.bi_size - 1); -		dio_bio->bi_error = -EIO; +		dio_bio->bi_status = BLK_STS_IOERR;  		/*  		 * Releases and cleans up our dio_bio, no need to bio_put()  		 * nor bio_endio()/bio_io_error() against dio_bio.  		 */ -		dio_end_io(dio_bio, ret); +		dio_end_io(dio_bio);  	}  	if (io_bio)  		bio_put(io_bio); @@ -8755,6 +8754,9 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)  			dio_data.overwrite = 1;  			inode_unlock(inode);  			relock = true; +		} else if (iocb->ki_flags & IOCB_NOWAIT) { +			ret = -EAGAIN; +			goto out;  		}  		ret = btrfs_delalloc_reserve_space(inode, offset, count);  		if (ret)  |