Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Apr 2003 20:04:17 +0200 (CEST)
From:      Lukas Ertl <l.ertl@univie.ac.at>
To:        freebsd-hackers@freebsd.org
Subject:   growing filesystems in 5-current
Message-ID:  <20030416195328.V719@leelou.in.tern>

next in thread | raw e-mail | index | archive | help
Hi Hackers,

since growfs currently is not able to grow filesystems on vinum volumes in
5-current, I started playing around with it and hacked to following patch.
On first look it seems to work, but there is still a problem I can't
explain.

Consider a simple vinum volume with a concat plex, containing a 32 MB
subdisk. I newfs this volume like that:

---8<---
# newfs -O2 /dev/vinum/mytest
/dev/vinum/mytest: 32.0MB (65536 sectors) block size 16384, fragment size
2048
        using 4 cylinder groups of 8.02MB, 513 blks, 1088 inodes.
super-block backups (for fsck -b #) at:
 160, 16576, 32992, 49408
---8<---

So far, so good. Then I attach another 32 MB subdisk to the plex and try
my hacked growfs on it and I get this:

---8<---
# growfs /dev/vinum/mytest
We strongly recommend you to make a backup before growing the Filesystem

 Did you backup your data (Yes/No) ? Yes
new file systemsize is: 32768 frags
Warning: 16160 sector(s) cannot be allocated.
growfs: 56.1MB (114912 sectors) block size 16384, fragment size 2048
        using 7 cylinder groups of 8.02MB, 513 blks, 1088 inodes.
super-block backups (for fsck -b #) at:
 65824, 82240, 98656
---8<---

Why do I loose so many sectors there? Can you help me find the bug?

At first I suspected sblock.fs_fpg, since a debug printf after:

---8<---
    if (sblock.fs_size % sblock.fs_fpg !=3D 0 &&
        sblock.fs_size % sblock.fs_fpg < cgdmin(&sblock, sblock.fs_ncg)) {
---8<---

said that sblock.fs_fpg is 0 - a debug printf before that if statement
told me a more likely number.

Apart from that: am I going the wrong way with this patch? Is there a
better way to fit growfs to the new vinum/geom stuff?

Here's the patch:

---8<---
Index: 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.13
diff -u -r1.13 growfs.c
--- growfs.c=0930 Dec 2002 21:18:05 -0000=091.13
+++ growfs.c=0916 Apr 2003 17:51:02 -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=09=09inobuf[MAXBSIZE];=09/* inode block */
 static int=09=09maxino;=09=09=09/* last valid inode */

+static int  unlabeled;
+
 /*
  * 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=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 get_dev_size(int, int *);

 /* ************************************************************ growfs ***=
** */
 /*
@@ -1884,6 +1888,21 @@
 =09return columns;
 }

+static void
+get_dev_size(int fd, int *size)
+{
+=09int sectorsize;
+=09off_t mediasize;
+
+=09ioctl(fd, DIOCGSECTORSIZE, &sectorsize);
+=09ioctl(fd, DIOCGMEDIASIZE, &mediasize);
+
+=09if (sectorsize <=3D 0)
+=09=09errx(1, "bogus sectorsize: %d", sectorsize);
+
+=09*size =3D mediasize / sectorsize;
+}
+
 /* ************************************************************** main ***=
** */
 /*
  * growfs(8)  is a utility which allows to increase the size of  an  exist=
ing
@@ -1921,6 +1940,7 @@
 =09struct disklabel=09*lp;
 =09struct partition=09*pp;
 =09int=09i,fsi,fso;
+=09u_int32_t p_size;
 =09char=09reply[5];
 #ifdef FSMAXSNAP
 =09int=09j;
@@ -2020,25 +2040,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'];
+=09if (lp !=3D NULL) {
+=09=09if (isdigit(*cp)) {
+=09=09=09pp =3D &lp->d_partitions[2];
+=09=09} else if (*cp>=3D'a' && *cp<=3D'h') {
+=09=09=09pp =3D &lp->d_partitions[*cp - 'a'];
+=09=09} else {
+=09=09=09errx(1, "unknown device");
+=09=09}
+=09=09p_size =3D pp->p_size;
 =09} else {
-=09=09errx(1, "unknown device");
+=09=09get_dev_size(fsi, &p_size);
 =09}

 =09/*
 =09 * Check if that partition looks suited 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.
@@ -2067,11 +2092,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}
@@ -2121,7 +2146,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/*
@@ -2182,12 +2207,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");
+=09if (!unlabeled) {
+=09=09pp->p_fsize =3D sblock.fs_fsize;
+=09=09pp->p_frag =3D sblock.fs_frag;
+=09=09pp->p_cpg =3D sblock.fs_fpg;
+
+=09=09return_disklabel(fso, lp, Nflag);
+=09=09DBG_PRINT0("label rewritten\n");
+=09}

 =09close(fsi);
 =09if(fso>-1) close(fso);
@@ -2254,12 +2281,13 @@
 =09if (!lab) {
 =09=09errx(1, "malloc failed");
 =09}
-=09if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
-=09=09errx(1, "DIOCGDINFO failed");
+=09if (!ioctl(fd, DIOCGDINFO, (char *)lab)) {
+=09=09return (lab);
 =09}
+=09unlabeled++;

 =09DBG_LEAVE;
-=09return (lab);
+=09return (NULL);
 }
---8<---

best regards,
le

--=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/



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