From owner-freebsd-hackers@FreeBSD.ORG Wed Apr 16 11:04:26 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0E43F37B401 for ; Wed, 16 Apr 2003 11:04:26 -0700 (PDT) Received: from mailbox.univie.ac.at (mail.univie.ac.at [131.130.1.27]) by mx1.FreeBSD.org (Postfix) with ESMTP id 08A2343FA3 for ; Wed, 16 Apr 2003 11:04:25 -0700 (PDT) (envelope-from l.ertl@univie.ac.at) Received: from localhost.localdomain (adslle.cc.univie.ac.at [131.130.102.11]) by mailbox.univie.ac.at (8.12.2/8.12.2) with ESMTP id h3GI4Hos366236 for ; Wed, 16 Apr 2003 20:04:19 +0200 Date: Wed, 16 Apr 2003 20:04:17 +0200 (CEST) From: Lukas Ertl To: freebsd-hackers@freebsd.org Message-ID: <20030416195328.V719@leelou.in.tern> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=ISO-8859-1 Content-Transfer-Encoding: QUOTED-PRINTABLE X-DCC-ZID-Univie-Metrics: mx1 4261; Body=1 Fuz1=1 Fuz2=1 Subject: growing filesystems in 5-current X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Apr 2003 18:04:26 -0000 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 #include #include +#include #include #include @@ -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, §orsize); +=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/