mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	btrfs: Remove extent_io_ops::readpage_io_failed_hook
For data inodes this hook does nothing but to return -EAGAIN which is used to signal to the endio routines that this bio belongs to a data inode. If this is the case the actual retrying is handled by bio_readpage_error. Alternatively, if this bio belongs to the btree inode then btree_io_failed_hook just does some cleanup and doesn't retry anything. This patch simplifies the code flow by eliminating readpage_io_failed_hook and instead open-coding btree_io_failed_hook in end_bio_extent_readpage. Also eliminate some needless checks since IO is always performed on either data inode or btree inode, both of which are guaranteed to have their extent_io_tree::ops set. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									7b41ba71c1
								
							
						
					
					
						commit
						78e62c02ab
					
				
					 4 changed files with 35 additions and 60 deletions
				
			
		|  | @ -673,19 +673,6 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int btree_io_failed_hook(struct page *page, int failed_mirror) | ||||
| { | ||||
| 	struct extent_buffer *eb; | ||||
| 
 | ||||
| 	eb = (struct extent_buffer *)page->private; | ||||
| 	set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags); | ||||
| 	eb->read_mirror = failed_mirror; | ||||
| 	atomic_dec(&eb->io_pages); | ||||
| 	if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) | ||||
| 		btree_readahead_hook(eb, -EIO); | ||||
| 	return -EIO;	/* we fixed nothing */ | ||||
| } | ||||
| 
 | ||||
