From owner-p4-projects Sun Feb 9 19:20:30 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B57D237B405; Sun, 9 Feb 2003 19:20:17 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3B19337B401 for ; Sun, 9 Feb 2003 19:20:17 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id A2D9F43FDD for ; Sun, 9 Feb 2003 19:20:16 -0800 (PST) (envelope-from jmallett@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h1A3KGbv035232 for ; Sun, 9 Feb 2003 19:20:16 -0800 (PST) (envelope-from jmallett@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h1A3KG3J035224 for perforce@freebsd.org; Sun, 9 Feb 2003 19:20:16 -0800 (PST) Date: Sun, 9 Feb 2003 19:20:16 -0800 (PST) Message-Id: <200302100320.h1A3KG3J035224@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jmallett@freebsd.org using -f From: Juli Mallett Subject: PERFORCE change 24928 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=24928 Change 24928 by jmallett@jmallett_dalek on 2003/02/09 19:19:24 fxlabel.c: *) Code to add a partition. *) Abstract the decode / encode operations and use them appropriately. *) Abstract label summing. *) Make it possible to add files. *) Make it possible to get non-block-aligned files. *) Make it possible to delete files. diskfx.h: *) Add defines for each type in the type list. Affected files ... .. //depot/projects/mips/sbin/fxlabel/fxlabel.c#5 edit .. //depot/projects/mips/sys/sys/diskfx.h#6 edit Differences ... ==== //depot/projects/mips/sbin/fxlabel/fxlabel.c#5 (text+ko) ==== @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ struct volhdr label; struct volpart *vhp = &label.vh_part[FX_VOLHDRPART]; -static int needswap; static int bsize = 512; /* @@ -54,11 +54,14 @@ static void dirlist(struct volhdr *); static void getfile(struct volhdr *, int, const char *); static bool goodlabel(struct volhdr *, const char **); +static int32_t labelsum(struct volhdr *); static void newlabel(struct volhdr *); static void printlabel(struct volhdr *); static bool readlabel(int); +static void setpart(struct volhdr *, int, int, int, int); static void sumlabel(struct volhdr *); -static void swaplabel(struct volhdr *); +static void swap_dec_label(struct volhdr *); +static void swap_enc_label(struct volhdr *); static int startdisk(const char *, int); static bool writelabel(int); @@ -76,14 +79,15 @@ { const char *aflag, *dflag, *disk, *gflag; bool pflag, wflag; + int sflag; int ch; int fd; aflag = dflag = gflag = NULL; pflag = wflag = false; - needswap = be16toh(0x1234) != 0x1234; + sflag = 0; - while ((ch = getopt(argc, argv, "a:d:g:pw")) != -1) { + while ((ch = getopt(argc, argv, "a:d:g:ps:w")) != -1) { switch (ch) { case 'a': aflag = optarg; @@ -99,6 +103,14 @@ usage(); pflag = true; break; + case 's': + sflag = atoi(optarg); + if (sflag < bsize) { + warnx("volume header size not >= %d", bsize); + usage(); + } + sflag = ((sflag + 511) / bsize) * bsize; + break; case 'w': if (pflag) usage(); @@ -115,13 +127,14 @@ if (aflag == NULL && dflag == NULL && gflag == NULL && !pflag && !wflag) pflag = true; + if (!sflag) + sflag = 1; + while ((disk = *argv++) != NULL) { if (aflag != NULL) { fd = startdisk(disk, O_RDWR); defrag(&label, fd); addfile(&label, fd, aflag); - sumlabel(&label); - swaplabel(&label); if (writelabel(fd)) err(1, "%s (label write)", disk); close(fd); @@ -131,8 +144,6 @@ fd = startdisk(disk, O_RDWR); deletefile(&label, fd, dflag); defrag(&label, fd); - sumlabel(&label); - swaplabel(&label); if (writelabel(fd)) err(1, "%s (label write)", disk); close(fd); @@ -155,8 +166,7 @@ if (fd == -1) err(1, "%s (open)", disk); newlabel(&label); - sumlabel(&label); - swaplabel(&label); + setpart(&label, FX_VOLHDRPART, FX_TYPEVOLHDR, 0, sflag); if (writelabel(fd)) err(1, "%s (label write)", disk); close(fd); @@ -167,22 +177,98 @@ return (0); } +/* + * This could search through the directory and look for the smallest suitable + * free section, but defrag() should handle that for us in the future, so + * we just look for the end and see if we can fit it. + */ static void addfile(struct volhdr *vp, int fd, const char *file) { - errx(1, "adding of files is unimplemented"); + struct voldir *dp; + struct stat st; + size_t heresz; + ssize_t cnt; + int rounded; + int himark; + char *buf; + int slot; + int ifd; + int rv; + int i; + + himark = slot = -1; + + if (!vhp->vp_size) + errx(1, "can not find volhdr partition"); + ifd = open(file, O_RDONLY); + if (ifd == -1) + err(1, "%s (input open)", file); + rv = fstat(ifd, &st); + if (rv == -1) + err(1, "%s (input stat)", file); + for (i = 0; i < FX_DIRSIZE; i++) { + dp = &vp->vh_dir[i]; + if (!dp->vd_size) { + if (himark == -1) { + himark = 0; + } + slot = i; + continue; + } + if (strncmp(file, dp->vd_name, FX_NAMELEN) == 0) + errx(1, "%s already exists", file); + heresz = dp->vd_size / bsize; + if (himark < dp->vd_addr + heresz) + himark = dp->vd_addr + heresz; + } + if (himark == -1 || slot == -1) + errx(1, "could not find space for %s", file); + dp = &vp->vh_dir[slot]; + strncpy(dp->vd_name, file, FX_NAMELEN); + dp->vd_addr = himark + 1; + dp->vd_size = st.st_size; + rounded = ((st.st_size + 511) / bsize) * bsize; + buf = malloc(rounded); + if (buf == NULL) + errx(1, "malloc failed"); + memset(buf, 0, dp->vd_size); + cnt = read(ifd, buf, st.st_size); + if (cnt < 0 || (size_t)cnt != st.st_size) + err(1, "%s (input read)", file); + cnt = pwrite(fd, buf, rounded, dp->vd_addr * bsize); + if (cnt < 0 || (size_t)cnt != rounded) + err(1, "%s (input write)", file); } static void defrag(struct volhdr *vp, int fd) { - errx(1, "defragmenting of the free space is unimplemented"); + if (!vhp->vp_size) + errx(1, "can not find volhdr partition"); + warnx("defragmenting of the free space is unimplemented"); } static void deletefile(struct volhdr *vp, int fd, const char *file) { - errx(1, "deletion of files is unimplemented"); + struct voldir *dp; + int i; + + if (!vhp->vp_size) + errx(1, "can not find volhdr partition"); + for (i = 0; i < FX_DIRSIZE; i++) { + dp = &vp->vh_dir[i]; + if (!dp->vd_size) + continue; + if (strncmp(file, dp->vd_name, FX_NAMELEN) != 0) + continue; + memset(dp->vd_name, 0, FX_NAMELEN); + dp->vd_addr = 0; + dp->vd_size = 0; + return; + } + errx(1, "could not find %s", file); } static int @@ -222,6 +308,7 @@ getfile(struct volhdr *vp, int fd, const char *file) { struct voldir *dp; + int rounded; ssize_t cnt; char *buf; int ofd; @@ -239,8 +326,9 @@ buf = malloc(dp->vd_size); if (buf == NULL) errx(1, "malloc failed"); - cnt = pread(fd, buf, dp->vd_size, dp->vd_addr * bsize); - if (cnt != dp->vd_size) + rounded = ((dp->vd_size + 511) / bsize) * bsize; + cnt = pread(fd, buf, rounded, dp->vd_addr * bsize); + if (cnt != rounded) err(1, "%s (file read)", file); cnt = write(ofd, buf, dp->vd_size); if (cnt != dp->vd_size) @@ -254,19 +342,13 @@ static bool goodlabel(struct volhdr *vp, const char **errorp) { - int32_t *words; int32_t sum; - int i; - - sum = 0; - words = (int32_t *)vp; if (be32toh(vp->vh_magic) != FX_LABEL_MAGIC) { *errorp = "bad magic"; return (true); } - for (i = 0; i < sizeof *vp / sizeof *words; i++) - sum -= htobe32(words[i]); + sum = labelsum(vp); if (sum != 0) { *errorp = "bad checksum"; return (true); @@ -274,6 +356,22 @@ return (false); } +static int32_t +labelsum(struct volhdr *vp) +{ + int32_t *words; + int32_t sum; + int i; + + sum = 0; + words = (int32_t *)vp; + + for (i = 0; i < sizeof *vp / sizeof *words; i++) + sum -= be32toh(words[i]); + + return sum; +} + static void newlabel(struct volhdr *vp) { @@ -333,6 +431,17 @@ } } +static void +setpart(struct volhdr *vp, int p, int type, int begin, int blocks) +{ + struct volpart *part; + + part = &vp->vh_part[p]; + part->vp_size = blocks * bsize; + part->vp_begin = begin; + part->vp_type = type; +} + static int startdisk(const char *disk, int flags) { @@ -346,7 +455,7 @@ err(1, "%s (label read)", disk); if (goodlabel(&label, &error)) errx(1, "%s (label check): %s", disk, error); - swaplabel(&label); + swap_dec_label(&label); return (fd); } @@ -354,60 +463,82 @@ static void sumlabel(struct volhdr *vp) { - int32_t *words; int32_t sum; - int i; - words = (int32_t *)vp; - sum = 0; vp->vh_csum = 0; + sum = labelsum(vp); + vp->vh_csum = htobe32(sum); +} - for (i = 0; i < sizeof *vp / sizeof *words; i++) - sum += words[i]; - vp->vh_csum = -sum; +#define be16toh_v(v) ((v) = be16toh((v))) +#define be32toh_v(v) ((v) = be32toh((v))) + +static void +swap_dec_label(struct volhdr *vp) +{ + int i; + + be32toh_v(vp->vh_magic); + be16toh_v(vp->vh_root); + be16toh_v(vp->vh_swap); + /* kernel */ + /* ... dparms ... XXX unused */ + for (i = 0; i < FX_DIRSIZE; i++) { + /* name */ + be32toh_v(vp->vh_dir[i].vd_addr); + be32toh_v(vp->vh_dir[i].vd_size); + } + for (i = 0; i < FX_NPARTS; i++) { + be32toh_v(vp->vh_part[i].vp_size); + be32toh_v(vp->vh_part[i].vp_begin); + be32toh_v(vp->vh_part[i].vp_type); + } + be32toh_v(vp->vh_csum); + /* unused */ } -#define swap16(x) (x) = bswap32((x)) -#define swap32(x) (x) = bswap32((x)) +#define htobe16_v(v) ((v) = htobe16((v))) +#define htobe32_v(v) ((v) = htobe32((v))) -/* - * Swaps all the fields to and from network byte order, unless - * we're running in network byte order. - */ static void -swaplabel(struct volhdr *vp) +swap_enc_label(struct volhdr *vp) { int i; - if (!needswap) - return; - - swap32(vp->vh_magic); - swap16(vp->vh_root); - swap16(vp->vh_swap); + htobe32_v(vp->vh_magic); + htobe16_v(vp->vh_root); + htobe16_v(vp->vh_swap); /* kernel */ /* ... dparms ... XXX unused */ for (i = 0; i < FX_DIRSIZE; i++) { /* name */ - swap32(vp->vh_dir[i].vd_addr); - swap32(vp->vh_dir[i].vd_size); + htobe32_v(vp->vh_dir[i].vd_addr); + htobe32_v(vp->vh_dir[i].vd_size); } for (i = 0; i < FX_NPARTS; i++) { - swap32(vp->vh_part[i].vp_size); - swap32(vp->vh_part[i].vp_begin); - swap32(vp->vh_part[i].vp_type); + htobe32_v(vp->vh_part[i].vp_size); + htobe32_v(vp->vh_part[i].vp_begin); + htobe32_v(vp->vh_part[i].vp_type); } - swap32(vp->vh_csum); + htobe32_v(vp->vh_csum); /* unused */ } static bool writelabel(int fd) { + const char *error; + struct volhdr *vp; ssize_t cnt; - cnt = pwrite(fd, &label, sizeof label, 0); - if (cnt < 0 || (size_t)cnt != sizeof label) { + vp = &label; + + swap_enc_label(vp); + sumlabel(vp); + if (goodlabel(vp, &error)) + errx(1, "(label writeback): %s", error); + cnt = pwrite(fd, vp, sizeof *vp, 0); + if (cnt < 0 || (size_t)cnt != sizeof *vp) { return (true); } else { return (false); @@ -422,6 +553,6 @@ " fxlabel [-d file] disk [...]\n" " fxlabel [-g file] disk [...]\n" " fxlabel [-p] disk [...]\n" -" fxlabel [-w] disk [...]\n"); +" fxlabel [-w] [-s size] disk [...]\n"); exit(-1); } ==== //depot/projects/mips/sys/sys/diskfx.h#6 (text+ko) ==== @@ -35,20 +35,35 @@ #define FX_NAMELEN 8 static const char *fx_typename[] = { +#define FX_TYPEVOLHDR 0 "Volume Header", +#define FX_TYPERTRKS 1 "Repl Trks", +#define FX_TYPERSECS 2 "Repl Secs", +#define FX_TYPERAW 3 "Raw", +#define FX_TYPE42BSD 4 "4.2BSD", +#define FX_TYPESYSV 5 "SysV", +#define FX_TYPEVOL 6 "Volume", +#define FX_TYPEEFS 7 "EFS", +#define FX_TYPELVOL 8 "LVol", +#define FX_TYPERLVOL 9 "RLVol", +#define FX_TYPEXFS 10 "XFS", +#define FX_TYPEXFSLOG 11 "XFSLog", +#define FX_TYPEXLV 12 "XLV", +#define FX_TYPEXVM 13 "XVM" +#define FX_TYPEMAX 14 }; struct dparms { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message