diff options
-rw-r--r-- | fs/btrfs/raid56.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 95053a903474..0600bf69199e 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c | |||
@@ -69,6 +69,11 @@ | |||
69 | 69 | ||
70 | #define RBIO_CACHE_SIZE 1024 | 70 | #define RBIO_CACHE_SIZE 1024 |
71 | 71 | ||
72 | enum btrfs_rbio_ops { | ||
73 | BTRFS_RBIO_WRITE = 0, | ||
74 | BTRFS_RBIO_READ_REBUILD = 1, | ||
75 | }; | ||
76 | |||
72 | struct btrfs_raid_bio { | 77 | struct btrfs_raid_bio { |
73 | struct btrfs_fs_info *fs_info; | 78 | struct btrfs_fs_info *fs_info; |
74 | struct btrfs_bio *bbio; | 79 | struct btrfs_bio *bbio; |
@@ -131,7 +136,7 @@ struct btrfs_raid_bio { | |||
131 | * differently from a parity rebuild as part of | 136 | * differently from a parity rebuild as part of |
132 | * rmw | 137 | * rmw |
133 | */ | 138 | */ |
134 | int read_rebuild; | 139 | enum btrfs_rbio_ops operation; |
135 | 140 | ||
136 | /* first bad stripe */ | 141 | /* first bad stripe */ |
137 | int faila; | 142 | int faila; |
@@ -154,7 +159,6 @@ struct btrfs_raid_bio { | |||
154 | 159 | ||
155 | atomic_t refs; | 160 | atomic_t refs; |
156 | 161 | ||
157 | |||
158 | atomic_t stripes_pending; | 162 | atomic_t stripes_pending; |
159 | 163 | ||
160 | atomic_t error; | 164 | atomic_t error; |
@@ -590,8 +594,7 @@ static int rbio_can_merge(struct btrfs_raid_bio *last, | |||
590 | return 0; | 594 | return 0; |
591 | 595 | ||
592 | /* reads can't merge with writes */ | 596 | /* reads can't merge with writes */ |
593 | if (last->read_rebuild != | 597 | if (last->operation != cur->operation) { |
594 | cur->read_rebuild) { | ||
595 | return 0; | 598 | return 0; |
596 | } | 599 | } |
597 | 600 | ||
@@ -784,9 +787,9 @@ static noinline void unlock_stripe(struct btrfs_raid_bio *rbio) | |||
784 | spin_unlock(&rbio->bio_list_lock); | 787 | spin_unlock(&rbio->bio_list_lock); |
785 | spin_unlock_irqrestore(&h->lock, flags); | 788 | spin_unlock_irqrestore(&h->lock, flags); |
786 | 789 | ||
787 | if (next->read_rebuild) | 790 | if (next->operation == BTRFS_RBIO_READ_REBUILD) |
788 | async_read_rebuild(next); | 791 | async_read_rebuild(next); |
789 | else { | 792 | else if (next->operation == BTRFS_RBIO_WRITE){ |
790 | steal_rbio(rbio, next); | 793 | steal_rbio(rbio, next); |
791 | async_rmw_stripe(next); | 794 | async_rmw_stripe(next); |
792 | } | 795 | } |
@@ -1720,6 +1723,7 @@ int raid56_parity_write(struct btrfs_root *root, struct bio *bio, | |||
1720 | } | 1723 | } |
1721 | bio_list_add(&rbio->bio_list, bio); | 1724 | bio_list_add(&rbio->bio_list, bio); |
1722 | rbio->bio_list_bytes = bio->bi_iter.bi_size; | 1725 | rbio->bio_list_bytes = bio->bi_iter.bi_size; |
1726 | rbio->operation = BTRFS_RBIO_WRITE; | ||
1723 | 1727 | ||
1724 | /* | 1728 | /* |
1725 | * don't plug on full rbios, just get them out the door | 1729 | * don't plug on full rbios, just get them out the door |
@@ -1768,7 +1772,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) | |||
1768 | faila = rbio->faila; | 1772 | faila = rbio->faila; |
1769 | failb = rbio->failb; | 1773 | failb = rbio->failb; |
1770 | 1774 | ||
1771 | if (rbio->read_rebuild) { | 1775 | if (rbio->operation == BTRFS_RBIO_READ_REBUILD) { |
1772 | spin_lock_irq(&rbio->bio_list_lock); | 1776 | spin_lock_irq(&rbio->bio_list_lock); |
1773 | set_bit(RBIO_RMW_LOCKED_BIT, &rbio->flags); | 1777 | set_bit(RBIO_RMW_LOCKED_BIT, &rbio->flags); |
1774 | spin_unlock_irq(&rbio->bio_list_lock); | 1778 | spin_unlock_irq(&rbio->bio_list_lock); |
@@ -1785,7 +1789,7 @@ static void __raid_recover_end_io(struct btrfs_raid_bio *rbio) | |||
1785 | * if we're rebuilding a read, we have to use | 1789 | * if we're rebuilding a read, we have to use |
1786 | * pages from the bio list | 1790 | * pages from the bio list |
1787 | */ | 1791 | */ |
1788 | if (rbio->read_rebuild && | 1792 | if (rbio->operation == BTRFS_RBIO_READ_REBUILD && |
1789 | (stripe == faila || stripe == failb)) { | 1793 | (stripe == faila || stripe == failb)) { |
1790 | page = page_in_rbio(rbio, stripe, pagenr, 0); | 1794 | page = page_in_rbio(rbio, stripe, pagenr, 0); |
1791 | } else { | 1795 | } else { |
@@ -1878,7 +1882,7 @@ pstripe: | |||
1878 | * know they can be trusted. If this was a read reconstruction, | 1882 | * know they can be trusted. If this was a read reconstruction, |
1879 | * other endio functions will fiddle the uptodate bits | 1883 | * other endio functions will fiddle the uptodate bits |
1880 | */ | 1884 | */ |
1881 | if (!rbio->read_rebuild) { | 1885 | if (rbio->operation == BTRFS_RBIO_WRITE) { |
1882 | for (i = 0; i < nr_pages; i++) { | 1886 | for (i = 0; i < nr_pages; i++) { |
1883 | if (faila != -1) { | 1887 | if (faila != -1) { |
1884 | page = rbio_stripe_page(rbio, faila, i); | 1888 | page = rbio_stripe_page(rbio, faila, i); |
@@ -1895,7 +1899,7 @@ pstripe: | |||
1895 | * if we're rebuilding a read, we have to use | 1899 | * if we're rebuilding a read, we have to use |
1896 | * pages from the bio list | 1900 | * pages from the bio list |
1897 | */ | 1901 | */ |
1898 | if (rbio->read_rebuild && | 1902 | if (rbio->operation == BTRFS_RBIO_READ_REBUILD && |
1899 | (stripe == faila || stripe == failb)) { | 1903 | (stripe == faila || stripe == failb)) { |
1900 | page = page_in_rbio(rbio, stripe, pagenr, 0); | 1904 | page = page_in_rbio(rbio, stripe, pagenr, 0); |
1901 | } else { | 1905 | } else { |
@@ -1910,8 +1914,7 @@ cleanup: | |||
1910 | kfree(pointers); | 1914 | kfree(pointers); |
1911 | 1915 | ||
1912 | cleanup_io: | 1916 | cleanup_io: |
1913 | 1917 | if (rbio->operation == BTRFS_RBIO_READ_REBUILD) { | |
1914 | if (rbio->read_rebuild) { | ||
1915 | if (err == 0 && | 1918 | if (err == 0 && |
1916 | !test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags)) | 1919 | !test_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags)) |
1917 | cache_rbio_pages(rbio); | 1920 | cache_rbio_pages(rbio); |
@@ -2050,7 +2053,7 @@ out: | |||
2050 | return 0; | 2053 | return 0; |
2051 | 2054 | ||
2052 | cleanup: | 2055 | cleanup: |
2053 | if (rbio->read_rebuild) | 2056 | if (rbio->operation == BTRFS_RBIO_READ_REBUILD) |
2054 | rbio_orig_end_io(rbio, -EIO, 0); | 2057 | rbio_orig_end_io(rbio, -EIO, 0); |
2055 | return -EIO; | 2058 | return -EIO; |
2056 | } | 2059 | } |
@@ -2076,7 +2079,7 @@ int raid56_parity_recover(struct btrfs_root *root, struct bio *bio, | |||
2076 | 2079 | ||
2077 | if (hold_bbio) | 2080 | if (hold_bbio) |
2078 | set_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags); | 2081 | set_bit(RBIO_HOLD_BBIO_MAP_BIT, &rbio->flags); |
2079 | rbio->read_rebuild = 1; | 2082 | rbio->operation = BTRFS_RBIO_READ_REBUILD; |
2080 | bio_list_add(&rbio->bio_list, bio); | 2083 | bio_list_add(&rbio->bio_list, bio); |
2081 | rbio->bio_list_bytes = bio->bi_iter.bi_size; | 2084 | rbio->bio_list_bytes = bio->bi_iter.bi_size; |
2082 | 2085 | ||