bin/51138: [PATCH] re-enable growfs(8) to work on vinum volumes in -CURRENT

Lukas Ertl l.ertl at univie.ac.at
Fri Apr 18 14:30:03 PDT 2003


>Number:         51138
>Category:       bin
>Synopsis:       [PATCH] re-enable growfs(8) to work on vinum volumes in -CURRENT
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 18 14:30:00 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Lukas Ertl
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Vienna University Computer Center
>Environment:
System: FreeBSD korben 5.0-CURRENT FreeBSD 5.0-CURRENT #4: Fri Apr 18 13:27:37 CEST 2003 le at korben:/usr/obj/usr/src/sys/KORBEN i386


	
>Description:

>From the 5.0-RELEASE errata:

"growfs(8) no longer works on vinum(4) volumes (and presumably, on geom(4) 
entities) since these subsystems no longer fake disklabels, but growfs(8) 
insists on examining a label."

This patch removes this bug.

>How-To-Repeat:

N/A.

>Fix:

	

--- growfs.c.diff begins here ---
Index: sbin/growfs/growfs.c
===================================================================
RCS file: /u/cvs/cvs/src/sbin/growfs/growfs.c,v
retrieving revision 1.13
diff -u -r1.13 growfs.c
--- sbin/growfs/growfs.c	30 Dec 2002 21:18:05 -0000	1.13
+++ sbin/growfs/growfs.c	18 Apr 2003 21:01:18 -0000
@@ -56,6 +56,7 @@
 #include <sys/disklabel.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <sys/disk.h>
 
 #include <stdio.h>
 #include <paths.h>
@@ -111,6 +112,8 @@
 static char		inobuf[MAXBSIZE];	/* inode block */
 static int		maxino;			/* last valid inode */
 
+static int  unlabeled;   /* unlabeled partition, e.g. vinum volume etc. */
+
 /*
  * An  array of elements of type struct gfs_bpp describes all blocks  to
  * be relocated in order to free the space needed for the cylinder group
@@ -148,6 +151,7 @@
 static void	updrefs(int, ino_t, struct gfs_bpp *, int, int, unsigned int);
 static void	indirchk(ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t, ufs_lbn_t,
 		    struct gfs_bpp *, int, int, unsigned int);
+static void     get_dev_size(int, int *);
 
 /* ************************************************************ growfs ***** */
 /*
@@ -1884,6 +1888,26 @@
 	return columns;
 }
 
+/* ****************************************************** get_dev_size ***** */
+/*
+ * Get the size of the partition if we can't figure it out from the disklabel,
+ * e.g. from vinum volumes.
+ */
+static void
+get_dev_size(int fd, int *size)
+{
+	int sectorsize;
+	off_t mediasize;
+
+	ioctl(fd, DIOCGSECTORSIZE, &sectorsize);
+	ioctl(fd, DIOCGMEDIASIZE, &mediasize);
+
+	if (sectorsize <= 0)
+		errx(1, "bogus sectorsize: %d", sectorsize);
+
+	*size = mediasize / sectorsize;
+}
+
 /* ************************************************************** main ***** */
 /*
  * growfs(8)  is a utility which allows to increase the size of  an  existing
@@ -1921,6 +1945,7 @@
 	struct disklabel	*lp;
 	struct partition	*pp;
 	int	i,fsi,fso;
+	u_int32_t p_size;
 	char	reply[5];
 #ifdef FSMAXSNAP
 	int	j;
@@ -2020,25 +2045,30 @@
 	 */
 	cp=device+strlen(device)-1;
 	lp = get_disklabel(fsi);
-	if(lp->d_type == DTYPE_VINUM) {
-		pp = &lp->d_partitions[0];
-	} else if (isdigit(*cp)) {
-		pp = &lp->d_partitions[2];
-	} else if (*cp>='a' && *cp<='h') {
-		pp = &lp->d_partitions[*cp - 'a'];
+	if (lp != NULL) {
+		if (isdigit(*cp)) {
+			pp = &lp->d_partitions[2];
+		} else if (*cp>='a' && *cp<='h') {
+			pp = &lp->d_partitions[*cp - 'a'];
+		} else {
+			errx(1, "unknown device");
+		}
+		p_size = pp->p_size;
 	} else {
-		errx(1, "unknown device");
+		get_dev_size(fsi, &p_size);
 	}
 
 	/*
 	 * Check if that partition looks suited for growing a file system.
 	 */
-	if (pp->p_size < 1) {
+	if (p_size < 1) {
 		errx(1, "partition is unavailable");
 	}
+/*
 	if (pp->p_fstype != FS_BSDFFS) {
 		errx(1, "partition not 4.2BSD");
 	}
+*/
 
 	/*
 	 * Read the current superblock, and take a backup.
@@ -2067,11 +2097,11 @@
 	 * Determine size to grow to. Default to the full size specified in
 	 * the disk label.
 	 */
-	sblock.fs_size = dbtofsb(&osblock, pp->p_size);
+	sblock.fs_size = dbtofsb(&osblock, p_size);
 	if (size != 0) {
-		if (size > pp->p_size){
+		if (size > p_size){
 			errx(1, "There is not enough space (%d < %d)",
-			    pp->p_size, size);
+			    p_size, size);
 		}
 		sblock.fs_size = dbtofsb(&osblock, size);	
 	}
@@ -2121,7 +2151,7 @@
 	 * later on realize we have to abort our operation, on that block
 	 * there should be no data, so we can't destroy something yet.
 	 */
-	wtfs((ufs2_daddr_t)pp->p_size-1, (size_t)DEV_BSIZE, (void *)&sblock,
+	wtfs((ufs2_daddr_t)p_size-1, (size_t)DEV_BSIZE, (void *)&sblock,
 	    fso, Nflag);
 
 	/*
@@ -2182,12 +2212,14 @@
 	/*
 	 * Update the disk label.
 	 */
-	pp->p_fsize = sblock.fs_fsize;
-	pp->p_frag = sblock.fs_frag;
-	pp->p_cpg = sblock.fs_fpg;
-
-	return_disklabel(fso, lp, Nflag);
-	DBG_PRINT0("label rewritten\n");
+	if (!unlabeled) {
+		pp->p_fsize = sblock.fs_fsize;
+		pp->p_frag = sblock.fs_frag;
+		pp->p_cpg = sblock.fs_fpg;
+		
+		return_disklabel(fso, lp, Nflag);
+		DBG_PRINT0("label rewritten\n");
+	}
 
 	close(fsi);
 	if(fso>-1) close(fso);
@@ -2254,12 +2286,13 @@
 	if (!lab) {
 		errx(1, "malloc failed");
 	}
-	if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
-		errx(1, "DIOCGDINFO failed");
+	if (!ioctl(fd, DIOCGDINFO, (char *)lab)) {
+		return (lab);
 	}
+	unlabeled++;
 
 	DBG_LEAVE;
-	return (lab);
+	return (NULL);
 }
 
 
--- growfs.c.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:
 To: FreeBSD-gnats-submit at freebsd.org
 Subject: [PATCH] re-enable growfs(8) to work on vinum volumes in -CURRENT
 From: Lukas Ertl <le at univie.ac.at>
 Reply-To: Lukas Ertl <le at univie.ac.at>
 Cc: 
 X-send-pr-version: 3.113
 X-GNATS-Notify: 
 
 


More information about the freebsd-bugs mailing list