diff options
author | Tomasz Majchrzak <tomasz.majchrzak@intel.com> | 2016-11-28 15:07:05 +0100 |
---|---|---|
committer | Jes Sorensen <Jes.Sorensen@redhat.com> | 2016-11-28 23:44:45 +0100 |
commit | bb758ccad0e9e47af565d4e23b43aa5a8ceb9886 (patch) | |
tree | ed51e5d7c2274b11fdff0af1db89dfe8491c490c /sysfs.c | |
parent | IMSM: Update num_data_stripes during migration (diff) | |
download | mdadm-bb758ccad0e9e47af565d4e23b43aa5a8ceb9886.tar.xz mdadm-bb758ccad0e9e47af565d4e23b43aa5a8ceb9886.zip |
mdadm: bad block support for external metadata - initialization
If metadata handler provides support for bad blocks, tell md by writing
'external_bbl' to rdev state file (both on create and assemble),
followed by a list of known bad blocks written via sysfs 'bad_blocks'
file.
Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
Reviewed-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 27 |
1 files changed, 26 insertions, 1 deletions
@@ -52,8 +52,10 @@ void sysfs_free(struct mdinfo *sra) while (sra->devs) { struct mdinfo *d = sra->devs; sra->devs = d->next; + free(d->bb.entries); free(d); } + free(sra->bb.entries); free(sra); sra = sra2; } @@ -261,7 +263,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) dbase = base + strlen(base); *dbase++ = '/'; - dev = xmalloc(sizeof(*dev)); + dev = xcalloc(1, sizeof(*dev)); /* Always get slot, major, minor */ strcpy(dbase, "slot"); @@ -691,6 +693,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) char nm[PATH_MAX]; char *dname; int rv; + int i; sprintf(dv, "%d:%d", sd->disk.major, sd->disk.minor); rv = sysfs_set_str(sra, NULL, "new_dev", dv); @@ -722,6 +725,28 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) if (resume) sysfs_set_num(sra, sd, "recovery_start", sd->recovery_start); } + if (sd->bb.supported) { + if (sysfs_set_str(sra, sd, "state", "external_bbl")) { + /* + * backward compatibility - if kernel doesn't support + * bad blocks for external metadata, let it continue + * as long as there are none known so far + */ + if (sd->bb.count) { + pr_err("The kernel has no support for bad blocks in external metadata\n"); + return -1; + } + } + + for (i = 0; i < sd->bb.count; i++) { + char s[30]; + const struct md_bb_entry *entry = &sd->bb.entries[i]; + + snprintf(s, sizeof(s) - 1, "%llu %d\n", entry->sector, + entry->length); + rv |= sysfs_set_str(sra, sd, "bad_blocks", s); + } + } return rv; } |