Skip to content

Commit

Permalink
imsm: PPL support
Browse files Browse the repository at this point in the history
Enable creating and assembling IMSM raid5 arrays with PPL. Update the
IMSM metadata format to include new fields used for PPL.

Add structures for PPL metadata. They are used also by super1 and shared
with the kernel, so put them in md_p.h.

Write the initial empty PPL header when creating an array. When
assembling an array with PPL, validate the PPL header and in case it is
not correct allow to overwrite it if --force was provided.

Write the PPL location and size for a device to the new rdev sysfs
attributes 'ppl_sector' and 'ppl_size'. Enable PPL in the kernel by
writing to 'consistency_policy' before the array is activated.

Signed-off-by: Artur Paszkiewicz <[email protected]>
Signed-off-by: Jes Sorensen <[email protected]>
  • Loading branch information
apaszkie authored and Jes Sorensen committed Mar 29, 2017
1 parent 6588436 commit 2432ce9
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 24 deletions.
49 changes: 49 additions & 0 deletions Assemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -1942,6 +1942,55 @@ int assemble_container_content(struct supertype *st, int mdfd,
map_update(NULL, fd2devnm(mdfd), content->text_version,
content->uuid, chosen_name);

if (content->consistency_policy == CONSISTENCY_POLICY_PPL &&
st->ss->validate_ppl) {
content->array.state |= 1;
err = 0;

for (dev = content->devs; dev; dev = dev->next) {
int dfd;
char *devpath;
int ret;

ret = st->ss->validate_ppl(st, content, dev);
if (ret == 0)
continue;

if (ret < 0) {
err = 1;
break;
}

if (!c->force) {
pr_err("%s contains invalid PPL - consider --force or --update-subarray with --update=no-ppl\n",
chosen_name);
content->array.state &= ~1;
avail[dev->disk.raid_disk] = 0;
break;
}

/* have --force - overwrite the invalid ppl */
devpath = map_dev(dev->disk.major, dev->disk.minor, 0);
dfd = dev_open(devpath, O_RDWR);
if (dfd < 0) {
pr_err("Failed to open %s\n", devpath);
err = 1;
break;
}

err = st->ss->write_init_ppl(st, content, dfd);
close(dfd);

if (err)
break;
}

if (err) {
free(avail);
return err;
}
}

if (enough(content->array.level, content->array.raid_disks,
content->array.layout, content->array.state & 1, avail) == 0) {
if (c->export && result)
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ MON_OBJS = mdmon.o monitor.o managemon.o util.o maps.o mdstat.o sysfs.o \
Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \
super-mbr.o super-gpt.o \
super-ddf.o sha1.o crc32.o msg.o bitmap.o xmalloc.o \
platform-intel.o probe_roms.o
platform-intel.o probe_roms.o crc32c.o

MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS))

Expand All @@ -161,7 +161,8 @@ STATICOBJS = pwgr.o
ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c policy.c dlink.c util.c \
maps.c lib.c xmalloc.c \
super0.c super1.c super-ddf.c super-intel.c sha1.c crc32.c sg_io.c mdstat.c \
platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c mapfile.c
platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c mapfile.c \
crc32c.c
ASSEMBLE_AUTO_SRCS := mdopen.c
ASSEMBLE_FLAGS:= $(CFLAGS) -DMDASSEMBLE
ifdef MDASSEMBLE_AUTO
Expand Down
25 changes: 25 additions & 0 deletions md_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,29 @@ struct r5l_meta_block {
#define R5LOG_VERSION 0x1
#define R5LOG_MAGIC 0x6433c509

struct ppl_header_entry {
__u64 data_sector; /* raid sector of the new data */
__u32 pp_size; /* length of partial parity */
__u32 data_size; /* length of data */
__u32 parity_disk; /* member disk containing parity */
__u32 checksum; /* checksum of this entry's partial parity */
} __attribute__ ((__packed__));

#define PPL_HEADER_SIZE 4096
#define PPL_HDR_RESERVED 512
#define PPL_HDR_ENTRY_SPACE \
(PPL_HEADER_SIZE - PPL_HDR_RESERVED - 4 * sizeof(__u32) - sizeof(__u64))
#define PPL_HDR_MAX_ENTRIES \
(PPL_HDR_ENTRY_SPACE / sizeof(struct ppl_header_entry))

struct ppl_header {
__u8 reserved[PPL_HDR_RESERVED];/* reserved space, fill with 0xff */
__u32 signature; /* signature (family number of volume) */
__u32 padding; /* zero pad */
__u64 generation; /* generation number of the header */
__u32 entries_count; /* number of entries in entry array */
__u32 checksum; /* checksum of the header */
struct ppl_header_entry entries[PPL_HDR_MAX_ENTRIES];
} __attribute__ ((__packed__));

#endif
6 changes: 6 additions & 0 deletions mdadm.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ struct mdinfo {
#define MaxSector (~0ULL) /* resync/recovery complete position */
};
long bitmap_offset; /* 0 == none, 1 == a file */
unsigned int ppl_size;
unsigned long long ppl_sector;
unsigned long safe_mode_delay; /* ms delay to mark clean */
int new_level, delta_disks, new_layout, new_chunk;
int errors;
Expand Down Expand Up @@ -1074,6 +1076,10 @@ extern struct superswitch {
/* write initial empty PPL on device */
int (*write_init_ppl)(struct supertype *st, struct mdinfo *info, int fd);

/* validate ppl before assemble */
int (*validate_ppl)(struct supertype *st, struct mdinfo *info,
struct mdinfo *disk);

/* records new bad block in metadata */
int (*record_bad_block)(struct active_array *a, int n,
unsigned long long sector, int length);
Expand Down
Loading

0 comments on commit 2432ce9

Please sign in to comment.