diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2007-04-19 22:12:42 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2007-04-19 22:12:42 +0000 |
commit | 240e8f61db8a357d01cf10b698e8bf6c56a7c8d0 (patch) | |
tree | 7927e701755f51fac3bfe1f591439b1ee69d5a4b /sys/dev/softraid.c | |
parent | ec9a189b97f9983e9dd0650a8fbc1d85dc7743af (diff) |
Save volume and chunk metadata as well.
Diffstat (limited to 'sys/dev/softraid.c')
-rw-r--r-- | sys/dev/softraid.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c index f31841299d1..856dbe728f9 100644 --- a/sys/dev/softraid.c +++ b/sys/dev/softraid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid.c,v 1.24 2007/04/19 02:44:29 marco Exp $ */ +/* $OpenBSD: softraid.c,v 1.25 2007/04/19 22:12:41 marco Exp $ */ /* * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us> * @@ -706,7 +706,7 @@ int sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc) { char *devl; - int i, s, no_chunk, rv = EINVAL, sb = -1; + int i, s, no_chunk, rv = EINVAL, sb = -1, vol; size_t bytes = 0; u_quad_t vol_size, max_chunk_sz = 0, min_chunk_sz; struct sr_chunk_head *cl; @@ -843,13 +843,19 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc) if (dev == NULL) goto unwind; + /* fill out volume metadata */ + strlcpy(sd->sd_vol.sv_meta.svm_devname, dev->dv_xname, sizeof(sd->sd_vol.sv_meta.svm_devname)); DNPRINTF(SR_D_IOCTL, "%s: sr device added: %s on scsibus: %d\n", DEVNAME(sc), dev->dv_xname, sd->sd_link.scsibus); sc->sc_dis[sd->sd_link.scsibus] = sd; - sb = sd->sd_link.scsibus; + sb = sd->sd_link.scsibus; /* XXX remove this */ + for (i = 0, vol = -1; i <= sd->sd_link.scsibus; i++) + if (sc->sc_dis[i]) + vol++; + sd->sd_vol.sv_meta.svm_volid = vol; rv = sr_save_metadata(sd); /* save metadata to disk */ @@ -1072,7 +1078,6 @@ sr_raid1_alloc_resources(struct sr_discipline *sd) sd->sd_meta = malloc(SR_META_SIZE * 512 , M_DEVBUF, M_WAITOK); bzero(sd->sd_meta, SR_META_SIZE * 512); - rv = 0; return (rv); } @@ -1756,6 +1761,8 @@ sr_save_metadata(struct sr_discipline *sd) { struct sr_softc *sc = sd->sd_sc; struct sr_metadata *sm = sd->sd_meta; + struct sr_vol_meta *sv = &sd->sd_vol.sv_meta, *im_sv;; + struct sr_chunk_meta *im_sc; struct sr_chunk *src; struct buf b; int i, rv = 1; @@ -1764,6 +1771,14 @@ sr_save_metadata(struct sr_discipline *sd) DNPRINTF(SR_D_META, "%s: sr_save_metadata %s\n", DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname); + if (!sm) { + printf("%s: no in memory copy of metadata\n", DEVNAME(sc)); + goto bad; + } + + im_sv = (struct sr_vol_meta *)(sm + 1); + im_sc = (struct sr_chunk_meta *)(im_sv + 1); + if (sm->ssd_magic == 0) { /* initial metadata */ sm->ssd_magic = SR_MAGIC; @@ -1777,15 +1792,30 @@ sr_save_metadata(struct sr_discipline *sd) sr_get_uuid(&sm->ssd_uuid); /* volume */ + bcopy(sv, im_sv, sizeof(struct sr_metadata)); + bcopy(&sm->ssd_uuid, &im_sv->svm_uuid, + sizeof(im_sv->svm_uuid)); sm->ssd_vd_ver = SR_VOL_VERSION; sm->ssd_vd_size = sizeof(struct sr_vol_meta); + /* chunk */ + /* XXX do some sanity to prevent too many disks */ + for (i = 0; i < sd->sd_vol.sv_meta.svm_no_chunk; i++) { + bcopy(&sm->ssd_uuid, + &sd->sd_vol.sv_chunks[i]->src_meta.scm_uuid, + sizeof(struct sr_uuid)); + bcopy(sd->sd_vol.sv_chunks[i], &im_sc[i], + sizeof(struct sr_chunk_meta)); + } sm->ssd_chunk_ver = SR_CHUNK_VERSION; sm->ssd_chunk_size = sizeof(struct sr_chunk_meta); sm->ssd_chunk_no = sd->sd_vol.sv_meta.svm_no_chunk; } + /* from here on out metadata is updated */ + sm->ssd_ondisk++; + #ifdef SR_DEBUG /* metadata */ DNPRINTF(SR_D_META, "\tmagic 0x%llx\n", sm->ssd_magic); @@ -1804,6 +1834,11 @@ sr_save_metadata(struct sr_discipline *sd) memset(&b, 0, sizeof(b)); src = sd->sd_vol.sv_chunks[i]; + + /* skip disks that are offline */ + if (src->src_meta.scm_status == BIOC_SDOFFLINE) + continue; + b.b_flags = B_WRITE; b.b_blkno = 2; /* skip past mbr and partition table */ b.b_bcount = sz; @@ -1821,6 +1856,7 @@ sr_save_metadata(struct sr_discipline *sd) biowait(&b); /* XXX do something smart here */ + /* marck chunk offline and restart metadata write */ if (b.b_flags & B_ERROR) { printf("%s: %s i/o error on block %d while writing " "metadata %d\n", DEVNAME(sc), |