Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Oct 2010 22:18:39 +0200
From:      Tobias Fredriksson <tobfr108@gmail.com>
To:        freebsd-fs@freebsd.org
Subject:   Growing large UFS over 16TB?
Message-ID:  <6AE65535-DCCE-46A5-BBB9-358FEB34C18C@gmail.com>

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

So I have this UFS, unfortunately it was just done newfs /dev/da1 with =
no regards to installing GPT or anything like that.

It started out as a 6x2TB system raid, then we expanded with 2x2TB.

Growing this filesystem was not possible with the current tool however =
with the patch from http://masq.tychl.net/growfs.patch it worked fine.

Now that I'm trying to grow it from 12TB to closer to 20TB it fails =
after about 15 minutes.
It displays all the super-block backups all the way to "39061769312" =
then it sits there reading from the volume for about 5-10 minutes.

The following error message is then output
growfs: rdfs: attempting to read negative block number: Inappropriate =
ioctl for device

I understand the reason for this, its trying to read a block and the =
integer just wrapped around. Nice.
The relevant lines from growfs.c are

static void
rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi)
{
	[...]
	if (bno < 0) {
		err(32, "rdfs: attempting to read negative block =
number");
	}
	[...]

Just for fun I commented the if part out and recompiled.
growfs: rdfs: read error: -4889807711788704476: Input/output error

The only place that ufs2_daddr_t is defined is in =
/usr/include/ufs/ufs/dinode.h
typedef int64_t       ufs2_daddr_t;

So again for fun I changed this to u_int64_t. I also removed the =
comments on that if part in growfs.c

This caused the same message as last to be repeated. But not the =
negative number.
growfs: rdfs: read error: -4889807711788704476: Input/output error

This leads me to believe that I'm at least doing something partially =
right.

The next part that growfs.c is doing in rdfs is
        n =3D read(fsi, bf, size);
        if (n !=3D (ssize_t)size) {
                err(34, "rdfs: read error: %jd", (intmax_t)bno);
        }

So I changed
"rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi)"
to
"rdfs(ufs2_daddr_t bno, size_t size, void *bf, u_int64_t fsi)"
However this changed nothing. Same output.
Since its failing out at the if sentance then of course the problem is =
in ssize_t not being big enough.
As such I of course changed the values for this in =
/usr/include/machine/_types.h and I also checked out _limit.h in the =
same dir.
_types.h
typedef __int64_t      __ssize_t;
to
typedef __uint64_t      __ssize_t;

_limit.h
#define __SSIZE_MAX     __LONG_MAX      /* max value for a ssize_t */
#define __SIZE_T_MAX    __ULONG_MAX     /* max value for a size_t */
to
#define __SSIZE_MAX    __ULLONG_MAX      /* max value for a ssize_t */
#define __SIZE_T_MAX    __ULLONG_MAX     /* max value for a size_t */

However this failed to make any sort of change. I returned all of the =
later values as nothing helped.

So I'm turning to the fs gurus. At the moment I have no way of moving =
the data off and creating this properly. As such changing to another fs =
is not an option right now neither.

So if anybody has any suggestions on what to do to temporarily fix the =
issue until we can move the data of the raid and rebuild it properly, =
please let me know.

[root@stor1 /usr/src/sbin/growfs]# ./growfs /dev/da1
We strongly recommend you to make a backup before growing the Filesystem

 Did you backup your data (Yes/No) ? Yes
new file systemsize is: 9765570560 frags
Warning: 136832 sector(s) cannot be allocated.
growfs: 19073314.0MB (39062145408 sectors) block size 16384, fragment =
size 2048
	using 103818 cylinder groups of 183.72MB, 11758 blks, 23552 =
inodes.
[...]
growfs: rdfs: read error: -4889807711788704476: Input/output error

Cheers=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6AE65535-DCCE-46A5-BBB9-358FEB34C18C>