diff options
author | NeilBrown <neilb@suse.de> | 2013-05-21 16:28:23 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-05-22 12:22:36 +1000 |
commit | 63c12c89d4bed2cfbf9d263b968563741bb37d2c (patch) | |
tree | b3b007e9d72172e6be040d6134b50f286c4b344b /Grow.c | |
parent | 89ecd3cfe41685cf260ed8f53ff95e2f0ad625cb (diff) |
Grow: use new_data_offset instead of backups for raid4/5/6 reshape.
If we can modify the data_offset, we can avoid doing any backups at all.
If we can't fall back on old approach - but not if --data-offset
was requested.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 34 |
1 files changed, 34 insertions, 0 deletions
@@ -1438,6 +1438,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re) info->new_chunk, info->array.chunk_size, re->after.data_disks, re->before.data_disks); + re->min_offset_change = re->backup_blocks / re->before.data_disks; re->new_size = info->component_size * re->after.data_disks; return NULL; @@ -2856,6 +2857,39 @@ started: goto release; } + switch(set_new_data_offset(sra, st, devname, info->delta_disks, + data_offset, + reshape.min_offset_change)) { + case -1: + goto release; + case 0: + /* Updated data_offset, so it's easy now */ + update_cache_size(container, sra, info, + min(reshape.before.data_disks, + reshape.after.data_disks), + reshape.backup_blocks); + + /* Right, everything seems fine. Let's kick things off. + */ + sync_metadata(st); + + if (impose_reshape(sra, info, st, fd, restart, + devname, container, &reshape) < 0) + goto release; + if (sysfs_set_str(sra, NULL, "sync_action", "reshape") < 0) { + pr_err("Failed to initiate reshape!\n"); + goto release; + } + + return 0; + case 1: /* Couldn't set data_offset, try the old way */ + if (data_offset != INVALID_SECTORS) { + pr_err("Cannot update data_offset on this array\n"); + goto release; + } + break; + } + /* Decide how many blocks (sectors) for a reshape * unit. The number we have so far is just a minimum */ |