Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Feb 2003 19:20:16 -0800 (PST)
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 24928 for review
Message-ID:  <200302100320.h1A3KG3J035224@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/diskfx.h>
 #include <sys/endian.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <err.h>
 #include <fcntl.h>
 #include <stdbool.h>
@@ -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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302100320.h1A3KG3J035224>