[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [linux-lvm] Failed xfs_growfs after lvextend



On Sat, Nov 05, 2005 at 01:31:10PM -0500, Randall A. Jones wrote:
> I extended an LV to 12.28TB and ran xfs_growfs on the mount point, lv0.
> This appeared to work fine except that after this, the filesystem didn't 
> appear any larger.

I looked into this problem awhile back now.  I believe what you're
seeing here is an inconsistency in the kernels block layer - at least,
when I last looked at this, this was the problem - the size increase
was indeed done inside the driver, and /sys/block/xxx/size confirmed
that, but the interfaces which use /dev/xxx to get the device size do
not see the increase (i.e. lseek(SEEK_END) or a BLKGETSIZE64 ioctl).

I wrote the attached program to show the issue, and sent mail to LKML
to let folks know of the issue, I guess noone has got around to trying
to address the problem yet though.  The core of the problem was that
the /dev/xxx inode size (i_size) had not been updated to reflect the
change in device size, IIRC.

Hmm, actually, I just went and read through fs/block_dev.c again, and
perhaps this is a device mapper bug after all - there is an interface
for increasing the inode size (bd_set_size) but it doesn't seem to
be called from anywhere in drivers/md/dm*...?  Theres one call to the
i_size_write interface on the bdev inode, but I can't tell whether it
will be called on the resize - perhaps a device mapper guru can tell
us?  It looks like MD might do the resize correctly though, its got a
call in what looks like a device-size-increasing code path.

Give this program a try though, just to see if you are seeing the same
problem that I was.

cheers.

-- 
Nathan
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mount.h>

#ifndef BLKGETSIZE64
# define BLKGETSIZE64   _IOR(0x12,114,size_t)
#endif

int main(int argc, char **argv)
{
	__uint64_t	size;
	long long	sz = -1;
	int		error, fd;

	if (argc != 2) {
		fputs("insufficient arguments\n", stderr);
		return 1;
	}
	fd = open(argv[1], O_RDONLY);
	if (!fd) {
		perror(argv[1]);
		return 1;
	}

	error = ioctl(fd, BLKGETSIZE64, &size);
	if (error >= 0) {
		/* BLKGETSIZE64 returns size in bytes not 512-byte blocks */
		sz = (long long)(size >> 9);
		printf("%lld 512 byte blocks (BLKGETSIZE64)\n", sz);
	} else {
		/* If BLKGETSIZE64 fails, try BLKGETSIZE */
		unsigned long tmpsize;

		error = ioctl(fd, BLKGETSIZE, &tmpsize);
		if (error < 0) {
			fprintf(stderr, "can't determine device size");
			return 1;
		}
		sz = (long long)tmpsize;
		printf("%lld 512 byte blocks (BLKGETSIZE)\n", sz);
	}
	return 0;
}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]