md: superblock changes for PPL
authorArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Thu, 9 Mar 2017 08:59:57 +0000 (09:59 +0100)
committerShaohua Li <shli@fb.com>
Thu, 16 Mar 2017 23:55:53 +0000 (16:55 -0700)
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.

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/md.c
drivers/md/md.h
drivers/md/raid0.c
drivers/md/raid1.c
include/uapi/linux/raid/md_p.h

index 72ef3f1..d570459 100644 (file)
@@ -1507,6 +1507,12 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
        } else if (sb->bblog_offset != 0)
                rdev->badblocks.shift = 0;
 
+       if (le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL) {
+               rdev->ppl.offset = (__s16)le16_to_cpu(sb->ppl.offset);
+               rdev->ppl.size = le16_to_cpu(sb->ppl.size);
+               rdev->ppl.sector = rdev->sb_start + rdev->ppl.offset;
+       }
+
        if (!refdev) {
                ret = 1;
        } else {
@@ -1619,6 +1625,13 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
 
                if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
                        set_bit(MD_HAS_JOURNAL, &mddev->flags);
+
+               if (le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL) {
+                       if (le32_to_cpu(sb->feature_map) &
+                           (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_JOURNAL))
+                               return -EINVAL;
+                       set_bit(MD_HAS_PPL, &mddev->flags);
+               }
        } else if (mddev->pers == NULL) {
                /* Insist of good event counter while assembling, except for
                 * spares (which don't need an event count) */
@@ -1832,6 +1845,12 @@ retry:
        if (test_bit(MD_HAS_JOURNAL, &mddev->flags))
                sb->feature_map |= cpu_to_le32(MD_FEATURE_JOURNAL);
 
+       if (test_bit(MD_HAS_PPL, &mddev->flags)) {
+               sb->feature_map |= cpu_to_le32(MD_FEATURE_PPL);
+               sb->ppl.offset = cpu_to_le16(rdev->ppl.offset);
+               sb->ppl.size = cpu_to_le16(rdev->ppl.size);
+       }
+
        rdev_for_each(rdev2, mddev) {
                i = rdev2->desc_nr;
                if (test_bit(Faulty, &rdev2->flags))
index 1c00160..a7b2f16 100644 (file)
@@ -122,6 +122,13 @@ struct md_rdev {
                                           * sysfs entry */
 
        struct badblocks badblocks;
+
+       struct {
+               short offset;   /* Offset from superblock to start of PPL.
+                                * Not used by external metadata. */
+               unsigned int size;      /* Size in sectors of the PPL space */
+               sector_t sector;        /* First sector of the PPL space */
+       } ppl;
 };
 enum flag_bits {
        Faulty,                 /* device is known to have a fault */
@@ -226,6 +233,7 @@ enum mddev_flags {
                                 * supported as calls to md_error() will
                                 * never cause the array to become failed.
                                 */
+       MD_HAS_PPL,             /* The raid array has PPL feature set */
 };
 
 enum mddev_sb_flags {
index 93347ca..56f70c3 100644 (file)
@@ -29,7 +29,8 @@
 #define UNSUPPORTED_MDDEV_FLAGS                \
        ((1L << MD_HAS_JOURNAL) |       \
         (1L << MD_JOURNAL_CLEAN) |     \
-        (1L << MD_FAILFAST_SUPPORTED))
+        (1L << MD_FAILFAST_SUPPORTED) |\
+        (1L << MD_HAS_PPL))
 
 static int raid0_congested(struct mddev *mddev, int bits)
 {
index a34f587..730e572 100644 (file)
@@ -47,7 +47,8 @@
 
 #define UNSUPPORTED_MDDEV_FLAGS                \
        ((1L << MD_HAS_JOURNAL) |       \
-        (1L << MD_JOURNAL_CLEAN))
+        (1L << MD_JOURNAL_CLEAN) |     \
+        (1L << MD_HAS_PPL))
 
 /*
  * Number of guaranteed r1bios in case of extreme VM load:
index 9930f3e..fe21128 100644 (file)
@@ -242,10 +242,18 @@ struct mdp_superblock_1 {
 
        __le32  chunksize;      /* in 512byte sectors */
        __le32  raid_disks;
-       __le32  bitmap_offset;  /* sectors after start of superblock that bitmap starts
-                                * NOTE: signed, so bitmap can be before superblock
-                                * only meaningful of feature_map[0] is set.
-                                */
+       union {
+               __le32  bitmap_offset;  /* sectors after start of superblock that bitmap starts
+                                        * NOTE: signed, so bitmap can be before superblock
+                                        * only meaningful of feature_map[0] is set.
+                                        */
+
+               /* only meaningful when feature_map[MD_FEATURE_PPL] is set */
+               struct {
+                       __le16 offset; /* sectors from start of superblock that ppl starts (signed) */
+                       __le16 size; /* ppl size in sectors */
+               } ppl;
+       };
 
        /* These are only valid with feature bit '4' */
        __le32  new_level;      /* new level we are reshaping to                */
@@ -318,6 +326,7 @@ struct mdp_superblock_1 {
                                             */
 #define MD_FEATURE_CLUSTERED           256 /* clustered MD */
 #define        MD_FEATURE_JOURNAL              512 /* support write cache */
+#define        MD_FEATURE_PPL                  1024 /* support PPL */
 #define        MD_FEATURE_ALL                  (MD_FEATURE_BITMAP_OFFSET       \
                                        |MD_FEATURE_RECOVERY_OFFSET     \
                                        |MD_FEATURE_RESHAPE_ACTIVE      \
@@ -328,6 +337,7 @@ struct mdp_superblock_1 {
                                        |MD_FEATURE_RECOVERY_BITMAP     \
                                        |MD_FEATURE_CLUSTERED           \
                                        |MD_FEATURE_JOURNAL             \
+                                       |MD_FEATURE_PPL                 \
                                        )
 
 struct r5l_payload_header {