1

I am a bit puzzled about the maximum metadata log size that can be setup in a XFS file system. I have found the same information everywhere: the maximum size is 64K blocks or 128M, whichever is smaller. With a standard 4K block size I have then max metadata logsize = min (256M, 128M) = 128M. Fair enough, but when I tried to create a file system with metadata log bigger than 128M, I got no errors, and this is confirmed by the output of the xfs_info command:

ingrid:/home/engineer # mkfs.xfs -f -l size=1024m /dev/md0
meta-data=/dev/md0               isize=256    agcount=16, agsize=2359280 blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=37748480, imaxpct=25
         =                       sunit=16     swidth=64 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=4096   blocks=262144, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

Is there any new feature in version 2 of the internal log that makes possible to override the 128M limit?

ingrid:/home/engineer # uname -a
Linux sles11-064-VM-esocl00-i1r0-mysql 2.6.32.19-0.3-default #1 SMP 2010-09-17 20:28:21 +0200 x86_64 x86_64 x86_64 GNU/Linux

# rpm -qa | grep -i xfs
xfsprogs-3.1.1-0.1.36
xfsdump-3.0.4-0.1.35

Many thanks for any advice you could give me.

1 Answer 1

3

Solved. I had to go through the source code of mkfs.xfs. First of all I installed:

xfsprogs-3.1.1-0.1.36.src.rpm

Let's go through /usr/src/packages:

# ls -ltr | grep xfsprogs-3.1.1
-rw-r--r-- 1 root root 1072077 2010-02-03 10:33 xfsprogs-3.1.1.tar.bz2

Decompressing and listing:

# cd xfsprogs-3.1.1
# ls
aclocal.m4    configure     db      estimate  growfs      io         libxcmd  logprint   Makefile   mkfs   README      rtcp
config.guess  configure.in  debian  fsck      include     libdisk    libxfs   ltmain.sh  man        po     release.sh  VERSION
config.sub    copy          doc     fsr       install-sh  libhandle  libxlog  m4         mdrestore  quota  repair

We are interested in the mkfs.xfs therefore:

# vi mkfs/xfs_mkfs.c

void validate_log_size(__uint64_t logblocks, int blocklog, int min_logblocks)
{
        if (logblocks < min_logblocks) {
                fprintf(stderr,
        _("log size %lld blocks too small, minimum size is %d blocks\n"),
                        (long long)logblocks, min_logblocks);
                usage();
        }
        if (logblocks > XFS_MAX_LOG_BLOCKS) {
                fprintf(stderr,
        _("log size %lld blocks too large, maximum size is %lld blocks\n"),
                        (long long)logblocks, XFS_MAX_LOG_BLOCKS);
                usage();
        }
        if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
                fprintf(stderr,
        _("log size %lld bytes too large, maximum size is %lld bytes\n"),
                        (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
                usage();
        }
}

The limits for the metadata log are set by the variables XFS_MAX_LOG_BLOCKS and XFS_MAX_LOG_BYTES. These variables are defined in the include/xfs_fs.h:

#define XFS_MIN_AG_BLOCKS       64
#define XFS_MIN_LOG_BLOCKS      512ULL
#define XFS_MAX_LOG_BLOCKS      (1024 * 1024ULL)
#define XFS_MIN_LOG_BYTES       (10 * 1024 * 1024ULL)

/* keep the maximum size under 2^31 by a small amount */
#define XFS_MAX_LOG_BYTES \
        ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES)

So, for this version of XFS we have:

XFS_MAX_LOG_BLOCKS = 1048576 <<<
XFS_MIN_LOG_BYTES = 10485760
XFS_MAX_LOG_BYTES = (2*1024*1024*1024)-(10485760) = 2136997888 = 2038M <<<<

Using a block size of 4 KB (standard):

1048576 * 4096 = 4294967296 = 4096M

I think that the maximum size of the log is the minimum between XFS_MAX_LOG_BYTES and XFS_MAX_LOG_BLOCKS * block_size. Infact:

 # mkfs.xfs -f -l size=2039m /dev/md0
log size 2138046464 bytes too large, maximum size is 2136997888 bytes
Usage: mkfs.xfs
/* blocksize */         [-b log=n|size=num]
/* data subvol */       [-d agcount=n,agsize=n,file,name=xxx,size=num,
                            (sunit=value,swidth=value|su=num,sw=num),
                            sectlog=n|sectsize=num
/* inode size */        [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2]
/* log subvol */        [-l agnum=n,internal,size=num,logdev=xxx,version=n
                            sunit=value|su=num,sectlog=n|sectsize=num,
                            lazy-count=0|1]
/* label */             [-L label (maximum 12 characters)]
/* naming */            [-n log=n|size=num,version=2|ci]
/* prototype file */    [-p fname]
/* quiet */             [-q]
/* realtime subvol */   [-r extsize=num,size=num,rtdev=xxx]
/* sectorsize */        [-s log=n|size=num]
/* version */           [-V]
                        devicename
<devicename> is required unless -d name=xxx is given.
<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),
      xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).
<value> is xxx (512 byte blocks).

Hope this helps!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .