From le@univie.ac.at  Fri Apr 18 14:25:36 2003
Return-Path: <le@univie.ac.at>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 84F8237B409
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Apr 2003 14:25:36 -0700 (PDT)
Received: from mailbox.univie.ac.at (mailbox.univie.ac.at [131.130.1.27])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 00DCC43FE0
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Apr 2003 14:25:34 -0700 (PDT)
	(envelope-from le@univie.ac.at)
Received: from korben.in.tern (dialin202.cc.univie.ac.at [131.130.202.202])
	by mailbox.univie.ac.at (8.12.2/8.12.2) with ESMTP id h3ILPP6G351802
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Apr 2003 23:25:27 +0200
Received: from korben.in.tern (korben.in.tern [127.0.0.1])
	by korben.in.tern (8.12.9/8.12.9) with ESMTP id h3ILPMnt001284
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 18 Apr 2003 23:25:23 +0200 (CEST)
	(envelope-from le@korben.in.tern)
Received: (from le@localhost)
	by korben.in.tern (8.12.9/8.12.9/Submit) id h3ILPL9i001283
	for FreeBSD-gnats-submit@freebsd.org; Fri, 18 Apr 2003 23:25:22 +0200 (CEST)
	(envelope-from le)
Message-Id: <200304182125.h3ILPL9i001283@korben.in.tern>
Date: Fri, 18 Apr 2003 23:25:22 +0200 (CEST)
From: Lukas Ertl <l.ertl@univie.ac.at>
To: FreeBSD-gnats-submit@freebsd.org
Subject: [PATCH] re-enable growfs(8) to work on vinum volumes in -CURRENT

>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:    grog
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 18 14:30:00 PDT 2003
>Closed-Date:    Sun May 11 23:34:42 PDT 2003
>Last-Modified:  Sun May 11 23:34:42 PDT 2003
>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@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:

From: Lukas Ertl <l.ertl@univie.ac.at>
To: freebsd-gnats-submit@FreeBSD.org, l.ertl@univie.ac.at,
	freebsd-bugs@FreeBSD.org
Cc:  
Subject: Re: bin/51138: [PATCH] re-enable growfs(8) to work on vinum volumes
 in -CURRENT
