Include information about PPL location and size into mdp_superblock_1 and copy it to/from rdev. Because PPL is mutually exclusive with bitmap, put it in place of 'bitmap_offset'. Add a new flag MD_FEATURE_PPL for 'feature_map', analogically to MD_FEATURE_BITMAP_OFFSET. Add MD_HAS_PPL to mddev->flags to indicate that PPL is enabled on an array.
Unified · Split
| @@ -1507,6 +1507,12 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ · 1506 unmodified lines | ||
| 1507 | 1507 | } else if (sb->bblog_offset != 0) |
| 1508 | 1508 | rdev->badblocks.shift = 0; |
| 1509 | 1509 | |
| 1510 | + if (le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL) { | |
| 1511 | + rdev->ppl.offset = (__s16)le16_to_cpu(sb->ppl.offset); | |
| 1512 | + rdev->ppl.size = le16_to_cpu(sb->ppl.size); | |
| 1513 | + rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset; | |
| 1514 | + } | |
| 1515 | + | |
| 1510 | 1516 | if (!refdev) { |
| 1511 | 1517 | ret = 1; |
| 1512 | 1518 | } else { |
| @@ -1619,6 +1625,13 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) · 106 unmodified lines | ||
| 1619 | 1625 | |
| 1620 | 1626 | if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) |
| 1621 | 1627 | set_bit(MD_HAS_JOURNAL, &mddev->flags); |
| 1628 | + | |
| 1629 | + if (le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL) { | |
| 1630 | + if (le32_to_cpu(sb->feature_map) & | |
| 1631 | + (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_JOURNAL)) | |
| 1632 | + return -EINVAL; | |
| 1633 | + set_bit(MD_HAS_PPL, &mddev->flags); | |
| 1634 | + } | |
| 1622 | 1635 | } else if (mddev->pers == NULL) { |
| 1623 | 1636 | /* Insist of good event counter while assembling, except for |
| 1624 | 1637 | * spares (which don't need an event count) */ |
| @@ -1832,6 +1845,12 @@ retry: · 207 unmodified lines | ||
| 1832 | 1845 | if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) |
| 1833 | 1846 | sb->feature_map |= cpu_to_le32(MD_FEATURE_JOURNAL); |
| 1834 | 1847 | |
| 1848 | + if (test_bit(MD_HAS_PPL, &mddev->flags)) { | |
| 1849 | + sb->feature_map |= cpu_to_le32(MD_FEATURE_PPL); | |
| 1850 | + sb->ppl.offset = cpu_to_le16(rdev->ppl.offset); | |
| 1851 | + sb->ppl.size = cpu_to_le16(rdev->ppl.size); | |
| 1852 | + } | |
| 1853 | + | |
| 1835 | 1854 | rdev_for_each(rdev2, mddev) { |
| 1836 | 1855 | i = rdev2->desc_nr; |
| 1837 | 1856 | if (test_bit(Faulty, &rdev2->flags)) |
| @@ -122,6 +122,13 @@ struct md_rdev { · 121 unmodified lines | ||
| 122 | 122 | * sysfs entry */ |
| 123 | 123 | |
| 124 | 124 | struct badblocks badblocks; |
| 125 | + | |
| 126 | + struct { | |
| 127 | + short offset; /* Offset from superblock to start of PPL. | |
| 128 | + * Not used by external metadata. */ | |
| 129 | + unsigned int size; /* Size in sectors of the PPL space */ | |
| 130 | + sector_t sector; /* First sector of the PPL space */ | |
| 131 | + } ppl; | |
| 125 | 132 | }; |
| 126 | 133 | enum flag_bits { |
| 127 | 134 | Faulty, /* device is known to have a fault */ |
| @@ -226,6 +233,7 @@ enum mddev_flags { · 98 unmodified lines | ||
| 226 | 233 | * supported as calls to md_error() will |
| 227 | 234 | * never cause the array to become failed. |
| 228 | 235 | */ |
| 236 | + MD_HAS_PPL, /* The raid array has PPL feature set */ | |
| 229 | 237 | }; |
| 230 | 238 | |
| 231 | 239 | enum mddev_sb_flags { |
| @@ -29,7 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | #define UNSUPPORTED_MDDEV_FLAGS \ |
| 30 | 30 | ((1L << MD_HAS_JOURNAL) | \ |
| 31 | 31 | (1L << MD_JOURNAL_CLEAN) | \ |
| 32 | − (1L << MD_FAILFAST_SUPPORTED)) | |
| 32 | + (1L << MD_FAILFAST_SUPPORTED) |\ | |
| 33 | + (1L << MD_HAS_PPL)) | |
| 33 | 34 | |
| 34 | 35 | static int raid0_congested(struct mddev *mddev, int bits) |
| 35 | 36 | { |
| @@ -47,7 +47,8 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #define UNSUPPORTED_MDDEV_FLAGS \ |
| 49 | 49 | ((1L << MD_HAS_JOURNAL) | \ |
| 50 | − (1L << MD_JOURNAL_CLEAN)) | |
| 50 | + (1L << MD_JOURNAL_CLEAN) | \ | |
| 51 | + (1L << MD_HAS_PPL)) | |
| 51 | 52 | |
| 52 | 53 | /* |
| 53 | 54 | * Number of guaranteed r1bios in case of extreme VM load: |
| @@ -242,10 +242,18 @@ struct mdp_superblock_1 { · 241 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | __le32 chunksize; /* in 512byte sectors */ |
| 244 | 244 | __le32 raid_disks; |
| 245 | − __le32 bitmap_offset; /* sectors after start of superblock that bitmap starts | |
| 246 | − * NOTE: signed, so bitmap can be before superblock | |
| 247 | − * only meaningful of feature_map[0] is set. | |
| 248 | − */ | |
| 245 | + union { | |
| 246 | + __le32 bitmap_offset; /* sectors after start of superblock that bitmap starts | |
| 247 | + * NOTE: signed, so bitmap can be before superblock | |
| 248 | + * only meaningful of feature_map[0] is set. | |
| 249 | + */ | |
| 250 | + | |
| 251 | + /* only meaningful when feature_map[MD_FEATURE_PPL] is set */ | |
| 252 | + struct { | |
| 253 | + __le16 offset; /* sectors from start of superblock that ppl starts (signed) */ | |
| 254 | + __le16 size; /* ppl size in sectors */ | |
| 255 | + } ppl; | |
| 256 | + }; | |
| 249 | 257 | |
| 250 | 258 | /* These are only valid with feature bit '4' */ |
| 251 | 259 | __le32 new_level; /* new level we are reshaping to */ |
| @@ -318,6 +326,7 @@ struct mdp_superblock_1 { · 66 unmodified lines | ||
| 318 | 326 | */ |
| 319 | 327 | #define MD_FEATURE_CLUSTERED 256 /* clustered MD */ |
| 320 | 328 | #define MD_FEATURE_JOURNAL 512 /* support write cache */ |
| 329 | +#define MD_FEATURE_PPL 1024 /* support PPL */ | |
| 321 | 330 | #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ |
| 322 | 331 | |MD_FEATURE_RECOVERY_OFFSET \ |
| 323 | 332 | |MD_FEATURE_RESHAPE_ACTIVE \ |
| @@ -328,6 +337,7 @@ struct mdp_superblock_1 { · 4 unmodified lines | ||
| 328 | 337 | |MD_FEATURE_RECOVERY_BITMAP \ |
| 329 | 338 | |MD_FEATURE_CLUSTERED \ |
| 330 | 339 | |MD_FEATURE_JOURNAL \ |
| 340 | + |MD_FEATURE_PPL \ | |
| 331 | 341 | ) |
| 332 | 342 | |
| 333 | 343 | struct r5l_payload_header { |