From 2b96188328077d6caeb059080499fe9949e03351 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 18 Jun 2007 05:13:43 +0000 Subject: [PATCH] Move all the code related to handling the current 32 bit disklabel to subr_disklabel32.c. Move the header file from sys/disklabel.h to sys/disklabel32.h. Rename all the related structures and constants and retire 'struct disklabel'. Redo the sys/disklabel.h header file to implement a generic disklabel abstraction. Modify kern/subr_diskslice.c to use this abstraction, with some shims for the ops dispatch at the moment which will be cleaned up later. Adjust all auxillary code that directly accesses 32 bit disklabels to use the new structure and constant names. Remove the snoop-adjust code. The kernel would snoop reads and writes to the disklabel area via the raw slice device (e.g. ad0s1) and convert the disklabel from the in-core format to the on-disk format and vise-versa. The reads and writes made by disklabel -r and the kernel's own internal readdisklabel and writedisklabel code used the snooping. Rearrange the kernel's internal code to manually convert the disklabel when reading and writing. Rearrange the /sbin/disklabel program to do the same when the -r option is used. Have the disklabel program also check which DragonFly OS it is running under so it can be run on older systems. Note that the disklabel binary prior to these changes will NOT operate on the disklabel properly if running on a NEW kernel. Introduce skeleton files for 64 bit disklabel support. --- include/disktab.h | 6 +- lib/libc/gen/disklabel.c | 20 +-- lib/libc/gen/getdiskbyname.3 | 6 +- lib/libstand/stand.h | 6 +- sbin/disklabel/disklabel.8 | 20 ++- sbin/disklabel/disklabel.c | 279 +++++++++++++++++++--------- sbin/gpt/migrate.c | 14 +- sbin/vinum/list.c | 10 +- sys/boot/efi/libefi/devicename.c | 4 +- sys/boot/ia64/libski/devicename.c | 6 +- sys/boot/pc32/boot2/boot2.c | 12 +- sys/boot/pc32/libi386/biosdisk.c | 24 +-- sys/boot/pc32/libi386/devicename.c | 6 +- sys/conf/files | 4 +- sys/kern/subr_disklabel32.c | 269 +++++++++++++++------------ sys/kern/subr_diskslice.c | 211 ++++++---------------- sys/sys/disklabel.h | 257 +++++++------------------- sys/sys/disklabel32.h | 71 +++----- sys/sys/disklabel64.h | 103 +++++++++++ sys/sys/diskslice.h | 10 +- sys/sys/ndisklabel.h | 127 ------------- sys/sys/odisklabel.h | 280 ----------------------------- sys/sys/param.h | 4 +- 23 files changed, 696 insertions(+), 1053 deletions(-) create mode 100644 sys/sys/disklabel64.h delete mode 100644 sys/sys/ndisklabel.h delete mode 100644 sys/sys/odisklabel.h diff --git a/include/disktab.h b/include/disktab.h index eefa5ef2e0..93b200c124 100644 --- a/include/disktab.h +++ b/include/disktab.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)disktab.h 8.1 (Berkeley) 6/2/93 - * $DragonFly: src/include/disktab.h,v 1.3 2007/05/17 23:49:58 dillon Exp $ + * $DragonFly: src/include/disktab.h,v 1.4 2007/06/18 05:13:33 dillon Exp $ */ #ifndef _DISKTAB_H_ @@ -103,9 +103,9 @@ struct disktab { #ifndef _KERNEL __BEGIN_DECLS -struct disklabel; +struct disklabel32; struct disktab *getdisktabbyname (const char *); -struct disklabel *getdiskbyname (const char *); +struct disklabel32 *getdiskbyname (const char *); __END_DECLS #endif diff --git a/lib/libc/gen/disklabel.c b/lib/libc/gen/disklabel.c index 391e83595b..ac529bbf06 100644 --- a/lib/libc/gen/disklabel.c +++ b/lib/libc/gen/disklabel.c @@ -32,12 +32,12 @@ * * @(#)disklabel.c 8.2 (Berkeley) 5/3/95 * $FreeBSD: src/lib/libc/gen/disklabel.c,v 1.9.2.1 2001/03/05 08:40:47 obrien Exp $ - * $DragonFly: src/lib/libc/gen/disklabel.c,v 1.12 2007/06/17 23:50:13 dillon Exp $ + * $DragonFly: src/lib/libc/gen/disklabel.c,v 1.13 2007/06/18 05:13:34 dillon Exp $ */ #include #define DKTYPENAMES -#include +#include #include #include #include @@ -52,12 +52,12 @@ static int gettype (const char *, const char **); -struct disklabel * +struct disklabel32 * getdiskbyname(const char *name) { - static struct disklabel disk; - struct disklabel *dp = &disk; - struct partition *pp; + static struct disklabel32 disk; + struct disklabel32 *dp = &disk; + struct partition32 *pp; char *buf; char *db_array[2] = { _PATH_DISKTAB, 0 }; char *cp, *cq; /* can't be register */ @@ -108,7 +108,7 @@ getdiskbyname(const char *name) strcpy(ptype, "tx"); max = 'a' - 1; pp = &dp->d_partitions[0]; - for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { + for (p = 'a'; p < 'a' + MAXPARTITIONS32; p++, pp++) { long l; psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; if (cgetnum(buf, psize, &l) == -1) @@ -135,12 +135,12 @@ getdiskbyname(const char *name) dp->d_npartitions = max + 1 - 'a'; strcpy(psize, "dx"); dx = dp->d_drivedata; - for (p = '0'; p < '0' + NDDATA; p++, dx++) { + for (p = '0'; p < '0' + NDDATA32; p++, dx++) { psize[1] = p; getnumdflt(*dx, psize, 0); } - dp->d_magic = DISKMAGIC; - dp->d_magic2 = DISKMAGIC; + dp->d_magic = DISKMAGIC32; + dp->d_magic2 = DISKMAGIC32; free(buf); return (dp); } diff --git a/lib/libc/gen/getdiskbyname.3 b/lib/libc/gen/getdiskbyname.3 index c0916140a9..15e87d5a8c 100644 --- a/lib/libc/gen/getdiskbyname.3 +++ b/lib/libc/gen/getdiskbyname.3 @@ -31,7 +31,7 @@ .\" .\" @(#)getdiskbyname.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD: src/lib/libc/gen/getdiskbyname.3,v 1.3.2.4 2001/12/14 18:33:51 ru Exp $ -.\" $DragonFly: src/lib/libc/gen/getdiskbyname.3,v 1.3 2007/05/17 23:53:44 dillon Exp $ +.\" $DragonFly: src/lib/libc/gen/getdiskbyname.3,v 1.4 2007/06/18 05:13:34 dillon Exp $ .\" .Dd June 4, 1993 .Dt GETDISKBYNAME 3 @@ -43,8 +43,8 @@ .Lb libc .Sh SYNOPSIS .In disktab.h -.In sys/disklabel.h -.Ft struct disklabel * +.In sys/disklabel32.h +.Ft struct disklabel32 * .Fn getdiskbyname "const char *name" .Sh DESCRIPTION The diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h index 201dbb1a6c..ea80e60e78 100644 --- a/lib/libstand/stand.h +++ b/lib/libstand/stand.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/lib/libstand/stand.h,v 1.18.2.8 2002/06/17 11:22:39 sobomax Exp $ - * $DragonFly: src/lib/libstand/stand.h,v 1.8 2005/12/11 02:27:26 swildner Exp $ + * $DragonFly: src/lib/libstand/stand.h,v 1.9 2007/06/18 05:13:37 dillon Exp $ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $ */ @@ -251,8 +251,8 @@ extern void *reallocf(void *, size_t); extern void mallocstats(void); /* disklabel support (undocumented, may be junk) */ -struct disklabel; -extern char *getdisklabel(const char *, struct disklabel *); +struct disklabel32; +extern char *getdisklabel32(const char *, struct disklabel32 *); extern int printf(const char *, ...); extern void vprintf(const char *, __va_list); diff --git a/sbin/disklabel/disklabel.8 b/sbin/disklabel/disklabel.8 index 719b14a606..0c20c805cc 100644 --- a/sbin/disklabel/disklabel.8 +++ b/sbin/disklabel/disklabel.8 @@ -34,7 +34,7 @@ .\" .\" @(#)disklabel.8 8.2 (Berkeley) 4/19/94 .\" $FreeBSD: src/sbin/disklabel/disklabel.8,v 1.15.2.22 2003/04/17 17:56:34 trhodes Exp $ -.\" $DragonFly: src/sbin/disklabel/disklabel.8,v 1.13 2007/05/17 08:19:01 swildner Exp $ +.\" $DragonFly: src/sbin/disklabel/disklabel.8,v 1.14 2007/06/18 05:13:38 dillon Exp $ .\" .Dd January 21, 2007 .Dt DISKLABEL 8 @@ -94,6 +94,9 @@ .Oc .Ar disk Ar protofile .Oo Ar disktype/auto Oc +.Nm +.Fl f Ar slice_start_lba +.Oo Ar options Oc .Sh DESCRIPTION The .Nm @@ -712,6 +715,21 @@ The asterisk .Pq Ql * indicates that the partition does not begin or end exactly on a cylinder boundary. +.Pp +.Dx +no longer snoop-adjusts the on-disklabel when reading or writing +raw labels. +.Nm +is now responsible for adjusting the label when operating in raw mode. +Traditional (32 bit BSD) disklabels store offsets as absolute block numbers +rather than slice-relative block numbers. +If +.Nm +is unable to issue the DIOCGPART ioctl to get slice information it will +refuse to read or write the label in raw mode. +The +.Fl f +option may be used to force the operation by supplying a manual offset. .Sh EXAMPLES .Dl "disklabel da0s1" .Pp diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index e56a67c0a8..eb0bd3b6b4 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -37,7 +37,7 @@ * @(#)disklabel.c 1.2 (Symmetric) 11/28/85 * @(#)disklabel.c 8.2 (Berkeley) 1/7/94 * $FreeBSD: src/sbin/disklabel/disklabel.c,v 1.28.2.15 2003/01/24 16:18:16 des Exp $ - * $DragonFly: src/sbin/disklabel/disklabel.c,v 1.20 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sbin/disklabel/disklabel.c,v 1.21 2007/06/18 05:13:38 dillon Exp $ */ #include @@ -45,10 +45,12 @@ #include #include #define DKTYPENAMES -#include +#include +#include #include #include #include +#include #include #include @@ -90,25 +92,26 @@ #define NUMBOOT 2 -void makelabel(const char *, const char *, struct disklabel *); -int writelabel(int, const char *, struct disklabel *); +void makelabel(const char *, const char *, struct disklabel32 *); +int writelabel(int, const char *, struct disklabel32 *); void l_perror(const char *); -struct disklabel *readlabel(int); -struct disklabel *makebootarea(char *, struct disklabel *, int); -void display(FILE *, const struct disklabel *); -int edit(struct disklabel *, int); +struct disklabel32 *readlabel(int); +struct disklabel32 *makebootarea(char *, struct disklabel32 *, int); +void display(FILE *, const struct disklabel32 *); +int edit(struct disklabel32 *, int); int editit(void); char *skip(char *); char *word(char *); -int getasciilabel(FILE *, struct disklabel *); -int getasciipartspec(char *, struct disklabel *, int, int); -int checklabel(struct disklabel *); -void setbootflag(struct disklabel *); +int getasciilabel(FILE *, struct disklabel32 *); +int getasciipartspec(char *, struct disklabel32 *, int, int); +int checklabel(struct disklabel32 *); +void setbootflag(struct disklabel32 *); void Warning(const char *, ...) __printflike(1, 2); void usage(void); int checkoldboot(int, const char *); -struct disklabel *getvirginlabel(void); -struct disklabel *getdisklabelfromdisktab(const char *name); +const char *fixlabel(int, struct disklabel32 *, int); +struct disklabel32 *getvirginlabel(void); +struct disklabel32 *getdisklabelfromdisktab(const char *name); #define DEFEDITOR _PATH_VI #define streq(a,b) (strcmp(a,b) == 0) @@ -118,7 +121,7 @@ char *specname; char tmpfil[] = PATH_TMPFILE; char namebuf[BBSIZE], *np = namebuf; -struct disklabel lab; +struct disklabel32 lab; char bootarea[BBSIZE]; #define MAX_PART ('z') @@ -143,18 +146,20 @@ enum { int rflag; int disable_write; /* set to disable writing to disk label */ +int forceflag; +u_int32_t slice_start_lba; #ifdef DEBUG int debug; -#define OPTIONS "BNRWb:denrs:w" +#define OPTIONS "BNRWb:def:nrs:w" #else -#define OPTIONS "BNRWb:enrs:w" +#define OPTIONS "BNRWb:ef:nrs:w" #endif int main(int argc, char *argv[]) { - struct disklabel *lp; + struct disklabel32 *lp; FILE *t; int ch, f = 0, flag, error = 0; char *name = 0; @@ -168,6 +173,11 @@ main(int argc, char *argv[]) case 'b': xxboot = optarg; break; + + case 'f': + forceflag = 1; + slice_start_lba = strtoul(optarg, NULL, 0); + break; #if NUMBOOT > 1 case 's': bootxx = optarg; @@ -327,7 +337,7 @@ main(int argc, char *argv[]) #if NUMBOOT > 0 case WRITEBOOT: { - struct disklabel tlab; + struct disklabel32 tlab; lp = readlabel(f); tlab = *lp; @@ -350,9 +360,9 @@ main(int argc, char *argv[]) * if specified. */ void -makelabel(const char *type, const char *name, struct disklabel *lp) +makelabel(const char *type, const char *name, struct disklabel32 *lp) { - struct disklabel *dp; + struct disklabel32 *dp; if (strcmp(type, "auto") == 0) dp = getvirginlabel(); @@ -370,10 +380,9 @@ makelabel(const char *type, const char *name, struct disklabel *lp) } int -writelabel(int f, const char *boot, struct disklabel *lp) +writelabel(int f, const char *boot, struct disklabel32 *lp) { - int yes = 1; - int no = 0; + const char *msg; int flag; int r; @@ -386,10 +395,10 @@ writelabel(int f, const char *boot, struct disklabel *lp) if (checkoldboot(f, boot)) errx(4, "Will not overwrite old bootblocks w/ label, install new boot blocks first!"); setbootflag(lp); - lp->d_magic = DISKMAGIC; - lp->d_magic2 = DISKMAGIC; + lp->d_magic = DISKMAGIC32; + lp->d_magic2 = DISKMAGIC32; lp->d_checksum = 0; - lp->d_checksum = dkcksum(lp); + lp->d_checksum = dkcksum32(lp); if (rflag) { /* * First set the kernel disk label, @@ -399,7 +408,7 @@ writelabel(int f, const char *boot, struct disklabel *lp) * may prevent us from changing the current (in-core) * label. */ - if (ioctl(f, DIOCSDINFO, lp) < 0 && + if (ioctl(f, DIOCSDINFO32, lp) < 0 && errno != ENODEV && errno != ENOTTY) { l_perror("ioctl DIOCSDINFO"); return (1); @@ -413,7 +422,13 @@ writelabel(int f, const char *boot, struct disklabel *lp) flag = 1; if (ioctl(f, DIOCWLABEL, &flag) < 0) warn("ioctl DIOCWLABEL"); + msg = fixlabel(f, lp, 1); + if (msg) { + warn(msg); + return (1); + } r = write(f, boot, lp->d_bbsize); + fixlabel(f, lp, 0); if (r != ((ssize_t)lp->d_bbsize)) { warn("write"); return (1); @@ -423,9 +438,9 @@ writelabel(int f, const char *boot, struct disklabel *lp) * Output the remainder of the disklabel */ if (bootbuf) { - ioctl(f, DIOCSETSNOOP, &yes); + fixlabel(f, lp, 1); r = write(f, bootbuf, bootsize); - ioctl(f, DIOCSETSNOOP, &no); + fixlabel(f, lp, 0); if (r != bootsize) { warn("write"); return(1); @@ -434,7 +449,7 @@ writelabel(int f, const char *boot, struct disklabel *lp) #endif flag = 0; ioctl(f, DIOCWLABEL, &flag); - } else if (ioctl(f, DIOCWDINFO, lp) < 0) { + } else if (ioctl(f, DIOCWDINFO32, lp) < 0) { l_perror("ioctl DIOCWDINFO"); return (1); } @@ -476,35 +491,35 @@ l_perror(const char *s) * Fetch disklabel for disk. * Use ioctl to get label unless -r flag is given. */ -struct disklabel * +struct disklabel32 * readlabel(int f) { - struct disklabel *lp; + const char *msg; + struct disklabel32 *lp; int r; - int yes = 1; - int no = 0; if (rflag) { - if (ioctl(f, DIOCSETSNOOP, &yes) < 0) - printf("BAD SNOOP\n"); r = read(f, bootarea, BBSIZE); - ioctl(f, DIOCSETSNOOP, &no); if (r < BBSIZE) err(4, "%s", specname); - for (lp = (struct disklabel *)bootarea; - lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); - lp = (struct disklabel *)((char *)lp + 16)) - if (lp->d_magic == DISKMAGIC && - lp->d_magic2 == DISKMAGIC) + for (lp = (struct disklabel32 *)bootarea; + lp <= (struct disklabel32 *)(bootarea + BBSIZE - sizeof(*lp)); + lp = (struct disklabel32 *)((char *)lp + 16)) { + if (lp->d_magic == DISKMAGIC32 && + lp->d_magic2 == DISKMAGIC32) break; - if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || - lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || - dkcksum(lp) != 0) - errx(1, - "bad pack magic number (label is damaged, or pack is unlabeled)"); + } + if (lp > (struct disklabel32 *)(bootarea+BBSIZE-sizeof(*lp)) || + lp->d_magic != DISKMAGIC32 || lp->d_magic2 != DISKMAGIC32 || + dkcksum32(lp) != 0) { + errx(1, "bad pack magic number (label is damaged, " + "or pack is unlabeled)"); + } + if ((msg = fixlabel(f, lp, 0)) != NULL) + errx(1, msg); } else { lp = &lab; - if (ioctl(f, DIOCGDINFO, lp) < 0) + if (ioctl(f, DIOCGDINFO32, lp) < 0) err(4, "ioctl DIOCGDINFO"); } return (lp); @@ -514,10 +529,10 @@ readlabel(int f) * Construct a bootarea (d_bbsize bytes) in the specified buffer ``boot'' * Returns a pointer to the disklabel portion of the bootarea. */ -struct disklabel * -makebootarea(char *boot, struct disklabel *dp, int f) +struct disklabel32 * +makebootarea(char *boot, struct disklabel32 *dp, int f) { - struct disklabel *lp; + struct disklabel32 *lp; char *p; int b; #if NUMBOOT > 0 @@ -534,8 +549,8 @@ makebootarea(char *boot, struct disklabel *dp, int f) dp->d_secsize = DEV_BSIZE; dp->d_bbsize = BBSIZE; } - lp = (struct disklabel *) - (boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET); + lp = (struct disklabel32 *) + (boot + (LABELSECTOR32 * dp->d_secsize) + LABELOFFSET32); bzero((char *)lp, sizeof *lp); #if NUMBOOT > 0 /* @@ -656,17 +671,17 @@ makebootarea(char *boot, struct disklabel *dp, int f) * Make sure no part of the bootstrap is written in the area * reserved for the label. */ - for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) + for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel32); p++) if (*p) errx(2, "bootstrap doesn't leave room for disk label"); return (lp); } void -display(FILE *f, const struct disklabel *lp) +display(FILE *f, const struct disklabel32 *lp) { int i, j; - const struct partition *pp; + const struct partition32 *pp; fprintf(f, "# %s:\n", specname); if (lp->d_type < DKMAXTYPES) @@ -694,7 +709,7 @@ display(FILE *f, const struct disklabel *lp) fprintf(f, "track-to-track seek: %ld\t# milliseconds\n", (u_long)lp->d_trkseek); fprintf(f, "drivedata: "); - for (i = NDDATA - 1; i >= 0; i--) { + for (i = NDDATA32 - 1; i >= 0; i--) { if (lp->d_drivedata[i]) break; } @@ -726,10 +741,10 @@ display(FILE *f, const struct disklabel *lp) } int -edit(struct disklabel *lp, int f) +edit(struct disklabel32 *lp, int f) { int c, fd; - struct disklabel label; + struct disklabel32 label; FILE *fp; if ((fd = mkstemp(tmpfil)) == -1 || @@ -836,7 +851,7 @@ word(char *cp) * and fill in lp. */ int -getasciilabel(FILE *f, struct disklabel *lp) +getasciilabel(FILE *f, struct disklabel32 *lp) { char *cp; const char **cpp; @@ -907,17 +922,17 @@ getasciilabel(FILE *f, struct disklabel *lp) continue; } if (streq(cp, "drivedata")) { - for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { + for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA32;) { lp->d_drivedata[i++] = strtoul(cp, NULL, 10); tp = word(cp); } continue; } if (sscanf(cp, "%lu partitions", &v) == 1) { - if (v == 0 || v > MAXPARTITIONS) { + if (v == 0 || v > MAXPARTITIONS32) { fprintf(stderr, "line %d: bad # of partitions\n", lineno); - lp->d_npartitions = MAXPARTITIONS; + lp->d_npartitions = MAXPARTITIONS32; errors++; } else lp->d_npartitions = v; @@ -1105,9 +1120,9 @@ getasciilabel(FILE *f, struct disklabel *lp) * Return 0 on success, 1 on failure. */ int -getasciipartspec(char *tp, struct disklabel *lp, int part, int lineno) +getasciipartspec(char *tp, struct disklabel32 *lp, int part, int lineno) { - struct partition *pp; + struct partition32 *pp; char *cp; const char **cpp; u_long v; @@ -1184,16 +1199,16 @@ getasciipartspec(char *tp, struct disklabel *lp, int part, int lineno) * derived fields according to supplied values. */ int -checklabel(struct disklabel *lp) +checklabel(struct disklabel32 *lp) { - struct partition *pp; + struct partition32 *pp; int i, errors = 0; char part; u_long total_size, total_percent, current_offset; int seen_default_offset; int hog_part; int j; - struct partition *pp2; + struct partition32 *pp2; if (lp->d_secsize == 0) { fprintf(stderr, "sector size 0\n"); @@ -1227,9 +1242,9 @@ checklabel(struct disklabel *lp) errors++; } else if (lp->d_sbsize % lp->d_secsize) Warning("super block size %% sector-size != 0"); - if (lp->d_npartitions > MAXPARTITIONS) + if (lp->d_npartitions > MAXPARTITIONS32) Warning("number of partitions (%lu) > MAXPARTITIONS (%d)", - (u_long)lp->d_npartitions, MAXPARTITIONS); + (u_long)lp->d_npartitions, MAXPARTITIONS32); /* first allocate space to the partitions, then offsets */ total_size = 0; /* in sectors */ @@ -1449,12 +1464,12 @@ checklabel(struct disklabel *lp) * * The device name must be given in its "canonical" form. */ -static struct disklabel dlab; +static struct disklabel32 dlab; -struct disklabel * +struct disklabel32 * getvirginlabel(void) { - struct disklabel *dl = &dlab; + struct disklabel32 *dl = &dlab; char nambuf[BBSIZE]; int f; @@ -1472,8 +1487,8 @@ getvirginlabel(void) * Try to use the new get-virgin-label ioctl. If it fails, * fallback to the old get-disdk-info ioctl. */ - if (ioctl(f, DIOCGDVIRGIN, dl) < 0) { - if (ioctl(f, DIOCGDINFO, dl) < 0) { + if (ioctl(f, DIOCGDVIRGIN32, dl) < 0) { + if (ioctl(f, DIOCGDINFO32, dl) < 0) { warn("ioctl DIOCGDINFO"); close(f); return (NULL); @@ -1483,16 +1498,16 @@ getvirginlabel(void) return (dl); } -struct disklabel * +struct disklabel32 * getdisklabelfromdisktab(const char *name) { struct disktab *dt; - struct disklabel *dl = &dlab; + struct disklabel32 *dl = &dlab; int i; if ((dt = getdisktabbyname(name)) == NULL) return(NULL); - dl->d_magic = DISKMAGIC; + dl->d_magic = DISKMAGIC32; dl->d_type = dt->d_typeid; dl->d_subtype = 0; dl->d_secsize = dt->d_media_blksize; @@ -1507,12 +1522,12 @@ getdisklabelfromdisktab(const char *name) dl->d_cylskew = dt->d_cylskew; dl->d_headswitch = dt->d_headswitch; dl->d_trkseek = dt->d_trkseek; - dl->d_magic2 = DISKMAGIC; + dl->d_magic2 = DISKMAGIC32; dl->d_npartitions = dt->d_npartitions; dl->d_bbsize = dt->d_bbsize; dl->d_sbsize = dt->d_sbsize; for (i = 0; i < dt->d_npartitions; ++i) { - struct partition *dlp = &dl->d_partitions[i]; + struct partition32 *dlp = &dl->d_partitions[i]; struct dt_partition *dtp = &dt->d_partitions[i]; dlp->p_size = dtp->p_size; @@ -1531,9 +1546,9 @@ getdisklabelfromdisktab(const char *name) * clobber bootstrap code. */ void -setbootflag(struct disklabel *lp) +setbootflag(struct disklabel32 *lp) { - struct partition *pp; + struct partition32 *pp; int i, errors = 0; char part; u_long boffset; @@ -1603,6 +1618,104 @@ checkoldboot(int f, const char *bootbuffer) return(0); } +/* + * Traditional 32 bit disklabels actually use absolute sector numbers on + * disk, NOT slice relative sector numbres. The OS hides this from us + * when we use DIOC ioctls to access the label, but newer versions of + * Dragonfly no longer adjusts the disklabel when snooping reads or writes + * so we have to figure it out ourselves. + */ +const char * +fixlabel(int f, struct disklabel32 *lp, int writeadj) +{ + const char *msg = NULL; + struct partinfo info; + struct partition32 *pp; + u_int64_t start; + u_int64_t end; + u_int64_t offset; + int part; + int rev; + int rev_len = sizeof(rev); + + if (sysctlbyname("kern.osrevision", &rev, &rev_len, NULL, 0) < 0) { + errx(1, "Cannot use raw mode on non-DragonFly systems\n"); + } + if (rev < 200701) { + warnx("Warning running new disklabel on old DragonFly systems,\n" + "assuming the disk layer will fixup the label.\n"); + sleep(3); + return(NULL); + } + + pp = &lp->d_partitions[RAW_PART]; + + if (forceflag) { + info.media_offset = slice_start_lba * lp->d_secsize; + info.media_blocks = pp->p_size; + info.media_blksize = lp->d_secsize; + } else if (ioctl(f, DIOCGPART, &info) < 0) { + msg = "Unable to extract the slice starting LBA, " + "you must use the -f option\n" + "to specify it manually, or perhaps try without " + "using -r and let the kernel deal with it\n"; + return(msg); + } + + if (lp->d_magic != DISKMAGIC32 || lp->d_magic2 != DISKMAGIC32) + return ("fixlabel: invalid magic"); + if (dkcksum32(lp) != 0) + return ("fixlabel: invalid checksum"); + + /* + * What a mess. For ages old backwards compatibility the disklabel + * on-disk stores absolute offsets instead of slice-relative offsets. + * So fix it up when reading, writing, or snooping. + * + * The in-core label is always slice-relative. + */ + if (writeadj) { + /* + * incore -> disk + */ + start = 0; + offset = info.media_offset / info.media_blksize; + } else { + /* + * disk -> incore + */ + start = info.media_offset / info.media_blksize; + offset = -info.media_offset / info.media_blksize; + } + if (pp->p_offset != start) + return ("fixlabel: raw partition offset != slice offset"); + if (pp->p_size != info.media_blocks) { + if (pp->p_size > info.media_blocks) + return ("fixlabel: raw partition size > slice size"); + } + end = start + info.media_blocks; + if (start > end) + return ("fixlabel: slice wraps"); + if (lp->d_secpercyl <= 0) + return ("fixlabel: d_secpercyl <= 0"); + pp -= RAW_PART; + for (part = 0; part < lp->d_npartitions; part++, pp++) { + if (pp->p_offset != 0 || pp->p_size != 0) { + if (pp->p_offset < start + || pp->p_offset + pp->p_size > end + || pp->p_offset + pp->p_size < pp->p_offset) { + /* XXX else silently discard junk. */ + bzero(pp, sizeof *pp); + } else { + pp->p_offset += offset; + } + } + } + lp->d_checksum = 0; + lp->d_checksum = dkcksum32(lp); + return (NULL); +} + void usage(void) { diff --git a/sbin/gpt/migrate.c b/sbin/gpt/migrate.c index 772ba7162c..93ea6ac278 100644 --- a/sbin/gpt/migrate.c +++ b/sbin/gpt/migrate.c @@ -24,11 +24,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $ - * $DragonFly: src/sbin/gpt/migrate.c,v 1.2 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sbin/gpt/migrate.c,v 1.3 2007/06/18 05:13:39 dillon Exp $ */ #include -#include +#include #include #include @@ -68,15 +68,15 @@ static struct gpt_ent* migrate_disklabel(int fd, off_t start, struct gpt_ent *ent) { char *buf; - struct disklabel *dl; + struct disklabel32 *dl; off_t ofs, rawofs; int i; - buf = gpt_read(fd, start + LABELSECTOR, 1); - dl = (void*)(buf + LABELOFFSET); + buf = gpt_read(fd, start + LABELSECTOR32, 1); + dl = (void*)(buf + LABELOFFSET32); - if (le32toh(dl->d_magic) != DISKMAGIC || - le32toh(dl->d_magic2) != DISKMAGIC) { + if (le32toh(dl->d_magic) != DISKMAGIC32 || + le32toh(dl->d_magic2) != DISKMAGIC32) { warnx("%s: warning: FreeBSD slice without disklabel", device_name); return (ent); diff --git a/sbin/vinum/list.c b/sbin/vinum/list.c index 1a12e0785a..10ee31ca44 100644 --- a/sbin/vinum/list.c +++ b/sbin/vinum/list.c @@ -37,7 +37,7 @@ * * $Id: list.c,v 1.25 2000/12/20 03:38:43 grog Exp grog $ * $FreeBSD: src/sbin/vinum/list.c,v 1.25.2.4 2001/05/28 05:58:04 grog Exp $ - * $DragonFly: src/sbin/vinum/list.c,v 1.9 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sbin/vinum/list.c,v 1.10 2007/06/18 05:13:41 dillon Exp $ */ #define _KERNEL_STRUCTURES @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include "vext.h" #include @@ -1279,7 +1279,7 @@ dumpconfig(char *part) int partition; /* UNIX partition */ int slice; int founddrive; /* flag when we find a vinum drive */ - struct disklabel label; /* label of this drive */ + struct disklabel32 label; /* label of this drive */ int driveno; /* fd of drive */ int found; u_int64_t drivelength; @@ -1301,7 +1301,7 @@ dumpconfig(char *part) fprintf(stderr, "Can't open %s: %s (%d)\n", partname, strerror(errno), errno); continue; } - if (ioctl(driveno, DIOCGDINFO, &label) < 0) { + if (ioctl(driveno, DIOCGDINFO32, &label) < 0) { fprintf(stderr, "Can't get label from %s: %s (%d)\n", partname, strerror(errno), errno); continue; } @@ -1332,7 +1332,7 @@ dumpconfig(char *part) fprintf(stderr, "Can't open %s: %s (%d)\n", partname, strerror(errno), errno); return; } - if (ioctl(driveno, DIOCGDINFO, &label) < 0) { + if (ioctl(driveno, DIOCGDINFO32, &label) < 0) { fprintf(stderr, "Can't get label from %s: %s (%d)\n", partname, strerror(errno), errno); return; } diff --git a/sys/boot/efi/libefi/devicename.c b/sys/boot/efi/libefi/devicename.c index 504d41d1e5..8ecc8ebee0 100644 --- a/sys/boot/efi/libefi/devicename.c +++ b/sys/boot/efi/libefi/devicename.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/efi/libefi/devicename.c,v 1.2 2001/09/07 08:49:47 dfr Exp $ - * $DragonFly: src/sys/boot/efi/libefi/devicename.c,v 1.2 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sys/boot/efi/libefi/devicename.c,v 1.3 2007/06/18 05:13:41 dillon Exp $ */ #include @@ -133,7 +133,7 @@ efi_parsedev(struct efi_devdesc **dev, const char *devspec, const char **path) } if (*cp && (*cp != ':')) { partition = *cp - 'a'; /* get a partition number */ - if ((partition < 0) || (partition >= MAXPARTITIONS)) { + if ((partition < 0) || (partition >= MAXPARTITIONS32)) { err = EPART; goto fail; } diff --git a/sys/boot/ia64/libski/devicename.c b/sys/boot/ia64/libski/devicename.c index 9e8df7bde6..11aa5cc234 100644 --- a/sys/boot/ia64/libski/devicename.c +++ b/sys/boot/ia64/libski/devicename.c @@ -24,12 +24,12 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/ia64/libski/devicename.c,v 1.2 2003/09/08 09:11:32 obrien Exp $ - * $DragonFly: src/sys/boot/ia64/libski/devicename.c,v 1.1 2003/11/10 06:08:37 dillon Exp $ + * $DragonFly: src/sys/boot/ia64/libski/devicename.c,v 1.2 2007/06/18 05:13:41 dillon Exp $ */ #include #include -#include +#include #include "bootstrap.h" #include "libski.h" @@ -131,7 +131,7 @@ ski_parsedev(struct ski_devdesc **dev, const char *devspec, const char **path) } if (*cp && (*cp != ':')) { partition = *cp - 'a'; /* get a partition number */ - if ((partition < 0) || (partition >= MAXPARTITIONS)) { + if ((partition < 0) || (partition >= MAXPARTITIONS32)) { err = EPART; goto fail; } diff --git a/sys/boot/pc32/boot2/boot2.c b/sys/boot/pc32/boot2/boot2.c index d727c171d1..e283e7fb97 100644 --- a/sys/boot/pc32/boot2/boot2.c +++ b/sys/boot/pc32/boot2/boot2.c @@ -45,10 +45,10 @@ * purpose. * * $FreeBSD: src/sys/boot/i386/boot2/boot2.c,v 1.64 2003/08/25 23:28:31 obrien Exp $ - * $DragonFly: src/sys/boot/pc32/boot2/boot2.c,v 1.15 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sys/boot/pc32/boot2/boot2.c,v 1.16 2007/06/18 05:13:42 dillon Exp $ */ #include -#include +#include #include #include #include @@ -517,7 +517,7 @@ static int dskread(void *buf, unsigned lba, unsigned nblk) { struct dos_partition *dp; - struct disklabel *d; + struct disklabel32 *d; char *sec; unsigned sl, i; @@ -549,10 +549,10 @@ dskread(void *buf, unsigned lba, unsigned nblk) } dsk.start = dp->dp_start; } - if (drvread(sec, dsk.start + LABELSECTOR, 1)) + if (drvread(sec, dsk.start + LABELSECTOR32, 1)) return -1; - d = (void *)(sec + LABELOFFSET); - if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) { + d = (void *)(sec + LABELOFFSET32); + if (d->d_magic != DISKMAGIC32 || d->d_magic2 != DISKMAGIC32) { if (dsk.part != RAW_PART) { printf(INVALID_S, "label"); return -1; diff --git a/sys/boot/pc32/libi386/biosdisk.c b/sys/boot/pc32/libi386/biosdisk.c index ff114fb2d9..6346366df6 100644 --- a/sys/boot/pc32/libi386/biosdisk.c +++ b/sys/boot/pc32/libi386/biosdisk.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/i386/libi386/biosdisk.c,v 1.45 2004/09/21 06:46:44 wes Exp $ - * $DragonFly: src/sys/boot/pc32/libi386/biosdisk.c,v 1.11 2007/06/17 23:50:15 dillon Exp $ + * $DragonFly: src/sys/boot/pc32/libi386/biosdisk.c,v 1.12 2007/06/18 05:13:42 dillon Exp $ */ /* @@ -39,7 +39,7 @@ #include -#include +#include #include #include #include @@ -82,7 +82,7 @@ struct open_disk { #define BD_FLOPPY 0x0004 #define BD_LABELOK 0x0008 #define BD_PARTTABOK 0x0010 - struct disklabel od_disklabel; + struct disklabel32 od_disklabel; int od_nslices; /* slice count */ struct dos_partition od_slicetab[NEXTDOSPART]; }; @@ -370,14 +370,14 @@ bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix, { char line[80]; char buf[BIOSDISK_SECSIZE]; - struct disklabel *lp; + struct disklabel32 *lp; int i; /* read disklabel */ - if (bd_read(od, offset + LABELSECTOR, 1, buf)) + if (bd_read(od, offset + LABELSECTOR32, 1, buf)) return; - lp =(struct disklabel *)(&buf[0]); - if (lp->d_magic != DISKMAGIC) { + lp =(struct disklabel32 *)(&buf[0]); + if (lp->d_magic != DISKMAGIC32) { sprintf(line, "%s: FFS bad disklabel\n", prefix); pager_output(line); return; @@ -453,7 +453,7 @@ static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) { struct dos_partition *dptr; - struct disklabel *lp; + struct disklabel32 *lp; struct open_disk *od; int sector, slice, i; int error; @@ -610,17 +610,17 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) DEBUG("opening raw slice"); } else { - if (bd_read(od, sector + LABELSECTOR, 1, buf)) { + if (bd_read(od, sector + LABELSECTOR32, 1, buf)) { DEBUG("error reading disklabel"); error = EIO; goto out; } - DEBUG("copy %d bytes of label from %p to %p", sizeof(struct disklabel), buf + LABELOFFSET, &od->od_disklabel); - bcopy(buf + LABELOFFSET, &od->od_disklabel, sizeof(struct disklabel)); + DEBUG("copy %d bytes of label from %p to %p", sizeof(struct disklabel32), buf + LABELOFFSET32, &od->od_disklabel); + bcopy(buf + LABELOFFSET32, &od->od_disklabel, sizeof(struct disklabel32)); lp = &od->od_disklabel; od->od_flags |= BD_LABELOK; - if (lp->d_magic != DISKMAGIC) { + if (lp->d_magic != DISKMAGIC32) { DEBUG("no disklabel"); error = ENOENT; goto out; diff --git a/sys/boot/pc32/libi386/devicename.c b/sys/boot/pc32/libi386/devicename.c index c921b05599..7160b1438c 100644 --- a/sys/boot/pc32/libi386/devicename.c +++ b/sys/boot/pc32/libi386/devicename.c @@ -24,12 +24,12 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/boot/i386/libi386/devicename.c,v 1.6 2003/08/25 23:28:31 obrien Exp $ - * $DragonFly: src/sys/boot/pc32/libi386/devicename.c,v 1.3 2003/11/10 06:08:36 dillon Exp $ + * $DragonFly: src/sys/boot/pc32/libi386/devicename.c,v 1.4 2007/06/18 05:13:42 dillon Exp $ */ #include #include -#include +#include #include "bootstrap.h" #include "libi386.h" @@ -130,7 +130,7 @@ i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path) } if (*cp && (*cp != ':')) { partition = *cp - 'a'; /* get a partition number */ - if ((partition < 0) || (partition >= MAXPARTITIONS)) { + if ((partition < 0) || (partition >= MAXPARTITIONS32)) { err = EPART; goto fail; } diff --git a/sys/conf/files b/sys/conf/files index 903fb18b23..06f0ef06e1 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $ -# $DragonFly: src/sys/conf/files,v 1.163 2007/06/17 20:33:14 swildner Exp $ +# $DragonFly: src/sys/conf/files,v 1.164 2007/06/18 05:13:32 dillon Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -579,6 +579,8 @@ kern/subr_autoconf.c standard kern/subr_bus.c standard kern/subr_devstat.c standard kern/subr_disk.c standard +kern/subr_disklabel32.c standard +kern/subr_disklabel64.c standard kern/subr_diskslice.c standard kern/subr_eventhandler.c standard kern/subr_kcore.c standard diff --git a/sys/kern/subr_disklabel32.c b/sys/kern/subr_disklabel32.c index 6ece8d9911..3b3f49e404 100644 --- a/sys/kern/subr_disklabel32.c +++ b/sys/kern/subr_disklabel32.c @@ -89,7 +89,7 @@ * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/subr_disk.c,v 1.20.2.6 2001/10/05 07:14:57 peter Exp $ * $FreeBSD: src/sys/ufs/ufs/ufs_disksubr.c,v 1.44.2.3 2001/03/05 05:42:19 obrien Exp $ - * $DragonFly: src/sys/kern/subr_disklabel32.c,v 1.1 2007/06/17 23:50:16 dillon Exp $ + * $DragonFly: src/sys/kern/subr_disklabel32.c,v 1.2 2007/06/18 05:13:42 dillon Exp $ */ #include @@ -100,6 +100,7 @@ #include #include #include +#include #include #include #include /* DTYPE_* constants */ @@ -115,42 +116,44 @@ #include /* XXX used only for fs.h */ #include /* XXX used only to get BBSIZE/SBSIZE */ -static void partition_info(const char *sname, int part, struct partition *pp); +static void partition_info(const char *sname, int part, struct partition32 *pp); static void slice_info(const char *sname, struct diskslice *sp); +static const char *l32_fixlabel(const char *sname, struct diskslice *sp, + disklabel_t lpx, int writeflag); /* * Retrieve the partition start and extent, in blocks. Return 0 on success, * EINVAL on error. */ -int -getpartbounds(struct disklabel *lp, u_int32_t part, - u_int64_t *start, u_int64_t *blocks) +static int +l32_getpartbounds(disklabel_t lp, u_int32_t part, + u_int64_t *start, u_int64_t *blocks) { - struct partition *pp; + struct partition32 *pp; - if (part >= lp->d_npartitions) + if (part >= lp.lab32->d_npartitions) return (EINVAL); - pp = &lp->d_partitions[part]; + pp = &lp.lab32->d_partitions[part]; *blocks = pp->p_size; *start = pp->p_offset; return(0); } -int -getpartfstype(struct disklabel *lp, u_int32_t part) +static int +l32_getpartfstype(disklabel_t lp, u_int32_t part) { - struct partition *pp; + struct partition32 *pp; - if (part >= lp->d_npartitions) + if (part >= lp.lab32->d_npartitions) return (0); - pp = &lp->d_partitions[part]; + pp = &lp.lab32->d_partitions[part]; return(pp->p_fstype); } -u_int32_t -getnumparts(struct disklabel *lp) +static u_int32_t +l32_getnumparts(disklabel_t lp) { - return(lp->d_npartitions); + return(lp.lab32->d_npartitions); } /* @@ -160,34 +163,43 @@ getnumparts(struct disklabel *lp) * partition containing the label) must be filled in before calling us. * Returns NULL on success and an error string on failure. */ -char * -readdisklabel(cdev_t dev, struct disklabel *lp) +static const char * +l32_readdisklabel(cdev_t dev, struct diskslice *sp, disklabel_t *lpp, + struct disk_info *info) { + disklabel_t lpx; struct buf *bp; - struct disklabel *dlp; - char *msg = NULL; + struct disklabel32 *dlp; + const char *msg = NULL; + int secsize = info->d_media_blksize; - bp = geteblk((int)lp->d_secsize); - bp->b_bio1.bio_offset = (off_t)LABELSECTOR * lp->d_secsize; - bp->b_bcount = lp->d_secsize; + bp = geteblk(secsize); + bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * secsize; + bp->b_bcount = secsize; bp->b_flags &= ~B_INVAL; bp->b_cmd = BUF_CMD_READ; dev_dstrategy(dev, &bp->b_bio1); if (biowait(bp)) msg = "I/O error"; - else for (dlp = (struct disklabel *)bp->b_data; - dlp <= (struct disklabel *)((char *)bp->b_data + - lp->d_secsize - sizeof(*dlp)); - dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { - if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { + else for (dlp = (struct disklabel32 *)bp->b_data; + dlp <= (struct disklabel32 *)((char *)bp->b_data + + secsize - sizeof(*dlp)); + dlp = (struct disklabel32 *)((char *)dlp + sizeof(long))) { + if (dlp->d_magic != DISKMAGIC32 || + dlp->d_magic2 != DISKMAGIC32) { if (msg == NULL) msg = "no disk label"; } else if (dlp->d_npartitions > MAXPARTITIONS || - dkcksum(dlp) != 0) + dkcksum32(dlp) != 0) { msg = "disk label corrupted"; - else { - *lp = *dlp; - msg = NULL; + } else { + lpx.lab32 = dlp; + msg = l32_fixlabel(NULL, sp, lpx, FALSE); + if (msg == NULL) { + (*lpp).lab32 = kmalloc(sizeof(*dlp), + M_DEVBUF, M_WAITOK|M_ZERO); + *(*lpp).lab32 = *dlp; + } break; } } @@ -199,19 +211,23 @@ readdisklabel(cdev_t dev, struct disklabel *lp) /* * Check new disk label for sensibility before setting it. */ -int -setdisklabel(struct disklabel *olp, struct disklabel *nlp, - struct diskslice *sp, u_int32_t *openmask) +static int +l32_setdisklabel(disklabel_t olpx, disklabel_t nlpx, + struct diskslice *sp, u_int32_t *openmask) { - struct partition *opp, *npp; + struct disklabel32 *olp, *nlp; + struct partition32 *opp, *npp; int part; int i; + olp = olpx.lab32; + nlp = nlpx.lab32; + /* * Check it is actually a disklabel we are looking at. */ - if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC || - dkcksum(nlp) != 0) + if (nlp->d_magic != DISKMAGIC32 || nlp->d_magic2 != DISKMAGIC32 || + dkcksum32(nlp) != 0) return (EINVAL); /* @@ -249,7 +265,7 @@ setdisklabel(struct disklabel *olp, struct disklabel *nlp, ++i; } nlp->d_checksum = 0; - nlp->d_checksum = dkcksum(nlp); + nlp->d_checksum = dkcksum32(nlp); *olp = *nlp; if (olp->d_partitions[RAW_PART].p_offset) @@ -266,17 +282,21 @@ setdisklabel(struct disklabel *olp, struct disklabel *nlp, /* * Write disk label back to device after modification. */ -int -writedisklabel(cdev_t dev, struct disklabel *lp) +static int +l32_writedisklabel(cdev_t dev, struct diskslice *sp, disklabel_t lpx) { + struct disklabel32 *lp; + struct disklabel32 *dlp; struct buf *bp; - struct disklabel *dlp; + const char *msg; int error = 0; + lp = lpx.lab32; + if (lp->d_partitions[RAW_PART].p_offset != 0) return (EXDEV); /* not quite right */ bp = geteblk((int)lp->d_secsize); - bp->b_bio1.bio_offset = (off_t)LABELSECTOR * lp->d_secsize; + bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * lp->d_secsize; bp->b_bcount = lp->d_secsize; #if 1 /* @@ -292,16 +312,23 @@ writedisklabel(cdev_t dev, struct disklabel *lp) error = biowait(bp); if (error) goto done; - for (dlp = (struct disklabel *)bp->b_data; - dlp <= (struct disklabel *) + for (dlp = (struct disklabel32 *)bp->b_data; + dlp <= (struct disklabel32 *) ((char *)bp->b_data + lp->d_secsize - sizeof(*dlp)); - dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { - if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && - dkcksum(dlp) == 0) { + dlp = (struct disklabel32 *)((char *)dlp + sizeof(long))) { + if (dlp->d_magic == DISKMAGIC32 && + dlp->d_magic2 == DISKMAGIC32 && dkcksum32(dlp) == 0) { *dlp = *lp; - bp->b_cmd = BUF_CMD_WRITE; - dev_dstrategy(dkmodpart(dev, WHOLE_SLICE_PART), &bp->b_bio1); - error = biowait(bp); + lpx.lab32 = dlp; + msg = l32_fixlabel(NULL, sp, lpx, TRUE); + if (msg) { + error = EINVAL; + } else { + bp->b_cmd = BUF_CMD_WRITE; + dev_dstrategy(dkmodpart(dev, WHOLE_SLICE_PART), + &bp->b_bio1); + error = biowait(bp); + } goto done; } } @@ -309,7 +336,7 @@ writedisklabel(cdev_t dev, struct disklabel *lp) done: #else bzero(bp->b_data, lp->d_secsize); - dlp = (struct disklabel *)bp->b_data; + dlp = (struct disklabel32 *)bp->b_data; *dlp = *lp; bp->b_flags &= ~B_INVAL; bp->b_cmd = BUF_CMD_WRITE; @@ -328,73 +355,76 @@ done: * * If a diskslice is passed, the label is truncated to the slice */ -struct disklabel * -clone_label(struct disk_info *info, struct diskslice *sp) +static disklabel_t +l32_clone_label(struct disk_info *info, struct diskslice *sp) { - struct disklabel *lp1; + struct disklabel32 *lp; + disklabel_t res; - lp1 = kmalloc(sizeof *lp1, M_DEVBUF, M_WAITOK | M_ZERO); - lp1->d_nsectors = info->d_secpertrack; - lp1->d_ntracks = info->d_nheads; - lp1->d_secpercyl = info->d_secpercyl; - lp1->d_secsize = info->d_media_blksize; + lp = kmalloc(sizeof *lp, M_DEVBUF, M_WAITOK | M_ZERO); + lp->d_nsectors = info->d_secpertrack; + lp->d_ntracks = info->d_nheads; + lp->d_secpercyl = info->d_secpercyl; + lp->d_secsize = info->d_media_blksize; if (sp) - lp1->d_secperunit = (u_int)sp->ds_size; + lp->d_secperunit = (u_int)sp->ds_size; else - lp1->d_secperunit = (u_int)info->d_media_blocks; - - if (lp1->d_typename[0] == '\0') - strncpy(lp1->d_typename, "amnesiac", sizeof(lp1->d_typename)); - if (lp1->d_packname[0] == '\0') - strncpy(lp1->d_packname, "fictitious", sizeof(lp1->d_packname)); - if (lp1->d_nsectors == 0) - lp1->d_nsectors = 32; - if (lp1->d_ntracks == 0) - lp1->d_ntracks = 64; - lp1->d_secpercyl = lp1->d_nsectors * lp1->d_ntracks; - lp1->d_ncylinders = lp1->d_secperunit / lp1->d_secpercyl; - if (lp1->d_rpm == 0) - lp1->d_rpm = 3600; - if (lp1->d_interleave == 0) - lp1->d_interleave = 1; - if (lp1->d_npartitions < RAW_PART + 1) - lp1->d_npartitions = MAXPARTITIONS; - if (lp1->d_bbsize == 0) - lp1->d_bbsize = BBSIZE; - if (lp1->d_sbsize == 0) - lp1->d_sbsize = SBSIZE; + lp->d_secperunit = (u_int)info->d_media_blocks; + + if (lp->d_typename[0] == '\0') + strncpy(lp->d_typename, "amnesiac", sizeof(lp->d_typename)); + if (lp->d_packname[0] == '\0') + strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname)); + if (lp->d_nsectors == 0) + lp->d_nsectors = 32; + if (lp->d_ntracks == 0) + lp->d_ntracks = 64; + lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; + lp->d_ncylinders = lp->d_secperunit / lp->d_secpercyl; + if (lp->d_rpm == 0) + lp->d_rpm = 3600; + if (lp->d_interleave == 0) + lp->d_interleave = 1; + if (lp->d_npartitions < RAW_PART + 1) + lp->d_npartitions = MAXPARTITIONS; + if (lp->d_bbsize == 0) + lp->d_bbsize = BBSIZE; + if (lp->d_sbsize == 0) + lp->d_sbsize = SBSIZE; /* * Used by various devices to create a compatibility slice which * allows us to mount root from devices which do not have a * disklabel. Particularly: CDs. */ - lp1->d_partitions[RAW_PART].p_size = lp1->d_secperunit; + lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; if (info->d_dsflags & DSO_COMPATPARTA) { - lp1->d_partitions[0].p_size = lp1->d_secperunit; - lp1->d_partitions[0].p_fstype = FS_OTHER; + lp->d_partitions[0].p_size = lp->d_secperunit; + lp->d_partitions[0].p_fstype = FS_OTHER; } - lp1->d_magic = DISKMAGIC; - lp1->d_magic2 = DISKMAGIC; - lp1->d_checksum = dkcksum(lp1); - return (lp1); + lp->d_magic = DISKMAGIC32; + lp->d_magic2 = DISKMAGIC32; + lp->d_checksum = dkcksum32(lp); + res.lab32 = lp; + return (res); } -void -makevirginlabel(struct disklabel *lp, struct diskslices *ssp, - struct diskslice *sp, struct disk_info *info) +static void +l32_makevirginlabel(disklabel_t lpx, struct diskslices *ssp, + struct diskslice *sp, struct disk_info *info) { - struct partition *pp; + struct disklabel32 *lp = lpx.lab32; + struct partition32 *pp; - if (ssp->dss_slices[WHOLE_DISK_SLICE].ds_label) { - bcopy(ssp->dss_slices[WHOLE_DISK_SLICE].ds_label, lp, - sizeof(*lp)); + if (ssp->dss_slices[WHOLE_DISK_SLICE].ds_label.opaque) { + bcopy(ssp->dss_slices[WHOLE_DISK_SLICE].ds_label.opaque, lp, + sizeof(struct disklabel32)); } else { bzero(lp, sizeof(*lp)); } - lp->d_magic = DISKMAGIC; - lp->d_magic2 = DISKMAGIC; + lp->d_magic = DISKMAGIC32; + lp->d_magic2 = DISKMAGIC32; lp->d_npartitions = MAXPARTITIONS; if (lp->d_interleave == 0) @@ -441,23 +471,27 @@ makevirginlabel(struct disklabel *lp, struct diskslices *ssp, pp->p_fstype = FS_OTHER; } lp->d_checksum = 0; - lp->d_checksum = dkcksum(lp); + lp->d_checksum = dkcksum32(lp); } -char * -fixlabel(const char *sname, struct diskslice *sp, struct disklabel *lp, int writeflag) +static const char * +l32_fixlabel(const char *sname, struct diskslice *sp, + disklabel_t lpx, int writeflag) { + struct disklabel32 *lp; + struct partition32 *pp; u_int64_t start; u_int64_t end; u_int64_t offset; int part; - struct partition *pp; int warned; + lp = lpx.lab32; + /* These errors "can't happen" so don't bother reporting details. */ - if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) + if (lp->d_magic != DISKMAGIC32 || lp->d_magic2 != DISKMAGIC32) return ("fixlabel: invalid magic"); - if (dkcksum(lp) != 0) + if (dkcksum32(lp) != 0) return ("fixlabel: invalid checksum"); pp = &lp->d_partitions[RAW_PART]; @@ -531,14 +565,15 @@ fixlabel(const char *sname, struct diskslice *sp, struct disklabel *lp, int writ lp->d_ncylinders = sp->ds_size / lp->d_secpercyl; lp->d_secperunit = sp->ds_size; lp->d_checksum = 0; - lp->d_checksum = dkcksum(lp); + lp->d_checksum = dkcksum32(lp); return (NULL); } -void -adjust_label_reserved(struct diskslices *ssp, int slice, struct diskslice *sp) +static void +l32_adjust_label_reserved(struct diskslices *ssp, int slice, + struct diskslice *sp) { - struct disklabel *lp = sp->ds_label; + struct disklabel32 *lp = sp->ds_label.lab32; /* * If the slice is not the whole-disk slice, setup the reserved @@ -573,7 +608,7 @@ adjust_label_reserved(struct diskslices *ssp, int slice, struct diskslice *sp) } static void -partition_info(const char *sname, int part, struct partition *pp) +partition_info(const char *sname, int part, struct partition32 *pp) { kprintf("%s%c: start %lu, end %lu, size %lu\n", sname, 'a' + part, (u_long)pp->p_offset, (u_long)(pp->p_offset + pp->p_size - 1), @@ -587,3 +622,17 @@ slice_info(const char *sname, struct diskslice *sp) sp->ds_offset, sp->ds_offset + sp->ds_size - 1, sp->ds_size); } +struct disklabel_ops disklabel32_ops = { + .labelsect = LABELSECTOR32, + .labelsize = sizeof(struct disklabel32), + .op_readdisklabel = l32_readdisklabel, + .op_setdisklabel = l32_setdisklabel, + .op_writedisklabel = l32_writedisklabel, + .op_clone_label = l32_clone_label, + .op_adjust_label_reserved = l32_adjust_label_reserved, + .op_getpartbounds = l32_getpartbounds, + .op_getpartfstype = l32_getpartfstype, + .op_getnumparts = l32_getnumparts, + .op_makevirginlabel = l32_makevirginlabel +}; + diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c index 42c61d91a7..c2fd6a18a3 100644 --- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -44,7 +44,7 @@ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ * $FreeBSD: src/sys/kern/subr_diskslice.c,v 1.82.2.6 2001/07/24 09:49:41 dd Exp $ - * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.45 2007/06/17 23:50:16 dillon Exp $ + * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.46 2007/06/18 05:13:42 dillon Exp $ */ #include @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -67,15 +68,15 @@ #include /* XXX used only for fs.h */ #include /* XXX used only to get BBSIZE/SBSIZE */ -static void dsiodone (struct bio *bio); static int dsreadandsetlabel(cdev_t dev, u_int flags, struct diskslices *ssp, struct diskslice *sp, struct disk_info *info); static void free_ds_label (struct diskslices *ssp, int slice); -static void set_ds_label (struct diskslices *ssp, int slice, - struct disklabel *lp); +static void set_ds_label (struct diskslices *ssp, int slice, disklabel_t lp); static void set_ds_wlabel (struct diskslices *ssp, int slice, int wlabel); +#define ops (&disklabel32_ops) + /* * Determine the size of the transfer, and make sure it is * within the boundaries of the partition. Adjust transfer @@ -96,8 +97,7 @@ dscheck(cdev_t dev, struct bio *bio, struct diskslices *ssp) { struct buf *bp = bio->bio_buf; struct bio *nbio; - struct disklabel *lp; - char *msg; + disklabel_t lp; long nsec; u_int64_t secno; u_int64_t endsecno; @@ -107,7 +107,6 @@ dscheck(cdev_t dev, struct bio *bio, struct diskslices *ssp) u_int32_t slice; int shift; int mask; - int snoop; slice = dkslice(dev); part = dkpart(dev); @@ -156,9 +155,7 @@ doshift: if (slice == WHOLE_DISK_SLICE) { /* * Labels have not been allowed on whole-disks for a while. - * This really puts the nail in the coffin... no disk - * snooping will occur even if you tried to write a label - * without a slice structure. + * This really puts the nail in the coffin. * * Accesses to the WHOLE_DISK_SLICE do not use a disklabel * and partition numbers are special-cased. Currently numbers @@ -170,7 +167,7 @@ doshift: * sector size for the special raw access may not be the * same as the nominal sector size for the device. */ - lp = NULL; + lp.opaque = NULL; if (part < 128) { kprintf("dscheck(%s): illegal partition number (%d) " "for WHOLE_DISK_SLICE access\n", @@ -189,35 +186,26 @@ doshift: */ endsecno = sp->ds_size; slicerel_secno = secno; - snoop = 0; } else if (part == WHOLE_SLICE_PART) { /* - * We are accessing a slice. Enable snooping of the bsd - * label. Note that snooping only occurs if ds_reserved - * is also non-zero. ds_reserved will be non-zero if - * an in-core label is present or snooping has been - * explicitly requested via an ioctl(). - * * NOTE! opens on a whole-slice partition will not attempt * to read a disklabel in, so there may not be an in-core * disklabel even if there is one on the disk. */ endsecno = sp->ds_size; slicerel_secno = secno; - snoop = 1; - } else if ((lp = sp->ds_label) != NULL) { + } else if ((lp = sp->ds_label).opaque != NULL) { /* * A label is present, extract the partition. Snooping of * the disklabel is not supported even if accessible. Of * course, the reserved area is still write protected. */ - if (getpartbounds(lp, part, &slicerel_secno, &endsecno)) { + if (ops->op_getpartbounds(lp, part, &slicerel_secno, &endsecno)) { kprintf("dscheck(%s): partition %d out of bounds\n", devtoname(dev), part); goto bad; } slicerel_secno += secno; - snoop = 0; } else { /* * Attempt to access partition when no disklabel present @@ -281,42 +269,6 @@ doshift: nbio = push_bio(bio); nbio->bio_offset = (off_t)(sp->ds_offset + slicerel_secno) * ssp->dss_secsize; - - /* - * Snoop reads and writes to the label area - only done if - * snoop is non-zero, ds_reserved is non-zero, and the - * read covers the label sector. - */ - if (snoop && slicerel_secno < sp->ds_reserved && - slicerel_secno <= LABELSECTOR && - nsec && slicerel_secno + nsec > LABELSECTOR) { - /* - * Set up our own callback on I/O completion to handle - * undoing the fixup we did for the write as well as - * doing the fixup for a read. - * - * Set info2.offset to the offset within the buffer containing - * the start of the label. - */ - nbio->bio_done = dsiodone; - nbio->bio_caller_info1.ptr = sp; - nbio->bio_caller_info2.offset = - (LABELSECTOR - slicerel_secno) * ssp->dss_secsize; - if (bp->b_cmd != BUF_CMD_READ) { - msg = fixlabel( - NULL, sp, - (struct disklabel *) - (bp->b_data + (int)nbio->bio_caller_info2.offset), - TRUE); - if (msg != NULL) { - kprintf("dscheck(%s): %s\n", - devtoname(dev), msg); - bp->b_error = EROFS; - pop_bio(nbio); - goto error; - } - } - } return (nbio); bad_bcount: @@ -386,10 +338,10 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, struct diskslices **sspp, struct disk_info *info) { int error; - struct disklabel *lp; + disklabel_t lp; + disklabel_t lptmp; int old_wlabel; u_int32_t openmask[DKMAXPARTITIONS/(sizeof(u_int32_t)*8)]; - u_int64_t old_reserved; int part; int slice; struct diskslice *sp; @@ -404,7 +356,7 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, lp = sp->ds_label; switch (cmd) { - case DIOCGDVIRGIN: + case DIOCGDVIRGIN32: /* * You can only retrieve a virgin disklabel on the whole * disk slice or whole-slice partition. @@ -414,11 +366,11 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, return(EINVAL); } - lp = (struct disklabel *)data; - makevirginlabel(lp, ssp, sp, info); + lp.opaque = data; + ops->op_makevirginlabel(lp, ssp, sp, info); return (0); - case DIOCGDINFO: + case DIOCGDINFO32: /* * You can only retrieve a disklabel on the whole * slice partition. @@ -436,12 +388,12 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, (info->d_dsflags & DSO_COMPATLABEL) == 0) { return (ENODEV); } - if (sp->ds_label == NULL) { + if (sp->ds_label.opaque == NULL) { error = dsreadandsetlabel(dev, info->d_dsflags, ssp, sp, info); } if (error == 0) - *(struct disklabel *)data = *sp->ds_label; + bcopy(sp->ds_label.opaque, data, ops->labelsize); return (error); case DIOCGPART: @@ -456,7 +408,8 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, * * We ignore any error. */ - if (sp->ds_label == NULL && part == WHOLE_SLICE_PART && + if (sp->ds_label.opaque == NULL && + part == WHOLE_SLICE_PART && slice != WHOLE_DISK_SLICE) { dsreadandsetlabel(dev, info->d_dsflags, ssp, sp, info); @@ -475,11 +428,11 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, part != WHOLE_SLICE_PART) { u_int64_t start; u_int64_t blocks; - if (lp == NULL) + if (lp.opaque == NULL) return(EINVAL); - if (getpartbounds(lp, part, &start, &blocks)) + if (ops->op_getpartbounds(lp, part, &start, &blocks)) return(EINVAL); - dpart->fstype = getpartfstype(lp, part); + dpart->fstype = ops->op_getpartfstype(lp, part); dpart->media_offset += start * info->d_media_blksize; dpart->media_size = blocks * @@ -512,7 +465,7 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, (char *)ssp); return (0); - case DIOCSDINFO: + case DIOCSDINFO32: /* * You can write a disklabel on the whole disk slice or * whole-slice partition. @@ -532,20 +485,20 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, if (!(flags & FWRITE)) return (EBADF); - lp = kmalloc(sizeof *lp, M_DEVBUF, M_WAITOK); - if (sp->ds_label == NULL) - bzero(lp, sizeof *lp); + lp.opaque = kmalloc(ops->labelsize, M_DEVBUF, M_WAITOK); + if (sp->ds_label.opaque == NULL) + bzero(lp.opaque, ops->labelsize); else - bcopy(sp->ds_label, lp, sizeof *lp); - if (sp->ds_label == NULL) { + bcopy(sp->ds_label.opaque, lp.opaque, ops->labelsize); + if (sp->ds_label.opaque == NULL) { bzero(openmask, sizeof(openmask)); } else { bcopy(sp->ds_openmask, openmask, sizeof(openmask)); } - error = setdisklabel(lp, (struct disklabel *)data, - sp, openmask); + lptmp.opaque = data; + error = ops->op_setdisklabel(lp, lptmp, sp, openmask); if (error != 0) { - kfree(lp, M_DEVBUF); + kfree(lp.opaque, M_DEVBUF); return (error); } free_ds_label(ssp, slice); @@ -588,11 +541,8 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, * complete, then lock out future accesses and opens. */ *sspp = NULL; - lp = kmalloc(sizeof *lp, M_DEVBUF, M_WAITOK); - *lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label; error = dsopen(dev, S_IFCHR, ssp->dss_oflags, sspp, info); if (error != 0) { - kfree(lp, M_DEVBUF); *sspp = ssp; return (error); } @@ -611,19 +561,17 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, S_IFCHR, ssp->dss_oflags, sspp, info); if (error != 0) { - kfree(lp, M_DEVBUF); *sspp = ssp; return (EBUSY); } } } - kfree(lp, M_DEVBUF); dsgone(&ssp); return (0); - case DIOCWDINFO: - error = dsioctl(dev, DIOCSDINFO, data, flags, &ssp, info); + case DIOCWDINFO32: + error = dsioctl(dev, DIOCSDINFO32, data, flags, &ssp, info); if (error != 0) return (error); @@ -632,29 +580,11 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, */ old_wlabel = sp->ds_wlabel; set_ds_wlabel(ssp, slice, TRUE); - old_reserved = sp->ds_reserved; - sp->ds_reserved = SBSIZE / ssp->dss_secsize; - error = writedisklabel(dev, sp->ds_label); + error = ops->op_writedisklabel(dev, sp, sp->ds_label); set_ds_wlabel(ssp, slice, old_wlabel); - sp->ds_reserved = old_reserved; /* XXX should invalidate in-core label if write failed. */ return (error); - case DIOCSETSNOOP: - /* - * Set label snooping even if there is no label present. - */ - if (slice == WHOLE_DISK_SLICE || part != WHOLE_SLICE_PART) - return (EINVAL); - if (lp == NULL) { - if (*(int *)data) { - sp->ds_reserved = SBSIZE / ssp->dss_secsize; - } else { - sp->ds_reserved = 0; - } - } - return (0); - case DIOCWLABEL: if (slice == WHOLE_DISK_SLICE) return (ENODEV); @@ -668,27 +598,6 @@ dsioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, } } -/* - * Chain the bio_done. b_cmd remains valid through such chaining. - */ -static void -dsiodone(struct bio *bio) -{ - struct buf *bp = bio->bio_buf; - char *msg; - - if (bp->b_cmd != BUF_CMD_READ - || (!(bp->b_flags & B_ERROR) && bp->b_error == 0)) { - msg = fixlabel(NULL, bio->bio_caller_info1.ptr, - (struct disklabel *) - (bp->b_data + (int)bio->bio_caller_info2.offset), - FALSE); - if (msg != NULL) - kprintf("%s\n", msg); - } - biodone(bio->bio_prev); -} - int dsisopen(struct diskslices *ssp) { @@ -903,7 +812,7 @@ dsopen(cdev_t dev, int mode, u_int flags, * template. */ sp = &ssp->dss_slices[WHOLE_DISK_SLICE]; - sp->ds_label = clone_label(info, NULL); + sp->ds_label = ops->op_clone_label(info, NULL); sp->ds_wlabel = TRUE; sp->ds_reserved = 0; } @@ -927,7 +836,7 @@ dsopen(cdev_t dev, int mode, u_int flags, sp = &ssp->dss_slices[slice]; part = dkpart(dev); - if ((flags & DSO_NOLABELS) == 0 && sp->ds_label == NULL) { + if ((flags & DSO_NOLABELS) == 0 && sp->ds_label.opaque == NULL) { dev1 = dkmodslice(dkmodpart(dev, WHOLE_SLICE_PART), slice); /* @@ -953,8 +862,10 @@ dsopen(cdev_t dev, int mode, u_int flags, * table need exist. */ if (part != WHOLE_SLICE_PART && slice != WHOLE_DISK_SLICE) { - if (sp->ds_label == NULL || part >= getnumparts(sp->ds_label)) + if (sp->ds_label.opaque == NULL || + part >= ops->op_getnumparts(sp->ds_label)) { return (EINVAL); + } } dssetmask(sp, part); @@ -983,34 +894,29 @@ dsreadandsetlabel(cdev_t dev, u_int flags, struct diskslices *ssp, struct diskslice *sp, struct disk_info *info) { - struct disklabel *lp1; + disklabel_t lp; const char *msg; const char *sname; char partname[2]; int slice = dkslice(dev); - u_int64_t old_reserved; + + lp.opaque = NULL; sname = dsname(dev, dkunit(dev), slice, WHOLE_SLICE_PART, partname); - lp1 = clone_label(info, sp); - old_reserved = sp->ds_reserved; - sp->ds_reserved = 0; - msg = readdisklabel(dev, lp1); - sp->ds_reserved = old_reserved; + msg = ops->op_readdisklabel(dev, sp, &lp, info); if (msg != NULL && (flags & DSO_COMPATLABEL)) { msg = NULL; - kfree(lp1, M_DEVBUF); - lp1 = clone_label(info, sp); + lp = ops->op_clone_label(info, sp); } - if (msg == NULL) - msg = fixlabel(sname, sp, lp1, FALSE); if (msg != NULL) { if (sp->ds_type == DOSPTYP_386BSD /* XXX */) log(LOG_WARNING, "%s: cannot find label (%s)\n", sname, msg); - kfree(lp1, M_DEVBUF); + if (lp.opaque) + kfree(lp.opaque, M_DEVBUF); } else { - set_ds_label(ssp, slice, lp1); + set_ds_label(ssp, slice, lp); set_ds_wlabel(ssp, slice, FALSE); } return (msg ? EINVAL : 0); @@ -1019,7 +925,7 @@ dsreadandsetlabel(cdev_t dev, u_int flags, int64_t dssize(cdev_t dev, struct diskslices **sspp) { - struct disklabel *lp; + disklabel_t lp; int part; int slice; struct diskslices *ssp; @@ -1037,9 +943,9 @@ dssize(cdev_t dev, struct diskslices **sspp) ssp = *sspp; } lp = ssp->dss_slices[slice].ds_label; - if (lp == NULL) + if (lp.opaque == NULL) return (-1); - if (getpartbounds(lp, part, &start, &blocks)) + if (ops->op_getpartbounds(lp, part, &start, &blocks)) return (-1); return ((int64_t)blocks); } @@ -1047,24 +953,25 @@ dssize(cdev_t dev, struct diskslices **sspp) static void free_ds_label(struct diskslices *ssp, int slice) { - struct disklabel *lp; struct diskslice *sp; + disklabel_t lp; sp = &ssp->dss_slices[slice]; lp = sp->ds_label; - if (lp == NULL) - return; - kfree(lp, M_DEVBUF); - set_ds_label(ssp, slice, (struct disklabel *)NULL); + if (lp.opaque != NULL) { + kfree(lp.opaque, M_DEVBUF); + lp.opaque = NULL; + set_ds_label(ssp, slice, lp); + } } static void -set_ds_label(struct diskslices *ssp, int slice, struct disklabel *lp) +set_ds_label(struct diskslices *ssp, int slice, disklabel_t lp) { struct diskslice *sp = &ssp->dss_slices[slice]; sp->ds_label = lp; - adjust_label_reserved(ssp, slice, sp); + ops->op_adjust_label_reserved(ssp, slice, sp); } static void diff --git a/sys/sys/disklabel.h b/sys/sys/disklabel.h index 7dc749eaeb..dfc8f21bab 100644 --- a/sys/sys/disklabel.h +++ b/sys/sys/disklabel.h @@ -1,38 +1,40 @@ /* - * Copyright (c) 1987, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * + * Copyright (c) 2007 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 - * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/disklabel.h,v 1.26 2007/06/17 23:50:12 dillon Exp $ + * + * $DragonFly: src/sys/sys/disklabel.h,v 1.27 2007/06/18 05:13:42 dillon Exp $ + */ +/* + * Disklabel abstraction */ #ifndef _SYS_DISKLABEL_H_ @@ -41,177 +43,50 @@ #ifndef _SYS_TYPES_H_ #include #endif -#if defined(_KERNEL) && !defined(_SYS_SYSTM_H_) -#include +#ifndef _SYS_UUID_H_ +#include #endif -#ifndef _SYS_IOCCOM_H_ -#include -#endif - -/* - * Each disk has a label which includes information about the hardware - * disk geometry, filesystem partitions, and drive specific information. - * The label is in block 0 or 1, possibly offset from the beginning - * to leave room for a bootstrap, etc. - */ -/* XXX these should be defined per controller (or drive) elsewhere, not here! */ -#ifdef __i386__ -#define LABELSECTOR 1 /* sector containing label */ -#define LABELOFFSET 0 /* offset of label in sector */ -#endif +struct disklabel32; +struct disklabel64; -#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */ -#ifndef MAXPARTITIONS -#define MAXPARTITIONS 16 -#endif - -#define LABEL_PART 2 /* partition containing label */ -#define RAW_PART 2 /* partition containing whole disk */ -#define SWAP_PART 1 /* partition normally containing swap */ - -#ifndef LOCORE -struct disklabel { - u_int32_t d_magic; /* the magic number */ - u_int16_t d_type; /* drive type */ - u_int16_t d_subtype; /* controller/d_type specific */ - char d_typename[16]; /* type name, e.g. "eagle" */ - - char d_packname[16]; /* pack identifier */ - - /* disk geometry: */ - u_int32_t d_secsize; /* # of bytes per sector */ - u_int32_t d_nsectors; /* # of data sectors per track */ - u_int32_t d_ntracks; /* # of tracks per cylinder */ - u_int32_t d_ncylinders; /* # of data cylinders per unit */ - u_int32_t d_secpercyl; /* # of data sectors per cylinder */ - u_int32_t d_secperunit; /* # of data sectors per unit */ - - /* - * Spares (bad sector replacements) below are not counted in - * d_nsectors or d_secpercyl. Spare sectors are assumed to - * be physical sectors which occupy space at the end of each - * track and/or cylinder. - */ - u_int16_t d_sparespertrack; /* # of spare sectors per track */ - u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */ - /* - * Alternate cylinders include maintenance, replacement, configuration - * description areas, etc. - */ - u_int32_t d_acylinders; /* # of alt. cylinders per unit */ - - /* hardware characteristics: */ - /* - * d_interleave, d_trackskew and d_cylskew describe perturbations - * in the media format used to compensate for a slow controller. - * Interleave is physical sector interleave, set up by the - * formatter or controller when formatting. When interleaving is - * in use, logically adjacent sectors are not physically - * contiguous, but instead are separated by some number of - * sectors. It is specified as the ratio of physical sectors - * traversed per logical sector. Thus an interleave of 1:1 - * implies contiguous layout, while 2:1 implies that logical - * sector 0 is separated by one sector from logical sector 1. - * d_trackskew is the offset of sector 0 on track N relative to - * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew - * is the offset of sector 0 on cylinder N relative to sector 0 - * on cylinder N-1. - */ - u_int16_t d_rpm; /* rotational speed */ - u_int16_t d_interleave; /* hardware sector interleave */ - u_int16_t d_trackskew; /* sector 0 skew, per track */ - u_int16_t d_cylskew; /* sector 0 skew, per cylinder */ - u_int32_t d_headswitch; /* head switch time, usec */ - u_int32_t d_trkseek; /* track-to-track seek, usec */ - u_int32_t d_flags; /* generic flags (now unused) */ -#define NDDATA 5 - u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ -#define NSPARE 5 - u_int32_t d_spare[NSPARE]; /* reserved for future use */ - u_int32_t d_magic2; /* the magic number (again) */ - u_int16_t d_checksum; /* xor of data incl. partitions */ - - /* filesystem and partition information: */ - u_int16_t d_npartitions; /* number of partitions in following */ - u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ - u_int32_t d_sbsize; /* max size of fs superblock, bytes */ - struct partition { /* the partition table */ - u_int32_t p_size; /* number of sectors in partition */ - u_int32_t p_offset; /* starting sector */ - u_int32_t p_fsize; /* filesystem basic fragment size */ - u_int8_t p_fstype; /* filesystem type, see below */ - u_int8_t p_frag; /* filesystem fragments per block */ - union { - u_int16_t cpg; /* UFS: FS cylinders per group */ - u_int16_t sgs; /* LFS: FS segment shift */ - } __partition_u1; -#define p_cpg __partition_u1.cpg -#define p_sgs __partition_u1.sgs - } d_partitions[MAXPARTITIONS]; /* actually may be more */ -}; - -static u_int16_t dkcksum(struct disklabel *lp); - -static __inline u_int16_t -dkcksum(struct disklabel *lp) -{ - u_int16_t *start, *end; - u_int16_t sum = 0; - - start = (u_int16_t *)lp; - end = (u_int16_t *)&lp->d_partitions[lp->d_npartitions]; - while (start < end) - sum ^= *start++; - return (sum); -} - -#else /* LOCORE */ - /* - * offsets for asm boot files. - */ - .set d_secsize,40 - .set d_nsectors,44 - .set d_ntracks,48 - .set d_ncylinders,52 - .set d_secpercyl,56 - .set d_secperunit,60 - .set d_end_,276 /* size of disk label */ -#endif /* LOCORE */ - -#ifndef LOCORE - -/* - * Disk-specific ioctls. - */ -#define DIOCGDINFO _IOR('d', 101, struct disklabel)/* get */ -#define DIOCSDINFO _IOW('d', 102, struct disklabel)/* set */ -#define DIOCWDINFO _IOW('d', 103, struct disklabel)/* set, update disk */ -#define DIOCGDVIRGIN _IOR('d', 105, struct disklabel) /* get virgin label */ - -#ifdef _KERNEL +typedef union abstracted_disklabel { + void *opaque; + struct disklabel32 *lab32; + struct disklabel64 *lab64; +} disklabel_t; +struct cdev; struct diskslice; struct diskslices; struct disk_info; -char *readdisklabel (cdev_t dev, struct disklabel *lp); -int setdisklabel (struct disklabel *olp, struct disklabel *nlp, - struct diskslice *sp, u_int32_t *openmask); -int writedisklabel (cdev_t dev, struct disklabel *lp); -struct disklabel *clone_label(struct disk_info *info, struct diskslice *sp); -char *fixlabel(const char *sname, struct diskslice *sp, - struct disklabel *lp, int writeflag); -void adjust_label_reserved(struct diskslices *ssp, int slice, struct diskslice *sp); -int getpartbounds(struct disklabel *lp, u_int32_t part, - u_int64_t *start, u_int64_t *blocks); -int getpartfstype(struct disklabel *lp, u_int32_t part); -u_int32_t getnumparts(struct disklabel *lp); -void makevirginlabel(struct disklabel *lp, struct diskslices *ssp, - struct diskslice *sp, struct disk_info *info); - -#endif /* _KERNEL */ - -#endif /* LOCORE */ +struct disklabel_ops { + struct uuid type; /* uuid specifies disklabel type */ + int labelsect; + int labelsize; /* size of disklabel in bytes */ + + const char *(*op_readdisklabel) + (struct cdev *, struct diskslice *, disklabel_t *, + struct disk_info *); + int (*op_setdisklabel) + (disklabel_t, disklabel_t, struct diskslice *, u_int32_t *); + int (*op_writedisklabel) + (struct cdev *, struct diskslice *, disklabel_t); + disklabel_t (*op_clone_label) + (struct disk_info *, struct diskslice *); + void (*op_adjust_label_reserved) + (struct diskslices *, int, struct diskslice *); + int (*op_getpartbounds) + (disklabel_t, u_int32_t, u_int64_t *, u_int64_t *); + int (*op_getpartfstype) + (disklabel_t, u_int32_t); + u_int32_t (*op_getnumparts) + (disklabel_t); + void (*op_makevirginlabel) + (disklabel_t, struct diskslices *, + struct diskslice *, struct disk_info *); +}; #endif /* !_SYS_DISKLABEL_H_ */ + diff --git a/sys/sys/disklabel32.h b/sys/sys/disklabel32.h index 4b8710df9f..9f4f02f67b 100644 --- a/sys/sys/disklabel32.h +++ b/sys/sys/disklabel32.h @@ -32,11 +32,11 @@ * * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/disklabel32.h,v 1.26 2007/06/17 23:50:12 dillon Exp $ + * $DragonFly: src/sys/sys/disklabel32.h,v 1.27 2007/06/18 05:13:42 dillon Exp $ */ -#ifndef _SYS_DISKLABEL_H_ -#define _SYS_DISKLABEL_H_ +#ifndef _SYS_DISKLABEL32_H_ +#define _SYS_DISKLABEL32_H_ #ifndef _SYS_TYPES_H_ #include @@ -57,13 +57,13 @@ /* XXX these should be defined per controller (or drive) elsewhere, not here! */ #ifdef __i386__ -#define LABELSECTOR 1 /* sector containing label */ -#define LABELOFFSET 0 /* offset of label in sector */ +#define LABELSECTOR32 1 /* sector containing label */ +#define LABELOFFSET32 0 /* offset of label in sector */ #endif -#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */ -#ifndef MAXPARTITIONS -#define MAXPARTITIONS 16 +#define DISKMAGIC32 ((u_int32_t)0x82564557) /* The disk magic number */ +#ifndef MAXPARTITIONS32 +#define MAXPARTITIONS32 16 #endif #define LABEL_PART 2 /* partition containing label */ @@ -71,7 +71,7 @@ #define SWAP_PART 1 /* partition normally containing swap */ #ifndef LOCORE -struct disklabel { +struct disklabel32 { u_int32_t d_magic; /* the magic number */ u_int16_t d_type; /* drive type */ u_int16_t d_subtype; /* controller/d_type specific */ @@ -125,10 +125,10 @@ struct disklabel { u_int32_t d_headswitch; /* head switch time, usec */ u_int32_t d_trkseek; /* track-to-track seek, usec */ u_int32_t d_flags; /* generic flags (now unused) */ -#define NDDATA 5 - u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ -#define NSPARE 5 - u_int32_t d_spare[NSPARE]; /* reserved for future use */ +#define NDDATA32 5 + u_int32_t d_drivedata[NDDATA32];/* drive-type specific information */ +#define NSPARE32 5 + u_int32_t d_spare[NSPARE32]; /* reserved for future use */ u_int32_t d_magic2; /* the magic number (again) */ u_int16_t d_checksum; /* xor of data incl. partitions */ @@ -136,7 +136,7 @@ struct disklabel { u_int16_t d_npartitions; /* number of partitions in following */ u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ u_int32_t d_sbsize; /* max size of fs superblock, bytes */ - struct partition { /* the partition table */ + struct partition32 { /* the partition table */ u_int32_t p_size; /* number of sectors in partition */ u_int32_t p_offset; /* starting sector */ u_int32_t p_fsize; /* filesystem basic fragment size */ @@ -148,13 +148,13 @@ struct disklabel { } __partition_u1; #define p_cpg __partition_u1.cpg #define p_sgs __partition_u1.sgs - } d_partitions[MAXPARTITIONS]; /* actually may be more */ + } d_partitions[MAXPARTITIONS32];/* actually may be more */ }; -static u_int16_t dkcksum(struct disklabel *lp); +static u_int16_t dkcksum32(struct disklabel32 *lp); static __inline u_int16_t -dkcksum(struct disklabel *lp) +dkcksum32(struct disklabel32 *lp) { u_int16_t *start, *end; u_int16_t sum = 0; @@ -166,6 +166,10 @@ dkcksum(struct disklabel *lp) return (sum); } +#ifdef _KERNEL +extern struct disklabel_ops disklabel32_ops; +#endif + #else /* LOCORE */ /* * offsets for asm boot files. @@ -184,34 +188,11 @@ dkcksum(struct disklabel *lp) /* * Disk-specific ioctls. */ -#define DIOCGDINFO _IOR('d', 101, struct disklabel)/* get */ -#define DIOCSDINFO _IOW('d', 102, struct disklabel)/* set */ -#define DIOCWDINFO _IOW('d', 103, struct disklabel)/* set, update disk */ -#define DIOCGDVIRGIN _IOR('d', 105, struct disklabel) /* get virgin label */ - -#ifdef _KERNEL - -struct diskslice; -struct diskslices; -struct disk_info; - -char *readdisklabel (cdev_t dev, struct disklabel *lp); -int setdisklabel (struct disklabel *olp, struct disklabel *nlp, - struct diskslice *sp, u_int32_t *openmask); -int writedisklabel (cdev_t dev, struct disklabel *lp); -struct disklabel *clone_label(struct disk_info *info, struct diskslice *sp); -char *fixlabel(const char *sname, struct diskslice *sp, - struct disklabel *lp, int writeflag); -void adjust_label_reserved(struct diskslices *ssp, int slice, struct diskslice *sp); -int getpartbounds(struct disklabel *lp, u_int32_t part, - u_int64_t *start, u_int64_t *blocks); -int getpartfstype(struct disklabel *lp, u_int32_t part); -u_int32_t getnumparts(struct disklabel *lp); -void makevirginlabel(struct disklabel *lp, struct diskslices *ssp, - struct diskslice *sp, struct disk_info *info); - -#endif /* _KERNEL */ +#define DIOCGDINFO32 _IOR('d', 101, struct disklabel32) /* get */ +#define DIOCSDINFO32 _IOW('d', 102, struct disklabel32) /* set */ +#define DIOCWDINFO32 _IOW('d', 103, struct disklabel32) /* set, update disk */ +#define DIOCGDVIRGIN32 _IOR('d', 105, struct disklabel32) /* get virgin label */ #endif /* LOCORE */ -#endif /* !_SYS_DISKLABEL_H_ */ +#endif /* !_SYS_DISKLABEL32_H_ */ diff --git a/sys/sys/disklabel64.h b/sys/sys/disklabel64.h new file mode 100644 index 0000000000..2ea72c92e7 --- /dev/null +++ b/sys/sys/disklabel64.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2007 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $DragonFly: src/sys/sys/disklabel64.h,v 1.1 2007/06/18 05:13:42 dillon Exp $ + */ + +#ifndef _SYS_DISKLABEL64_H_ +#define _SYS_DISKLABEL64_H_ + +#ifndef _SYS_TYPES_H_ +#include +#endif +#if defined(_KERNEL) && !defined(_SYS_SYSTM_H_) +#include +#endif +#ifndef _SYS_IOCCOM_H_ +#include +#endif +#ifndef _SYS_UUID_H_ +#include +#endif + +/* + * 64 disklabels start at offset 0 on the disk or slice they reside. All + * values are byte offsets, not block numbers, in order to allow portability. + * Unlike the original 32 bit disklabels, the on-disk format for a 64 bit + * disklabel is slice-relative and does not have to be translated. + */ + +#define DISKMAGIC64 ((u_int32_t)0xc4464c59) /* The disk magic number */ +#ifndef MAXPARTITIONS64 +#define MAXPARTITIONS64 16 +#endif + +#ifndef LOCORE + +struct disklabel64 { + u_int32_t d_magic; /* the magic number */ + u_int32_t d_crc; /* crc32() */ + u_int32_t d_align; /* partition alignment requirement */ + u_int32_t d_npartitions; /* number of partitions */ + struct uuid d_obj_uuid; /* unique uuid for label */ + + u_int64_t d_total_size; /* total size incl everything (bytes) */ + u_int64_t d_bbase; /* boot area base offset (bytes) */ + /* boot area is pbase - bbase */ + u_int64_t d_pbase; /* first allocatable offset (bytes) */ + u_int64_t d_pstop; /* last allocatable offset+1 (bytes) */ + u_int64_t d_abase; /* location of backup copy if not 0 */ + + struct partition64 { /* the partition table */ + u_int64_t p_boffset; /* slice relative offset, in bytes */ + u_int64_t p_bsize; /* size of partition, in bytes */ + u_int32_t p_unused00; /* reserved for future use */ + u_int32_t p_unused01; /* reserved for future use */ + u_int32_t p_unused02; /* reserved for future use */ + u_int32_t p_unused03; /* reserved for future use */ + struct uuid p_type_uuid;/* mount type as UUID */ + struct uuid p_obj_uuid; /* unique uuid for storage */ + } d_partitions[MAXPARTITIONS64];/* actually may be more */ +}; + +/* + * Disk-specific ioctls. + */ +#define DIOCGDINFO64 _IOR('d', 101, struct disklabel64) +#define DIOCSDINFO64 _IOW('d', 102, struct disklabel64) +#define DIOCWDINFO64 _IOW('d', 103, struct disklabel64) +#define DIOCGDVIRGIN64 _IOR('d', 105, struct disklabel64) + +#endif /* LOCORE */ + +#endif /* !_SYS_DISKLABEL64_H_ */ diff --git a/sys/sys/diskslice.h b/sys/sys/diskslice.h index d1de866380..aea9317b4e 100644 --- a/sys/sys/diskslice.h +++ b/sys/sys/diskslice.h @@ -57,7 +57,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/sys/diskslice.h,v 1.36.2.1 2001/01/29 01:50:50 ken Exp $ - * $DragonFly: src/sys/sys/diskslice.h,v 1.20 2007/06/17 09:56:17 dillon Exp $ + * $DragonFly: src/sys/sys/diskslice.h,v 1.21 2007/06/18 05:13:42 dillon Exp $ */ #ifndef _SYS_DISKSLICE_H_ @@ -66,6 +66,9 @@ #ifndef _SYS_TYPES_H_ #include #endif +#ifndef _SYS_DISKLABEL_H_ +#include +#endif #ifndef _SYS_IOCCOM_H_ #include #endif @@ -88,7 +91,6 @@ #define DIOCWLABEL _IOW('d', 109, int) #define DIOCGSLICEINFO _IOR('d', 111, struct diskslices) #define DIOCSYNCSLICEINFO _IOW('d', 112, int) -#define DIOCSETSNOOP _IOW('d', 113, int) #define MAX_SLICES 16 /* @@ -129,7 +131,8 @@ struct diskslice { u_int64_t ds_size; /* number of sectors */ u_int32_t ds_reserved; /* sectors reserved parent overlap */ int ds_type; /* (foreign) slice type */ - struct disklabel *ds_label; /* BSD label, if any */ + disklabel_t ds_label; /* label, if any */ + struct disklabel_ops *ds_ops; /* label ops (probe default) */ void *ds_dev; /* devfs token for raw whole slice */ void *ds_devs[MAXPARTITIONS]; /* XXX s.b. in label */ u_int32_t ds_openmask[DKMAXPARTITIONS/(sizeof(u_int32_t)*8)]; @@ -386,7 +389,6 @@ dssetmaskfrommask(struct diskslice *ds, u_int32_t *tmask) struct buf; struct bio; -struct disklabel; struct disk_info; struct bio_queue_head; diff --git a/sys/sys/ndisklabel.h b/sys/sys/ndisklabel.h deleted file mode 100644 index b3d0eb2778..0000000000 --- a/sys/sys/ndisklabel.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2007 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Matthew Dillon - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/sys/sys/Attic/ndisklabel.h,v 1.2 2007/05/15 17:51:02 dillon Exp $ - */ - -/* - * DragonFly disk label - */ -#ifndef _SYS_NDISKLABEL_H_ -#define _SYS_NDISKLABEL_H_ - -#ifndef _SYS_TYPES_H_ -#include -#endif - -/* - * A Dragonfly new-style disklabel always resides at byte offset 4096 - * from the beginning of the block device, regardless of the sector size. - * - * All offsets stored in the disklabel are in bytes relative to the - * beginning of the block device, not relative to the disk label. - */ -#define DFLY_LABEL_BYTE_OFFSET 4096 - -/* - * Misc constants. - * - * Disklabels are stored in native-endian format and are portable as long - * as the code checks for and properly converts the label. Only big-endian - * and little-endian formats are supported. All fields are structuralized. - */ -#define DFLY_DISKMAGIC ((u_int64_t)0xc4466c7942534430ULL) -#define DFLY_DISKMAGIC_OTHER ((u_int64_t)0x30445342796c46c4ULL) -#define DFLY_MAXPARTITIONS 16 - -#ifndef LOCORE - -/* - * The disk label and partitions a-p. All offsets and sizes are in bytes - * but must be sector-aligned. Other then the alignment requirement, the - * disklabel doesn't care what the physical sector size of the media is. - * - * All offsets are in bytes and are relative to the beginning of the - * block device in question (raw disk, slice, whatever), NOT the beginning - * of the label. - */ -struct dfly_disklabel { - u_int64_t d_magic; /* magic number / endian check */ - u_int64_t d_serialno; /* initial disklabel creation */ - u_int64_t d_timestamp; /* timestamp of disklabel creation */ - u_int64_t d_crc; /* cyclic redundancy check for label */ - /* (after any endian translation) */ - u_int64_t d_size; /* size of block device in bytes */ - u_int32_t d_npart; /* actual number of partitions */ - u_int32_t d_labelsize; /* max size of label in bytes */ - u_int32_t d_bootpart; /* -1 if not defined */ - u_int32_t d_version; /* disklabel version control */ - char d_label[64]; /* user defined label (mandatory) */ - char d_reserved[128]; - - /* - * Partitions do not have individual labels. The filesystem or - * storage layer id is specified in ascii, 14 chars max, 0-extended. - * p_layer[15] must always be 0. - * - * All offsets and sizes are in bytes but still must be aligned to - * the native sector size of the media. - */ - struct dfly_diskpart { - u_int64_t p_offset; /* offset in bytes */ - u_int64_t p_size; /* size in bytes */ - u_int32_t p_flags; /* misc flags */ - char p_layer[16]; /* FS or storage layer ID */ - } d_partitions[DFLY_MAXPARTITIONS]; - /* might be extended further */ -}; - -#endif - -#define DFLY_PARTF_VALID 0x0001 /* partition defined */ -#define DFLY_PARTF_GOOD 0x0002 /* fs/storage formatted */ -#define DFLY_PARTF_RECURSE 0x0004 /* recursive disklabel */ - -#define DFLY_DISKLABEL_SWAP "swap" /* strcmp w/ p_layer[] */ -#define DFLY_DISKLABEL_UFS "ufs" /* strcmp w/ p_layer[] */ - -#ifndef LOCORE - -#define DFLY_DIOCGDINFO _IOR('d', 101, struct dfly_disklabel) /* get */ -#define DFLY_DIOCSDINFO _IOW('d', 102, struct dfly_disklabel) /* set */ -#define DFLY_DIOCWDINFO _IOW('d', 103, struct dfly_disklabel) /* set, update */ -#define DFLY_DIOCGDVIRGIN _IOR('d', 105, struct dfly_disklabel) /* get new */ - -#endif - -#endif /* !_SYS_NDISKLABEL_H_ */ diff --git a/sys/sys/odisklabel.h b/sys/sys/odisklabel.h deleted file mode 100644 index 6cca35f698..0000000000 --- a/sys/sys/odisklabel.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 1987, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 - * $FreeBSD: src/sys/sys/disklabel.h,v 1.49.2.7 2001/05/27 05:58:26 jkh Exp $ - * $DragonFly: src/sys/sys/Attic/odisklabel.h,v 1.18 2007/05/16 05:20:25 dillon Exp $ - */ - -#ifndef _SYS_ODISKLABEL_H_ -#define _SYS_ODISKLABEL_H_ - -#ifndef _SYS_TYPES_H_ -#include -#endif -#if defined(_KERNEL) && !defined(_SYS_SYSTM_H_) -#include -#endif -#ifndef _SYS_IOCCOM_H_ -#include -#endif -#if defined(_KERNEL) && !defined(_SYS_CONF_H_) -#include /* for make_sub_dev() */ -#endif - -#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */ -#ifndef MAXPARTITIONS -#define MAXPARTITIONS 16 -#endif - -#define LABEL_PART 2 /* partition containing label */ -#define RAW_PART 2 /* partition containing whole disk */ -#define SWAP_PART 1 /* partition normally containing swap */ - -#ifndef LOCORE -struct odisklabel { - u_int32_t d_magic; /* the magic number */ - u_int16_t d_type; /* drive type */ - u_int16_t d_subtype; /* controller/d_type specific */ - char d_typename[16]; /* type name, e.g. "eagle" */ - - /* - * d_packname contains the pack identifier and is returned when - * the disklabel is read off the disk or in-core copy. - * d_boot0 and d_boot1 are the (optional) names of the - * primary (block 0) and secondary (block 1-15) bootstraps - * as found in /boot. These are returned when using - * getdiskbyname(3) to retrieve the values from /etc/disktab. - */ - union { - char un_d_packname[16]; /* pack identifier */ - struct { - char *un_d_boot0; /* primary bootstrap name */ - char *un_d_boot1; /* secondary bootstrap name */ - } un_b; - } d_un; -#define d_packname d_un.un_d_packname -#define d_boot0 d_un.un_b.un_d_boot0 -#define d_boot1 d_un.un_b.un_d_boot1 - - /* disk geometry: */ - u_int32_t d_secsize; /* # of bytes per sector */ - u_int32_t d_nsectors; /* # of data sectors per track */ - u_int32_t d_ntracks; /* # of tracks per cylinder */ - u_int32_t d_ncylinders; /* # of data cylinders per unit */ - u_int32_t d_secpercyl; /* # of data sectors per cylinder */ - u_int32_t d_secperunit; /* # of data sectors per unit */ - - /* - * Spares (bad sector replacements) below are not counted in - * d_nsectors or d_secpercyl. Spare sectors are assumed to - * be physical sectors which occupy space at the end of each - * track and/or cylinder. - */ - u_int16_t d_sparespertrack; /* # of spare sectors per track */ - u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */ - /* - * Alternate cylinders include maintenance, replacement, configuration - * description areas, etc. - */ - u_int32_t d_acylinders; /* # of alt. cylinders per unit */ - - /* hardware characteristics: */ - /* - * d_interleave, d_trackskew and d_cylskew describe perturbations - * in the media format used to compensate for a slow controller. - * Interleave is physical sector interleave, set up by the - * formatter or controller when formatting. When interleaving is - * in use, logically adjacent sectors are not physically - * contiguous, but instead are separated by some number of - * sectors. It is specified as the ratio of physical sectors - * traversed per logical sector. Thus an interleave of 1:1 - * implies contiguous layout, while 2:1 implies that logical - * sector 0 is separated by one sector from logical sector 1. - * d_trackskew is the offset of sector 0 on track N relative to - * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew - * is the offset of sector 0 on cylinder N relative to sector 0 - * on cylinder N-1. - */ - u_int16_t d_rpm; /* rotational speed */ - u_int16_t d_interleave; /* hardware sector interleave */ - u_int16_t d_trackskew; /* sector 0 skew, per track */ - u_int16_t d_cylskew; /* sector 0 skew, per cylinder */ - u_int32_t d_headswitch; /* head switch time, usec */ - u_int32_t d_trkseek; /* track-to-track seek, usec */ - u_int32_t d_flags; /* generic flags */ -#define NDDATA 5 - u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ -#define NSPARE 5 - u_int32_t d_spare[NSPARE]; /* reserved for future use */ - u_int32_t d_magic2; /* the magic number (again) */ - u_int16_t d_checksum; /* xor of data incl. partitions */ - - /* filesystem and partition information: */ - u_int16_t d_npartitions; /* number of partitions in following */ - u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ - u_int32_t d_sbsize; /* max size of fs superblock, bytes */ - struct opartition { /* the partition table */ - u_int32_t p_size; /* number of sectors in partition */ - u_int32_t p_offset; /* starting sector */ - u_int32_t p_fsize; /* filesystem basic fragment size */ - u_int8_t p_fstype; /* filesystem type, see below */ - u_int8_t p_frag; /* filesystem fragments per block */ - union { - u_int16_t cpg; /* UFS: FS cylinders per group */ - u_int16_t sgs; /* LFS: FS segment shift */ - } __partition_u1; -#define p_cpg __partition_u1.cpg -#define p_sgs __partition_u1.sgs - } d_partitions[MAXPARTITIONS]; /* actually may be more */ -}; - -static u_int16_t odkcksum(struct odisklabel *lp); - -static __inline u_int16_t -odkcksum(struct odisklabel *lp) -{ - u_int16_t *start, *end; - u_int16_t sum = 0; - - start = (u_int16_t *)lp; - end = (u_int16_t *)&lp->d_partitions[lp->d_npartitions]; - while (start < end) - sum ^= *start++; - return (sum); -} - -#else /* LOCORE */ - /* - * offsets for asm boot files. - */ - .set d_secsize,40 - .set d_nsectors,44 - .set d_ntracks,48 - .set d_ncylinders,52 - .set d_secpercyl,56 - .set d_secperunit,60 - .set d_end_,276 /* size of disk label */ -#endif /* LOCORE */ - -/* d_type values: */ -#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ -#define DTYPE_MSCP 2 /* MSCP */ -#define DTYPE_DEC 3 /* other DEC (rk, rl) */ -#define DTYPE_SCSI 4 /* SCSI */ -#define DTYPE_ESDI 5 /* ESDI interface */ -#define DTYPE_ST506 6 /* ST506 etc. */ -#define DTYPE_HPIB 7 /* CS/80 on HP-IB */ -#define DTYPE_HPFL 8 /* HP Fiber-link */ -#define DTYPE_FLOPPY 10 /* floppy */ -#define DTYPE_CCD 11 /* concatenated disk */ -#define DTYPE_VINUM 12 /* vinum volume */ -#define DTYPE_DOC2K 13 /* Msys DiskOnChip */ - -#ifdef DKTYPENAMES -static const char *dktypenames[] = { - "unknown", - "SMD", - "MSCP", - "old DEC", - "SCSI", - "ESDI", - "ST506", - "HP-IB", - "HP-FL", - "type 9", - "floppy", - "CCD", - "Vinum", - "DOC2K", - NULL -}; -#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1) -#endif - -/* - * Filesystem type and version. - * Used to interpret other filesystem-specific - * per-partition information. - */ -#define FS_UNUSED 0 /* unused */ -#define FS_SWAP 1 /* swap */ -#define FS_V6 2 /* Sixth Edition */ -#define FS_V7 3 /* Seventh Edition */ -#define FS_SYSV 4 /* System V */ -#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ -#define FS_V8 6 /* Eighth Edition, 4K blocks */ -#define FS_BSDFFS 7 /* 4.2BSD fast file system */ -#define FS_MSDOS 8 /* MSDOS file system */ -#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */ -#define FS_OTHER 10 /* in use, but unknown/unsupported */ -#define FS_HPFS 11 /* OS/2 high-performance file system */ -#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ -#define FS_BOOT 13 /* partition contains bootstrap */ -#define FS_VINUM 14 /* Vinum drive */ - -#ifdef DKTYPENAMES -static const char *fstypenames[] = { - "unused", - "swap", - "Version 6", - "Version 7", - "System V", - "4.1BSD", - "Eighth Edition", - "4.2BSD", - "MSDOS", - "4.4LFS", - "unknown", - "HPFS", - "ISO9660", - "boot", - "vinum", - NULL -}; -#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1) -#endif - -#ifndef LOCORE - -/* - * Disk-specific ioctls. - */ - /* get and set disklabel; DIOCGPART used internally */ -#define ODIOCGDINFO _IOR('d', 101, struct odisklabel)/* get */ -#define ODIOCSDINFO _IOW('d', 102, struct odisklabel)/* set */ -#define ODIOCWDINFO _IOW('d', 103, struct odisklabel)/* set, update disk */ -#define ODIOCGDVIRGIN _IOR('d', 105, struct odisklabel) /* get virgin label */ - -#endif /* LOCORE */ - -#endif /* !_SYS_ODISKLABEL_H_ */ diff --git a/sys/sys/param.h b/sys/sys/param.h index 97eb464ee1..57bfabf423 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -37,13 +37,13 @@ * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD: src/sys/sys/param.h,v 1.61.2.38 2003/05/22 17:12:01 fjoe Exp $ - * $DragonFly: src/sys/sys/param.h,v 1.40 2007/05/08 02:31:43 dillon Exp $ + * $DragonFly: src/sys/sys/param.h,v 1.41 2007/06/18 05:13:43 dillon Exp $ */ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ -#define BSD 200307 /* XXX kern.osrevision */ +#define BSD 200701 /* XXX kern.osrevision */ #define BSD4_3 1 /* XXX obsolete */ #define BSD4_4 1 /* XXX obsolete */ -- 2.41.0