Date: Sat, 26 Apr 2003 19:45:04 +0200 (CEST)

 This is an updated patch that applies to rev. 1.14 of growfs.c.
 
 I'd really appreciate it if someone could take a look at it, because I
 think it should go into 5.1.
 
 --- growfs.c.diff begins here ---
 Index: sbin/growfs/growfs.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /u/cvs/cvs/src/sbin/growfs/growfs.c,v
 retrieving revision 1.14
 diff -u -r1.14 growfs.c
 --- sbin/growfs/growfs.c=0926 Apr 2003 15:22:29 -0000=091.14
 +++ sbin/growfs/growfs.c=0926 Apr 2003 17:40:30 -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>
 @@ -110,6 +111,7 @@
  static ufs2_daddr_t =09inoblk;=09=09=09/* inode block address */
  static char=09=09inobuf[MAXBSIZE];=09/* inode block */
  static int=09=09maxino;=09=09=09/* last valid inode */
 +static int=09=09unlabeled;     /* unlabeled partition, e.g. vinum volume e=
 tc. */
 
  /*
   * An array of elements of type struct gfs_bpp describes all blocks to
 @@ -148,6 +150,7 @@
  static void=09updrefs(int, ino_t, struct gfs_bpp *, int, int, unsigned int=
 );
  static void=09indirchk(ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t, ufs_lbn_t,
  =09=09    struct gfs_bpp *, int, int, unsigned int);
 +static void=09get_dev_size(int, int *);
 
  /* ************************************************************ growfs ***=
 ** */
  /*
 @@ -1880,6 +1883,28 @@
  =09return columns;
  }
 
 +/* ****************************************************** get_dev_size ***=
 ** */
 +/*
 + * Get the size of the partition if we can't figure it out from the diskla=
 bel,
 + * e.g. from vinum volumes.
 + */
 +static void
 +get_dev_size(int fd, int *size)
 +{
 +   int sectorsize;
 +   off_t mediasize;
 +
 +   if (ioctl(fd, DIOCGSECTORSIZE, &sectorsize) =3D=3D -1)
 +        err(1,"DIOCGSECTORSIZE");
 +   if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) =3D=3D -1)
 +        err(1,"DIOCGMEDIASIZE");
 +
 +   if (sectorsize <=3D 0)
 +       errx(1, "bogus sectorsize: %d", sectorsize);
 +
 +   *size =3D mediasize / sectorsize;
 +}
 +
  /* ************************************************************** main ***=
 ** */
  /*
   * growfs(8)  is a utility which allows to increase the size of an existin=
 g
 @@ -1917,6 +1942,7 @@
  =09struct disklabel=09*lp;
  =09struct partition=09*pp;
  =09int=09i,fsi,fso;
 +    u_int32_t p_size;
  =09char=09reply[5];
  #ifdef FSMAXSNAP
  =09int=09j;
 @@ -2016,25 +2042,30 @@
  =09 */
  =09cp=3Ddevice+strlen(device)-1;
  =09lp =3D get_disklabel(fsi);
 -=09if(lp->d_type =3D=3D DTYPE_VINUM) {
 -=09=09pp =3D &lp->d_partitions[0];
 -=09} else if (isdigit(*cp)) {
 -=09=09pp =3D &lp->d_partitions[2];
 -=09} else if (*cp>=3D'a' && *cp<=3D'h') {
 -=09=09pp =3D &lp->d_partitions[*cp - 'a'];
 -=09} else {
 -=09=09errx(1, "unknown device");
 -=09}
 +    if (lp !=3D NULL) {
 +        if (isdigit(*cp)) {
 +            pp =3D &lp->d_partitions[2];
 +        } else if (*cp>=3D'a' && *cp<=3D'h') {
 +            pp =3D &lp->d_partitions[*cp - 'a'];
 +        } else {
 +            errx(1, "unknown device");
 +        }
 +        p_size =3D pp->p_size;
 +    } else {
 +        get_dev_size(fsi, &p_size);
 +    }
 
  =09/*
  =09 * Check if that partition is suitable for growing a file system.
  =09 */
 -=09if (pp->p_size < 1) {
 +=09if (p_size < 1) {
  =09=09errx(1, "partition is unavailable");
  =09}
 +/*
  =09if (pp->p_fstype !=3D FS_BSDFFS) {
  =09=09errx(1, "partition not 4.2BSD");
  =09}
 +*/
 
  =09/*
  =09 * Read the current superblock, and take a backup.
 @@ -2063,11 +2094,11 @@
  =09 * Determine size to grow to. Default to the full size specified in
  =09 * the disk label.
  =09 */
 -=09sblock.fs_size =3D dbtofsb(&osblock, pp->p_size);
 +=09sblock.fs_size =3D dbtofsb(&osblock, p_size);
  =09if (size !=3D 0) {
 -=09=09if (size > pp->p_size){
 +=09=09if (size > p_size){
  =09=09=09errx(1, "There is not enough space (%d < %d)",
 -=09=09=09    pp->p_size, size);
 +=09=09=09    p_size, size);
  =09=09}
  =09=09sblock.fs_size =3D dbtofsb(&osblock, size);
  =09}
 @@ -2117,7 +2148,7 @@
  =09 * later on realize we have to abort our operation, on that block
  =09 * there should be no data, so we can't destroy something yet.
  =09 */
 -=09wtfs((ufs2_daddr_t)pp->p_size-1, (size_t)DEV_BSIZE, (void *)&sblock,
 +=09wtfs((ufs2_daddr_t)p_size-1, (size_t)DEV_BSIZE, (void *)&sblock,
  =09    fso, Nflag);
 
  =09/*
 @@ -2178,12 +2209,14 @@
  =09/*
  =09 * Update the disk label.
  =09 */
 -=09pp->p_fsize =3D sblock.fs_fsize;
 -=09pp->p_frag =3D sblock.fs_frag;
 -=09pp->p_cpg =3D sblock.fs_fpg;
 -
 -=09return_disklabel(fso, lp, Nflag);
 -=09DBG_PRINT0("label rewritten\n");
 +    if (!unlabeled) {
 +        pp->p_fsize =3D sblock.fs_fsize;
 +        pp->p_frag =3D sblock.fs_frag;
 +        pp->p_cpg =3D sblock.fs_fpg;
 +
 +        return_disklabel(fso, lp, Nflag);
 +        DBG_PRINT0("label rewritten\n");
 +    }
 
  =09close(fsi);
  =09if(fso>-1) close(fso);
 @@ -2247,15 +2280,16 @@
  =09DBG_ENTER;
 
  =09lab=3D(struct disklabel *)malloc(sizeof(struct disklabel));
 -=09if (!lab) {
 +=09if (!lab)
  =09=09errx(1, "malloc failed");
 -=09}
 -=09if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
 -=09=09errx(1, "DIOCGDINFO failed");
 -=09}
 +
 +    if (!ioctl(fd, DIOCGDINFO, (char *)lab))
 +        return (lab);
 +
 +    unlabeled++;
 
  =09DBG_LEAVE;
 -=09return (lab);
 +=09return (NULL);
  }
 
 
 --- growfs.c.diff ends here ---
 
 --=20
 Lukas Ertl                             eMail: l.ertl@univie.ac.at
 UNIX-Systemadministrator               Tel.:  (+43 1) 4277-14073
 Zentraler Informatikdienst (ZID)       Fax.:  (+43 1) 4277-9140
 der Universit=E4t Wien                   http://mailbox.univie.ac.at/~le/
State-Changed-From-To: open->closed 
State-Changed-By: grog 
State-Changed-When: Sun May 11 23:33:33 PDT 2003 
State-Changed-Why:  
Fix committed. 


Responsible-Changed-From-To: freebsd-bugs->grog 
Responsible-Changed-By: grog 
Responsible-Changed-When: Sun May 11 23:33:33 PDT 2003 
Responsible-Changed-Why:  
Fix committed. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=51138 
>Unformatted:
 To: FreeBSD-gnats-submit@freebsd.org
 Subject: [PATCH] re-enable growfs(8) to work on vinum volumes in -CURRENT
 From: Lukas Ertl <le@univie.ac.at>
 Reply-To: Lukas Ertl <le@univie.ac.at>
 Cc: 
 X-send-pr-version: 3.113
 X-GNATS-Notify: 
 
 
Greg Lehey, 12 May 2003

Committed, thanks!

PR closed.
