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, §orsize);
+ 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