aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-raid.c
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2016-05-19 12:49:32 -0400
committerMike Snitzer <snitzer@redhat.com>2016-06-14 17:09:35 -0400
commit7b34df74d27b2a2350426daec80cda5d3c873622 (patch)
tree3a518bf2edc5e9458ebd120e3e102e055a859e38 /drivers/md/dm-raid.c
parent4763e543a679053be345e1129bcb5df78f849294 (diff)
dm raid: enhance super_sync() to support new superblock members
Add transferring the new takeover/reshape related superblock members introduced to the super_sync() function: - add/move supporting functions - add failed devices bitfield transfer functions to retrieve the bitfield from superblock format or update it in the superblock - add code to transfer all new members Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-raid.c')
-rw-r--r--drivers/md/dm-raid.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index bc5a53dfaa07..28420337f880 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -214,6 +214,12 @@ static bool _test_flags(uint32_t flags, uint32_t all_flags)
214 return (flags & all_flags) ? true : false; 214 return (flags & all_flags) ? true : false;
215} 215}
216 216
217/* Clear (multiple) @flags in @all_flags */
218static void _clear_flags(uint32_t flags, uint32_t *all_flags)
219{
220 *all_flags &= ~flags;
221}
222
217/* Return true if single @flag is set in @*flags, else set it and return false */ 223/* Return true if single @flag is set in @*flags, else set it and return false */
218static bool _test_and_set_flag(uint32_t flag, uint32_t *flags) 224static bool _test_and_set_flag(uint32_t flag, uint32_t *flags)
219{ 225{
@@ -1289,31 +1295,54 @@ static void sb_retrieve_failed_devices(struct dm_raid_superblock *sb, uint64_t *
1289 } 1295 }
1290} 1296}
1291 1297
1298static void sb_update_failed_devices(struct dm_raid_superblock *sb, uint64_t *failed_devices)
1299{
1300 int i = ARRAY_SIZE(sb->extended_failed_devices);
1301
1302 sb->failed_devices = cpu_to_le64(failed_devices[0]);
1303 while (i--)
1304 sb->extended_failed_devices[i] = cpu_to_le64(failed_devices[i+1]);
1305}
1306
1307/*
1308 * Synchronize the superblock members with the raid set properties
1309 *
1310 * All superblock data is little endian.
1311 */
1292static void super_sync(struct mddev *mddev, struct md_rdev *rdev) 1312static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
1293{ 1313{
1294 int i; 1314 bool update_failed_devices = false;
1295 uint64_t failed_devices; 1315 unsigned int i;
1316 uint64_t failed_devices[DISKS_ARRAY_ELEMS];
1296 struct dm_raid_superblock *sb; 1317 struct dm_raid_superblock *sb;
1297 struct raid_set *rs = container_of(mddev, struct raid_set, md); 1318 struct raid_set *rs = container_of(mddev, struct raid_set, md);
1298 1319
1320 /* No metadata device, no superblock */
1321 if (!rdev->meta_bdev)
1322 return;
1323
1324 BUG_ON(!rdev->sb_page);
1325
1299 sb = page_address(rdev->sb_page); 1326 sb = page_address(rdev->sb_page);
1300 failed_devices = le64_to_cpu(sb->failed_devices);
1301 1327
1302 for (i = 0; i < mddev->raid_disks; i++) 1328 sb_retrieve_failed_devices(sb, failed_devices);
1303 if (!rs->dev[i].data_dev ||
1304 test_bit(Faulty, &(rs->dev[i].rdev.flags)))
1305 failed_devices |= (1ULL << i);
1306 1329
1307 memset(sb + 1, 0, rdev->sb_size - sizeof(*sb)); 1330 for (i = 0; i < rs->raid_disks; i++)
1331 if (!rs->dev[i].data_dev || test_bit(Faulty, &rs->dev[i].rdev.flags)) {
1332 update_failed_devices = true;
1333 set_bit(i, (void *) failed_devices);
1334 }
1335
1336 if (update_failed_devices)
1337 sb_update_failed_devices(sb, failed_devices);
1308 1338
1309 sb->magic = cpu_to_le32(DM_RAID_MAGIC); 1339 sb->magic = cpu_to_le32(DM_RAID_MAGIC);
1310 sb->compat_features = cpu_to_le32(0); /* No features yet */ 1340 sb->compat_features = cpu_to_le32(0); /* Don't set reshape flag yet */
1311 1341
1312 sb->num_devices = cpu_to_le32(mddev->raid_disks); 1342 sb->num_devices = cpu_to_le32(mddev->raid_disks);
1313 sb->array_position = cpu_to_le32(rdev->raid_disk); 1343 sb->array_position = cpu_to_le32(rdev->raid_disk);
1314 1344
1315 sb->events = cpu_to_le64(mddev->events); 1345 sb->events = cpu_to_le64(mddev->events);
1316 sb->failed_devices = cpu_to_le64(failed_devices);
1317 1346
1318 sb->disk_recovery_offset = cpu_to_le64(rdev->recovery_offset); 1347 sb->disk_recovery_offset = cpu_to_le64(rdev->recovery_offset);
1319 sb->array_resync_offset = cpu_to_le64(mddev->recovery_cp); 1348 sb->array_resync_offset = cpu_to_le64(mddev->recovery_cp);
@@ -1321,6 +1350,32 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
1321 sb->level = cpu_to_le32(mddev->level); 1350 sb->level = cpu_to_le32(mddev->level);
1322 sb->layout = cpu_to_le32(mddev->layout); 1351 sb->layout = cpu_to_le32(mddev->layout);
1323 sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors); 1352 sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors);
1353
1354 sb->new_level = cpu_to_le32(mddev->new_level);
1355 sb->new_layout = cpu_to_le32(mddev->new_layout);
1356 sb->new_stripe_sectors = cpu_to_le32(mddev->new_chunk_sectors);
1357
1358 sb->delta_disks = cpu_to_le32(mddev->delta_disks);
1359
1360 smp_rmb(); /* Make sure we access most recent reshape position */
1361 sb->reshape_position = cpu_to_le64(mddev->reshape_position);
1362 if (le64_to_cpu(sb->reshape_position) != MaxSector) {
1363 /* Flag ongoing reshape */
1364 sb->flags |= cpu_to_le32(SB_FLAG_RESHAPE_ACTIVE);
1365
1366 if (mddev->delta_disks < 0 || mddev->reshape_backwards)
1367 sb->flags |= cpu_to_le32(SB_FLAG_RESHAPE_BACKWARDS);
1368 } else
1369 /* Flag no reshape */
1370 _clear_flags(cpu_to_le32(SB_FLAG_RESHAPE_ACTIVE|SB_FLAG_RESHAPE_BACKWARDS), &sb->flags);
1371
1372 sb->array_sectors = cpu_to_le64(mddev->array_sectors);
1373 sb->data_offset = cpu_to_le64(rdev->data_offset);
1374 sb->new_data_offset = cpu_to_le64(rdev->new_data_offset);
1375 sb->sectors = cpu_to_le64(rdev->sectors);
1376
1377 /* Zero out the rest of the payload after the size of the superblock */
1378 memset(sb + 1, 0, rdev->sb_size - sizeof(*sb));
1324} 1379}
1325 1380
1326/* 1381/*