aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-11-06 08:43:46 -0500
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:43 -0500
commit472262f35a6b3407e761b700d74c53530e5f144d (patch)
tree56165ccfa9fe72a9b0e2d455fe023300c0a4b434 /fs/btrfs/volumes.c
parent29a8d9a0bce6a5abac1f313400c2e189e8d10e67 (diff)
Btrfs: changes to live filesystem are also written to replacement disk
During a running dev replace operation, all write requests to the live filesystem are duplicated to also write to the target drive. Therefore btrfs_map_block() is changed to duplicate stripes that are written to the source disk of a device replace procedure to be written to the target disk as well. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index de0c05cca390..4d3bf187ab52 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4044,6 +4044,9 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4044 int num_stripes; 4044 int num_stripes;
4045 int max_errors = 0; 4045 int max_errors = 0;
4046 struct btrfs_bio *bbio = NULL; 4046 struct btrfs_bio *bbio = NULL;
4047 struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
4048 int dev_replace_is_ongoing = 0;
4049 int num_alloc_stripes;
4047 4050
4048 read_lock(&em_tree->lock); 4051 read_lock(&em_tree->lock);
4049 em = lookup_extent_mapping(em_tree, logical, *length); 4052 em = lookup_extent_mapping(em_tree, logical, *length);
@@ -4089,6 +4092,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4089 if (!bbio_ret) 4092 if (!bbio_ret)
4090 goto out; 4093 goto out;
4091 4094
4095 btrfs_dev_replace_lock(dev_replace);
4096 dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace);
4097 if (!dev_replace_is_ongoing)
4098 btrfs_dev_replace_unlock(dev_replace);
4099
4092 num_stripes = 1; 4100 num_stripes = 1;
4093 stripe_index = 0; 4101 stripe_index = 0;
4094 stripe_nr_orig = stripe_nr; 4102 stripe_nr_orig = stripe_nr;
@@ -4155,7 +4163,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4155 } 4163 }
4156 BUG_ON(stripe_index >= map->num_stripes); 4164 BUG_ON(stripe_index >= map->num_stripes);
4157 4165
4158 bbio = kzalloc(btrfs_bio_size(num_stripes), GFP_NOFS); 4166 num_alloc_stripes = num_stripes;
4167 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)))
4168 num_alloc_stripes <<= 1;
4169 bbio = kzalloc(btrfs_bio_size(num_alloc_stripes), GFP_NOFS);
4159 if (!bbio) { 4170 if (!bbio) {
4160 ret = -ENOMEM; 4171 ret = -ENOMEM;
4161 goto out; 4172 goto out;
@@ -4250,11 +4261,48 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw,
4250 } 4261 }
4251 } 4262 }
4252 4263
4264 if (dev_replace_is_ongoing && (rw & (REQ_WRITE | REQ_DISCARD)) &&
4265 dev_replace->tgtdev != NULL) {
4266 int index_where_to_add;
4267 u64 srcdev_devid = dev_replace->srcdev->devid;
4268
4269 /*
4270 * duplicate the write operations while the dev replace
4271 * procedure is running. Since the copying of the old disk
4272 * to the new disk takes place at run time while the
4273 * filesystem is mounted writable, the regular write
4274 * operations to the old disk have to be duplicated to go
4275 * to the new disk as well.
4276 * Note that device->missing is handled by the caller, and
4277 * that the write to the old disk is already set up in the
4278 * stripes array.
4279 */
4280 index_where_to_add = num_stripes;
4281 for (i = 0; i < num_stripes; i++) {
4282 if (bbio->stripes[i].dev->devid == srcdev_devid) {
4283 /* write to new disk, too */
4284 struct btrfs_bio_stripe *new =
4285 bbio->stripes + index_where_to_add;
4286 struct btrfs_bio_stripe *old =
4287 bbio->stripes + i;
4288
4289 new->physical = old->physical;
4290 new->length = old->length;
4291 new->dev = dev_replace->tgtdev;
4292 index_where_to_add++;
4293 max_errors++;
4294 }
4295 }
4296 num_stripes = index_where_to_add;
4297 }
4298
4253 *bbio_ret = bbio; 4299 *bbio_ret = bbio;
4254 bbio->num_stripes = num_stripes; 4300 bbio->num_stripes = num_stripes;
4255 bbio->max_errors = max_errors; 4301 bbio->max_errors = max_errors;
4256 bbio->mirror_num = mirror_num; 4302 bbio->mirror_num = mirror_num;
4257out: 4303out:
4304 if (dev_replace_is_ongoing)
4305 btrfs_dev_replace_unlock(dev_replace);
4258 free_extent_map(em); 4306 free_extent_map(em);
4259 return ret; 4307 return ret;
4260} 4308}