diff options
author | NeilBrown <neilb@suse.de> | 2008-10-15 05:34:18 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2008-10-15 05:34:18 +0200 |
commit | 1c6cb603fa60d3425f4d4b76e721b485bb006fcb (patch) | |
tree | ea7f7d00936e31e51f0016d4b72f7dc69ebc952c /super1.c | |
parent | Improve reporting of layout for raid10. (diff) | |
download | mdadm-1c6cb603fa60d3425f4d4b76e721b485bb006fcb.tar.xz mdadm-1c6cb603fa60d3425f4d4b76e721b485bb006fcb.zip |
Grow: Fix linear-growth when devices are not all the same size.
If we add a device to a linear array which is a difference size
to the other devices in the array then, for v1.x metadata, we need to
make sure the size is correctly reflected in the superblock.
Diffstat (limited to '')
-rw-r--r-- | super1.c | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -599,7 +599,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, } if (strcmp(update, "linear-grow-new") == 0) { int i; - int rfd; + int rfd, fd; int max = __le32_to_cpu(sb->max_dev); for (i=0 ; i < max ; i++) @@ -620,6 +620,25 @@ static int update_super1(struct supertype *st, struct mdinfo *info, sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk); + + fd = open(devname, O_RDONLY); + if (fd >= 0) { + unsigned long long ds; + get_dev_size(fd, devname, &ds); + close(fd); + ds >>= 9; + if (__le64_to_cpu(sb->super_offset) < + __le64_to_cpu(sb->data_offset)) { + sb->data_size = __cpu_to_le64( + ds - __le64_to_cpu(sb->data_offset)); + } else { + ds -= 8*2; + ds &= ~(unsigned long long)(4*2-1); + sb->super_offset = __cpu_to_le64(ds); + sb->data_size = __cpu_to_le64( + ds - __le64_to_cpu(sb->data_offset)); + } + } } if (strcmp(update, "linear-grow-update") == 0) { sb->raid_disks = __cpu_to_le32(info->array.raid_disks); |