aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-11-06 08:16:24 -0500
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:43 -0500
commit29a8d9a0bce6a5abac1f313400c2e189e8d10e67 (patch)
treebd87db714acddf9c1a50121ed18805333682ac44 /fs/btrfs
parent8dabb7420f014ab0f9f04afae8ae046c0f48b270 (diff)
Btrfs: introduce GET_READ_MIRRORS functionality for btrfs_map_block()
Before this commit, btrfs_map_block() was called with REQ_WRITE in order to retrieve the list of mirrors for a disk block. This needs to be changed for the device replace procedure since it makes a difference whether you are asking for read mirrors or for locations to write to. GET_READ_MIRRORS is introduced as a new interface to call btrfs_map_block(). In the current commit, the functionality is not yet changed, only the interface for GET_READ_MIRRORS is introduced and all the places that should use this new interface are adapted. The reason that REQ_WRITE cannot be abused anymore to retrieve a list of read mirrors is that during a running dev replace operation all write requests to the live filesystem are duplicated to also write to the target drive. Keep in mind that the target disk is only partially a valid copy of the source disk while the operation is ongoing. All writes go to the target disk, but not all reads would return valid data on the target disk. Therefore it is not possible anymore to abuse a REQ_WRITE interface to find valid mirrors for a REQ_READ. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/reada.c3
-rw-r--r--fs/btrfs/scrub.c4
-rw-r--r--fs/btrfs/volumes.c8
4 files changed, 11 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 45e7f752b64a..46bd7d5f504b 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -174,6 +174,9 @@ static int btrfs_csum_sizes[] = { 4, 0 };
174/* four bytes for CRC32 */ 174/* four bytes for CRC32 */
175#define BTRFS_EMPTY_DIR_SIZE 0 175#define BTRFS_EMPTY_DIR_SIZE 0
176 176
177/* spefic to btrfs_map_block(), therefore not in include/linux/blk_types.h */
178#define REQ_GET_READ_MIRRORS (1 << 30)
179
177#define BTRFS_FT_UNKNOWN 0 180#define BTRFS_FT_UNKNOWN 0
178#define BTRFS_FT_REG_FILE 1 181#define BTRFS_FT_REG_FILE 1
179#define BTRFS_FT_DIR 2 182#define BTRFS_FT_DIR 2
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index c705a48e676b..96b93daa0bbb 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -359,7 +359,8 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
359 * map block 359 * map block
360 */ 360 */
361 length = blocksize; 361 length = blocksize;
362 ret = btrfs_map_block(fs_info, REQ_WRITE, logical, &length, &bbio, 0); 362 ret = btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, logical, &length,
363 &bbio, 0);
363 if (ret || !bbio || length < blocksize) 364 if (ret || !bbio || length < blocksize)
364 goto error; 365 goto error;
365 366
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 30cbf6921c0b..30ba99724896 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1193,8 +1193,8 @@ static int scrub_setup_recheck_block(struct scrub_ctx *sctx,
1193 * with a length of PAGE_SIZE, each returned stripe 1193 * with a length of PAGE_SIZE, each returned stripe
1194 * represents one mirror 1194 * represents one mirror
1195 */ 1195 */
1196 ret = btrfs_map_block(fs_info, WRITE, logical, &mapped_length, 1196 ret = btrfs_map_block(fs_info, REQ_GET_READ_MIRRORS, logical,
1197 &bbio, 0); 1197 &mapped_length, &bbio, 0);
1198 if (ret || !bbio || mapped_length < sublen) { 1198 if (ret || !bbio || mapped_length < sublen) {
1199 kfree(bbio); 1199 kfree(bbio);
1200 return -EIO; 1200 return -EIO;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index a4e0963bf457..de0c05cca390 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4103,7 +4103,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4103 stripe_nr_end - stripe_nr_orig); 4103 stripe_nr_end - stripe_nr_orig);
4104 stripe_index = do_div(stripe_nr, map->num_stripes); 4104 stripe_index = do_div(stripe_nr, map->num_stripes);
4105 } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) { 4105 } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
4106 if (rw & (REQ_WRITE | REQ_DISCARD)) 4106 if (rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS))
4107 num_stripes = map->num_stripes; 4107 num_stripes = map->num_stripes;
4108 else if (mirror_num) 4108 else if (mirror_num)
4109 stripe_index = mirror_num - 1; 4109 stripe_index = mirror_num - 1;
@@ -4115,7 +4115,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4115 } 4115 }
4116 4116
4117 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { 4117 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
4118 if (rw & (REQ_WRITE | REQ_DISCARD)) { 4118 if (rw & (REQ_WRITE | REQ_DISCARD | REQ_GET_READ_MIRRORS)) {
4119 num_stripes = map->num_stripes; 4119 num_stripes = map->num_stripes;
4120 } else if (mirror_num) { 4120 } else if (mirror_num) {
4121 stripe_index = mirror_num - 1; 4121 stripe_index = mirror_num - 1;
@@ -4129,7 +4129,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4129 stripe_index = do_div(stripe_nr, factor); 4129 stripe_index = do_div(stripe_nr, factor);
4130 stripe_index *= map->sub_stripes; 4130 stripe_index *= map->sub_stripes;
4131 4131
4132 if (rw & REQ_WRITE) 4132 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS))
4133 num_stripes = map->sub_stripes; 4133 num_stripes = map->sub_stripes;
4134 else if (rw & REQ_DISCARD) 4134 else if (rw & REQ_DISCARD)
4135 num_stripes = min_t(u64, map->sub_stripes * 4135 num_stripes = min_t(u64, map->sub_stripes *
@@ -4242,7 +4242,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4242 } 4242 }
4243 } 4243 }
4244 4244
4245 if (rw & REQ_WRITE) { 4245 if (rw & (REQ_WRITE | REQ_GET_READ_MIRRORS)) {
4246 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 | 4246 if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
4247 BTRFS_BLOCK_GROUP_RAID10 | 4247 BTRFS_BLOCK_GROUP_RAID10 |
4248 BTRFS_BLOCK_GROUP_DUP)) { 4248 BTRFS_BLOCK_GROUP_DUP)) {