aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChandan Rajendra <chandan@linux.vnet.ibm.com>2016-01-21 05:25:55 -0500
committerDavid Sterba <dsterba@suse.com>2016-02-01 13:23:47 -0500
commit2dabb3248453be9b81906dd028ec6979708de7be (patch)
treec352bb791f5b331e1bbeac7740c7656abd461c4a /fs/btrfs/inode.c
parentc40a3d38aff4e1c832d1692850621be7d5e5308c (diff)
Btrfs: Direct I/O read: Work on sectorsized blocks
The direct I/O read's endio and corresponding repair functions work on page sized blocks. This commit adds the ability for direct I/O read to work on subpagesized blocks. Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c98
1 files changed, 75 insertions, 23 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e4565456eb01..53c9dd1c0f28 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7751,9 +7751,9 @@ static int btrfs_check_dio_repairable(struct inode *inode,
7751} 7751}
7752 7752
7753static int dio_read_error(struct inode *inode, struct bio *failed_bio, 7753static int dio_read_error(struct inode *inode, struct bio *failed_bio,
7754 struct page *page, u64 start, u64 end, 7754 struct page *page, unsigned int pgoff,
7755 int failed_mirror, bio_end_io_t *repair_endio, 7755 u64 start, u64 end, int failed_mirror,
7756 void *repair_arg) 7756 bio_end_io_t *repair_endio, void *repair_arg)
7757{ 7757{
7758 struct io_failure_record *failrec; 7758 struct io_failure_record *failrec;
7759 struct bio *bio; 7759 struct bio *bio;
@@ -7774,7 +7774,9 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
7774 return -EIO; 7774 return -EIO;
7775 } 7775 }
7776 7776
7777 if (failed_bio->bi_vcnt > 1) 7777 if ((failed_bio->bi_vcnt > 1)
7778 || (failed_bio->bi_io_vec->bv_len
7779 > BTRFS_I(inode)->root->sectorsize))
7778 read_mode = READ_SYNC | REQ_FAILFAST_DEV; 7780 read_mode = READ_SYNC | REQ_FAILFAST_DEV;
7779 else 7781 else
7780 read_mode = READ_SYNC; 7782 read_mode = READ_SYNC;
@@ -7782,7 +7784,7 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
7782 isector = start - btrfs_io_bio(failed_bio)->logical; 7784 isector = start - btrfs_io_bio(failed_bio)->logical;
7783 isector >>= inode->i_sb->s_blocksize_bits; 7785 isector >>= inode->i_sb->s_blocksize_bits;
7784 bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page, 7786 bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page,
7785 0, isector, repair_endio, repair_arg); 7787 pgoff, isector, repair_endio, repair_arg);
7786 if (!bio) { 7788 if (!bio) {
7787 free_io_failure(inode, failrec); 7789 free_io_failure(inode, failrec);
7788 return -EIO; 7790 return -EIO;
@@ -7812,12 +7814,17 @@ struct btrfs_retry_complete {
7812static void btrfs_retry_endio_nocsum(struct bio *bio) 7814static void btrfs_retry_endio_nocsum(struct bio *bio)
7813{ 7815{
7814 struct btrfs_retry_complete *done = bio->bi_private; 7816 struct btrfs_retry_complete *done = bio->bi_private;
7817 struct inode *inode;
7815 struct bio_vec *bvec; 7818 struct bio_vec *bvec;
7816 int i; 7819 int i;
7817 7820
7818 if (bio->bi_error) 7821 if (bio->bi_error)
7819 goto end; 7822 goto end;
7820 7823
7824 ASSERT(bio->bi_vcnt == 1);
7825 inode = bio->bi_io_vec->bv_page->mapping->host;
7826 ASSERT(bio->bi_io_vec->bv_len == BTRFS_I(inode)->root->sectorsize);
7827
7821 done->uptodate = 1; 7828 done->uptodate = 1;
7822 bio_for_each_segment_all(bvec, bio, i) 7829 bio_for_each_segment_all(bvec, bio, i)
7823 clean_io_failure(done->inode, done->start, bvec->bv_page, 0); 7830 clean_io_failure(done->inode, done->start, bvec->bv_page, 0);
@@ -7829,25 +7836,35 @@ end:
7829static int __btrfs_correct_data_nocsum(struct inode *inode, 7836static int __btrfs_correct_data_nocsum(struct inode *inode,
7830 struct btrfs_io_bio *io_bio) 7837 struct btrfs_io_bio *io_bio)
7831{ 7838{
7839 struct btrfs_fs_info *fs_info;
7832 struct bio_vec *bvec; 7840 struct bio_vec *bvec;
7833 struct btrfs_retry_complete done; 7841 struct btrfs_retry_complete done;
7834 u64 start; 7842 u64 start;
7843 unsigned int pgoff;
7844 u32 sectorsize;
7845 int nr_sectors;
7835 int i; 7846 int i;
7836 int ret; 7847 int ret;
7837 7848
7849 fs_info = BTRFS_I(inode)->root->fs_info;
7850 sectorsize = BTRFS_I(inode)->root->sectorsize;
7851
7838 start = io_bio->logical; 7852 start = io_bio->logical;
7839 done.inode = inode; 7853 done.inode = inode;
7840 7854
7841 bio_for_each_segment_all(bvec, &io_bio->bio, i) { 7855 bio_for_each_segment_all(bvec, &io_bio->bio, i) {
7842try_again: 7856 nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len);
7857 pgoff = bvec->bv_offset;
7858
7859next_block_or_try_again:
7843 done.uptodate = 0; 7860 done.uptodate = 0;
7844 done.start = start; 7861 done.start = start;
7845 init_completion(&done.done); 7862 init_completion(&done.done);
7846 7863
7847 ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, start, 7864 ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page,
7848 start + bvec->bv_len - 1, 7865 pgoff, start, start + sectorsize - 1,
7849 io_bio->mirror_num, 7866 io_bio->mirror_num,
7850 btrfs_retry_endio_nocsum, &done); 7867 btrfs_retry_endio_nocsum, &done);
7851 if (ret) 7868 if (ret)
7852 return ret; 7869 return ret;
7853 7870
@@ -7855,10 +7872,15 @@ try_again:
7855 7872
7856 if (!done.uptodate) { 7873 if (!done.uptodate) {
7857 /* We might have another mirror, so try again */ 7874 /* We might have another mirror, so try again */
7858 goto try_again; 7875 goto next_block_or_try_again;
7859 } 7876 }
7860 7877
7861 start += bvec->bv_len; 7878 start += sectorsize;
7879
7880 if (nr_sectors--) {
7881 pgoff += sectorsize;
7882 goto next_block_or_try_again;
7883 }
7862 } 7884 }
7863 7885
7864 return 0; 7886 return 0;
@@ -7868,7 +7890,9 @@ static void btrfs_retry_endio(struct bio *bio)
7868{ 7890{
7869 struct btrfs_retry_complete *done = bio->bi_private; 7891 struct btrfs_retry_complete *done = bio->bi_private;
7870 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); 7892 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
7893 struct inode *inode;
7871 struct bio_vec *bvec; 7894 struct bio_vec *bvec;
7895 u64 start;
7872 int uptodate; 7896 int uptodate;
7873 int ret; 7897 int ret;
7874 int i; 7898 int i;
@@ -7877,13 +7901,20 @@ static void btrfs_retry_endio(struct bio *bio)
7877 goto end; 7901 goto end;
7878 7902
7879 uptodate = 1; 7903 uptodate = 1;
7904
7905 start = done->start;
7906
7907 ASSERT(bio->bi_vcnt == 1);
7908 inode = bio->bi_io_vec->bv_page->mapping->host;
7909 ASSERT(bio->bi_io_vec->bv_len == BTRFS_I(inode)->root->sectorsize);
7910
7880 bio_for_each_segment_all(bvec, bio, i) { 7911 bio_for_each_segment_all(bvec, bio, i) {
7881 ret = __readpage_endio_check(done->inode, io_bio, i, 7912 ret = __readpage_endio_check(done->inode, io_bio, i,
7882 bvec->bv_page, 0, 7913 bvec->bv_page, bvec->bv_offset,
7883 done->start, bvec->bv_len); 7914 done->start, bvec->bv_len);
7884 if (!ret) 7915 if (!ret)
7885 clean_io_failure(done->inode, done->start, 7916 clean_io_failure(done->inode, done->start,
7886 bvec->bv_page, 0); 7917 bvec->bv_page, bvec->bv_offset);
7887 else 7918 else
7888 uptodate = 0; 7919 uptodate = 0;
7889 } 7920 }
@@ -7897,20 +7928,34 @@ end:
7897static int __btrfs_subio_endio_read(struct inode *inode, 7928static int __btrfs_subio_endio_read(struct inode *inode,
7898 struct btrfs_io_bio *io_bio, int err) 7929 struct btrfs_io_bio *io_bio, int err)
7899{ 7930{
7931 struct btrfs_fs_info *fs_info;
7900 struct bio_vec *bvec; 7932 struct bio_vec *bvec;
7901 struct btrfs_retry_complete done; 7933 struct btrfs_retry_complete done;
7902 u64 start; 7934 u64 start;
7903 u64 offset = 0; 7935 u64 offset = 0;
7936 u32 sectorsize;
7937 int nr_sectors;
7938 unsigned int pgoff;
7939 int csum_pos;
7904 int i; 7940 int i;
7905 int ret; 7941 int ret;
7906 7942
7943 fs_info = BTRFS_I(inode)->root->fs_info;
7944 sectorsize = BTRFS_I(inode)->root->sectorsize;
7945
7907 err = 0; 7946 err = 0;
7908 start = io_bio->logical; 7947 start = io_bio->logical;
7909 done.inode = inode; 7948 done.inode = inode;
7910 7949
7911 bio_for_each_segment_all(bvec, &io_bio->bio, i) { 7950 bio_for_each_segment_all(bvec, &io_bio->bio, i) {
7912 ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page, 7951 nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len);
7913 0, start, bvec->bv_len); 7952
7953 pgoff = bvec->bv_offset;
7954next_block:
7955 csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset);
7956 ret = __readpage_endio_check(inode, io_bio, csum_pos,
7957 bvec->bv_page, pgoff, start,
7958 sectorsize);
7914 if (likely(!ret)) 7959 if (likely(!ret))
7915 goto next; 7960 goto next;
7916try_again: 7961try_again:
@@ -7918,10 +7963,10 @@ try_again:
7918 done.start = start; 7963 done.start = start;
7919 init_completion(&done.done); 7964 init_completion(&done.done);
7920 7965
7921 ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, start, 7966 ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page,
7922 start + bvec->bv_len - 1, 7967 pgoff, start, start + sectorsize - 1,
7923 io_bio->mirror_num, 7968 io_bio->mirror_num,
7924 btrfs_retry_endio, &done); 7969 btrfs_retry_endio, &done);
7925 if (ret) { 7970 if (ret) {
7926 err = ret; 7971 err = ret;
7927 goto next; 7972 goto next;
@@ -7934,8 +7979,15 @@ try_again:
7934 goto try_again; 7979 goto try_again;
7935 } 7980 }
7936next: 7981next:
7937 offset += bvec->bv_len; 7982 offset += sectorsize;
7938 start += bvec->bv_len; 7983 start += sectorsize;
7984
7985 ASSERT(nr_sectors);
7986
7987 if (--nr_sectors) {
7988 pgoff += sectorsize;
7989 goto next_block;
7990 }
7939 } 7991 }
7940 7992
7941 return err; 7993 return err;