| static void end_workqueue_bio(struct bio *bio) | ||||
| { | ||||
| 	struct btrfs_end_io_wq *end_io_wq = bio->bi_private; | ||||
|  | @ -4560,7 +4547,4 @@ static const struct extent_io_ops btree_extent_io_ops = { | |||
| 	/* mandatory callbacks */ | ||||
| 	.submit_bio_hook = btree_submit_bio_hook, | ||||
| 	.readpage_end_io_hook = btree_readpage_end_io_hook, | ||||
| 	.readpage_io_failed_hook = btree_io_failed_hook, | ||||
| 
 | ||||
| 	/* optional callbacks */ | ||||
| }; | ||||
|  |  | |||
|  | @ -2333,13 +2333,11 @@ struct bio *btrfs_create_repair_bio(struct inode *inode, struct bio *failed_bio, | |||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * this is a generic handler for readpage errors (default | ||||
|  * readpage_io_failed_hook). if other copies exist, read those and write back | ||||
|  * good data to the failed position. does not investigate in remapping the | ||||
|  * failed extent elsewhere, hoping the device will be smart enough to do this as | ||||
|  * needed | ||||
|  * This is a generic handler for readpage errors. If other copies exist, read | ||||
|  * those and write back good data to the failed position. Does not investigate | ||||
|  * in remapping the failed extent elsewhere, hoping the device will be smart | ||||
|  * enough to do this as needed | ||||
|  */ | ||||
| 
 | ||||
| static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset, | ||||
| 			      struct page *page, u64 start, u64 end, | ||||
| 			      int failed_mirror) | ||||
|  | @ -2501,6 +2499,8 @@ static void end_bio_extent_readpage(struct bio *bio) | |||
| 		struct page *page = bvec->bv_page; | ||||
| 		struct inode *inode = page->mapping->host; | ||||
| 		struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | ||||
| 		bool data_inode = btrfs_ino(BTRFS_I(inode)) | ||||
| 			!= BTRFS_BTREE_INODE_OBJECTID; | ||||
| 
 | ||||
| 		btrfs_debug(fs_info, | ||||
| 			"end_bio_extent_readpage: bi_sector=%llu, err=%d, mirror=%u", | ||||
|  | @ -2530,7 +2530,7 @@ static void end_bio_extent_readpage(struct bio *bio) | |||
| 		len = bvec->bv_len; | ||||
| 
 | ||||
| 		mirror = io_bio->mirror_num; | ||||
| 		if (likely(uptodate && tree->ops)) { | ||||
| 		if (likely(uptodate)) { | ||||
| 			ret = tree->ops->readpage_end_io_hook(io_bio, offset, | ||||
| 							      page, start, end, | ||||
| 							      mirror); | ||||
|  | @ -2546,38 +2546,37 @@ static void end_bio_extent_readpage(struct bio *bio) | |||
| 		if (likely(uptodate)) | ||||
| 			goto readpage_ok; | ||||
| 
 | ||||
| 		if (tree->ops) { | ||||
| 			ret = tree->ops->readpage_io_failed_hook(page, mirror); | ||||
| 			if (ret == -EAGAIN) { | ||||
| 		if (data_inode) { | ||||
| 
 | ||||
| 			/*
 | ||||
| 				 * Data inode's readpage_io_failed_hook() always | ||||
| 				 * returns -EAGAIN. | ||||
| 				 * | ||||
| 				 * The generic bio_readpage_error handles errors | ||||
| 				 * the following way: If possible, new read | ||||
| 				 * requests are created and submitted and will | ||||
| 				 * end up in end_bio_extent_readpage as well (if | ||||
| 				 * we're lucky, not in the !uptodate case). In | ||||
| 				 * that case it returns 0 and we just go on with | ||||
| 				 * the next page in our bio. If it can't handle | ||||
| 				 * the error it will return -EIO and we remain | ||||
| 				 * responsible for that page. | ||||
| 			 * The generic bio_readpage_error handles errors the | ||||
| 			 * following way: If possible, new read requests are | ||||
| 			 * created and submitted and will end up in | ||||
| 			 * end_bio_extent_readpage as well (if we're lucky, | ||||
| 			 * not in the !uptodate case). In that case it returns | ||||
| 			 * 0 and we just go on with the next page in our bio. | ||||
| 			 * If it can't handle the error it will return -EIO and | ||||
| 			 * we remain responsible for that page. | ||||
| 			 */ | ||||
| 				ret = bio_readpage_error(bio, offset, page, | ||||
| 							 start, end, mirror); | ||||
| 			ret = bio_readpage_error(bio, offset, page, start, end, | ||||
| 						 mirror); | ||||
| 			if (ret == 0) { | ||||
| 				uptodate = !bio->bi_status; | ||||
| 				offset += len; | ||||
| 				continue; | ||||
| 			} | ||||
| 			} | ||||
| 		} else { | ||||
| 			struct extent_buffer *eb; | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * metadata's readpage_io_failed_hook() always returns | ||||
| 			 * -EIO and fixes nothing.  -EIO is also returned if | ||||
| 			 * data inode error could not be fixed. | ||||
| 			 */ | ||||
| 			ASSERT(ret == -EIO); | ||||
| 			eb = (struct extent_buffer *)page->private; | ||||
| 			set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags); | ||||
| 			eb->read_mirror = mirror; | ||||
| 			atomic_dec(&eb->io_pages); | ||||
| 			if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, | ||||
| 					       &eb->bflags)) | ||||
| 				btree_readahead_hook(eb, -EIO); | ||||
| 
 | ||||
| 			ret = -EIO; | ||||
| 		} | ||||
| readpage_ok: | ||||
| 		if (likely(uptodate)) { | ||||
|  |  | |||
|  | @ -101,7 +101,6 @@ struct extent_io_ops { | |||
| 	int (*readpage_end_io_hook)(struct btrfs_io_bio *io_bio, u64 phy_offset, | ||||
| 				    struct page *page, u64 start, u64 end, | ||||
| 				    int mirror); | ||||
| 	int (*readpage_io_failed_hook)(struct page *page, int failed_mirror); | ||||
| }; | ||||
| 
 | ||||
| struct extent_io_tree { | ||||
|  |  | |||
|  | @ -10409,12 +10409,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| __attribute__((const)) | ||||
| static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror) | ||||
| { | ||||
| 	return -EAGAIN; | ||||
| } | ||||
| 
 | ||||
| void btrfs_set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) | ||||
| { | ||||
| 	struct inode *inode = tree->private_data; | ||||
|  | @ -10810,7 +10804,6 @@ static const struct extent_io_ops btrfs_extent_io_ops = { | |||
| 	/* mandatory callbacks */ | ||||
| 	.submit_bio_hook = btrfs_submit_bio_hook, | ||||
| 	.readpage_end_io_hook = btrfs_readpage_end_io_hook, | ||||
| 	.readpage_io_failed_hook = btrfs_readpage_io_failed_hook, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Nikolay Borisov
						Nikolay Borisov