bin/51138: [PATCH] re-enable growfs(8) to work on vinum volumes
in -CURRENT
Lukas Ertl
l.ertl at univie.ac.at
Sat Apr 26 10:50:20 PDT 2003
The following reply was made to PR bin/51138; it has been noted by GNATS.
From: Lukas Ertl <l.ertl at univie.ac.at>
To: freebsd-gnats-submit at FreeBSD.org, l.ertl at univie.ac.at,
freebsd-bugs at 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, §orsize) =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 at 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/
More information about the freebsd-bugs
mailing list