Re: XFS issue under 2.6.25.13 kernel

Sławomir Nowakowski
2008-08-27T18:08:01Z

[-- Attachment #1: Type: text/plain, Size: 4951 bytes --]

Dear Dave,

We really apreciate your help..

In the realtion to previous correspondations about differences between
implementation of kernels 2.6.17.13 and 2.6.25.13 we'd like to ask
some questions.

We was based on git repository:

git://git.kernel.org

We have reverted some changes for XFS in 2.6.25.13 kernel. We have
usedf 3 commits:

- 94E1E99F11... (SGI-PV: 964468)
- 4BE536DEBE... (SGI-PV: 955674)
- 4CA488EB4... (SGI-PV: 971186)

With these changes we have created patch for 2.6.25.13 kernel. This
patch should eliminate additional reservation of disk space in XFS
file system. Our intention was to get similarity space of disk between
2.6.17.13 and 2.6.25.13 kernels.

Does patch that is attached to this mail do everything properly? Is it
100% compatibe with XFS API?

If you wnat anything more from us juts ask. WQe deliver it.

Thank you vey much for your attitude.

Roland

2008/8/27, Dave Chinner <david@fromorbit.com>:
> On Tue, Aug 26, 2008 at 02:53:23PM +0200, Sławomir Nowakowski wrote:
> > 2008/8/26 Dave Chinner <david@fromorbit.com>:
> > run under 2.6.17.17 and 2.6.25.13 kernels?
> >
> > Here is a situation on 2.6.17.13 kernel:
> >
> > xfs_io -x -c 'statfs' /mnt/point
> >
> > fd.path = "/mnt/sda"
> > statfs.f_bsize = 4096
> > statfs.f_blocks = 487416
> > statfs.f_bavail = 6
> > statfs.f_files = 160
> > statfs.f_ffree = 154
> > geom.bsize = 4096
> > geom.agcount = 8
> > geom.agblocks = 61247
> > geom.datablocks = 489976
> > geom.rtblocks = 0
> > geom.rtextents = 0
> > geom.rtextsize = 1
> > geom.sunit = 0
> > geom.swidth = 0
> > counts.freedata = 6
> > counts.freertx = 0
> > counts.freeino = 58
> > counts.allocino = 64
>
> The counts.* numbers are the real numbers, not th statfs numbers
> which are somewhat made up - the inode count for example is
> influenced by the amount of free space....
>
> > xfs_io -x -c 'resblks' /mnt/point
> >
> > reserved blocks = 0
> > available reserved blocks = 0
> ....
>
> >
> > But under 2.6.25.13 kernel the situation looks different:
> >
> > xfs_io -x -c 'statfs' /mnt/point:
> >
> > fd.path = "/mnt/-sda4"
> > statfs.f_bsize = 4096
> > statfs.f_blocks = 487416
> > statfs.f_bavail = 30
> > statfs.f_files = 544
> > statfs.f_ffree = 538
>
> More free space, therefore more inodes....
>
> > geom.bsize = 4096
> > geom.agcount = 8
> > geom.agblocks = 61247
> > geom.datablocks = 489976
> > geom.rtblocks = 0
> > geom.rtextents = 0
> > geom.rtextsize = 1
> > geom.sunit = 0
> > geom.swidth = 0
> > counts.freedata = 30
> > counts.freertx = 0
> > counts.freeino = 58
> > counts.allocino = 64
>
> but the counts.* values show that the inode counts are the same.
> However, the free space is different, partially due to a different
> set of ENOSPC deadlock fixes that were done that required different
> calculations of space usage....
>
> > xfs_io -x -c 'resblks' /mnt/point:
> >
> > reserved blocks = 18446744073709551586
> > available reserved blocks = 18446744073709551586
>
> Well, that is wrong - that's a large negative number.
>
> FWIW, I can't reproduce this on a pure 2.6.24 on ia32 or 2.6.27-rc4 kernel
> on x86_64-UML:
>
> # mount /mnt/xfs2
> # df -k /mnt/xfs2
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/ubd/2 2086912 1176 2085736 1% /mnt/xfs2
> # xfs_io -x -c 'resblks 0' /mnt/xfs2
> reserved blocks = 0
> available reserved blocks = 0
> # df -k /mnt/xfs2
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/ubd/2 2086912 160 2086752 1% /mnt/xfs2
> # xfs_io -f -c 'truncate 2g' -c 'resvsp 0 2086720k' /mnt/xfs2/fred
> # df -k /mnt/xfs2
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/ubd/2 2086912 2086880 32 100% /mnt/xfs2
> # xfs_io -x -c statfs /mnt/xfs2
> fd.path = "/mnt/xfs2"
> statfs.f_bsize = 4096
> statfs.f_blocks = 521728
> statfs.f_bavail = 8
> statfs.f_files = 192
> statfs.f_ffree = 188
> ....
> counts.freedata = 8
> counts.freertx = 0
> counts.freeino = 60
> counts.allocino = 64
> death:/mnt# umount /mnt/xfs2
> death:/mnt# mount /mnt/xfs2
> # xfs_io -x -c statfs /mnt/xfs2
> fd.path = "/mnt/xfs2"
> statfs.f_bsize = 4096
> statfs.f_blocks = 521728
> statfs.f_bavail = 0
> statfs.f_files = 64
> statfs.f_ffree = 60
> ....
> counts.freedata = 0
> counts.freertx = 0
> counts.freeino = 60
> counts.allocino = 64
> # df -k /mnt/xfs2
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/ubd/2 2086912 2086912 0 100% /mnt/xfs2
> # xfs_io -x -c resblks /mnt/xfs2
> reserved blocks = 8
> available reserved blocks = 8
>
> Can you produce a metadump of the filesystem image that your have produced
> on 2.6.17 that results in bad behaviour on later kernels so I can see if
> I can reproduce the same results here? If you've only got a handful of files
> the image will be small enough to mail to me....
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com
>

[-- Attachment #2: d10.diff.txt --]
[-- Type: text/plain, Size: 5180 bytes --]

diff -rNup xfs/linux-2.6/xfs_super.c xfs/linux-2.6/xfs_super.c
--- xfs/linux-2.6/xfs_super.c 2008-08-25 14:25:11.000000000 +0200
+++ xfs/linux-2.6/xfs_super.c 2008-08-27 11:55:33.000000000 +0200
@@ -61,6 +61,9 @@
#include <linux/kthread.h>
#include <linux/freezer.h>

+
+#define NO_2618_XFS
+
static struct quotactl_ops xfs_quotactl_operations;
static struct super_operations xfs_super_operations;
static kmem_zone_t *xfs_vnode_zone;
@@ -1187,8 +1190,13 @@ xfs_fs_statfs(
statp->f_bsize = sbp->sb_blocksize;
lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
statp->f_blocks = sbp->sb_dblocks - lsize;
+#ifndef NO_2618_XFS
statp->f_bfree = statp->f_bavail =
sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+#else
+ statp->f_bfree = statp->f_bavail = sbp->sb_fdblocks;
+#endif
+
fakeinos = statp->f_bfree << sbp->sb_inopblog;
#if XFS_BIG_INUMS
fakeinos += mp->m_inoadd;
diff -rNup xfs/xfs_fsops.c xfs/xfs_fsops.c
--- xfs/xfs_fsops.c 2008-08-25 14:25:13.000000000 +0200
+++ xfs/xfs_fsops.c 2008-08-27 11:56:30.000000000 +0200
@@ -46,6 +46,8 @@
#include "xfs_rw.h"
#include "xfs_filestream.h"

+#define NO_2618_XFS
+
/*
* File system operations
*/
@@ -464,7 +466,11 @@ xfs_fs_counts(
{
xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT);
spin_lock(&mp->m_sb_lock);
+#ifdef NO_2618_XFS
+ cnt->freedata = mp->m_sb.sb_fdblocks;
+#else
cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+#endif
cnt->freertx = mp->m_sb.sb_frextents;
cnt->freeino = mp->m_sb.sb_ifree;
cnt->allocino = mp->m_sb.sb_icount;
@@ -539,24 +545,42 @@ retry:
}
mp->m_resblks = request;
} else {
+#ifndef NO_2618_XFS
__int64_t free;

free = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
if (!free)
goto out; /* ENOSPC and fdblks_delta = 0 */
-
+
+#endif
delta = request - mp->m_resblks;
+
+#ifndef NO_2618_XFS
lcounter = free - delta;
+#else
+ lcounter = mp->m_sb.sb_fdblocks - delta;
+#endif
if (lcounter < 0) {
/* We can't satisfy the request, just get what we can */
+#ifndef NO_2618_XFS
mp->m_resblks += free;
mp->m_resblks_avail += free;
fdblks_delta = -free;
mp->m_sb.sb_fdblocks = XFS_ALLOC_SET_ASIDE(mp);
+#else
+ mp->m_resblks += mp->m_sb.sb_fdblocks;
+ mp->m_resblks_avail += mp->m_sb.sb_fdblocks;
+ fdblks_delta = -mp->m_sb.sb_fdblocks;
+ mp->m_sb.sb_fdblocks = 0;
+#endif
} else {
fdblks_delta = -delta;
+#ifndef NO_2618_XFS
mp->m_sb.sb_fdblocks =
lcounter + XFS_ALLOC_SET_ASIDE(mp);
+#else
+ mp->m_sb.sb_fdblocks = lcounter;
+#endif
mp->m_resblks = request;
mp->m_resblks_avail += delta;
}
diff -rNup xfs/xfs_mount.c xfs/xfs_mount.c
--- xfs/xfs_mount.c 2008-08-25 14:25:14.000000000 +0200
+++ xfs/xfs_mount.c 2008-08-27 14:42:02.000000000 +0200
@@ -44,6 +44,9 @@
#include "xfs_quota.h"
#include "xfs_fsops.h"

+
+#define NO_2618_XFS
+
STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t);
STATIC int xfs_uuid_mount(xfs_mount_t *);
STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
@@ -1525,6 +1528,11 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fi
*
* The m_sb_lock must be held when this routine is called.
*/
+
+#ifdef NO_2618_XFS
+ #define SET_ASIDE_BLOCKS 8
+#endif
+
int
xfs_mod_incore_sb_unlocked(
xfs_mount_t *mp,
@@ -1562,8 +1570,12 @@ xfs_mod_incore_sb_unlocked(
mp->m_sb.sb_ifree = lcounter;
return 0;
case XFS_SBS_FDBLOCKS:
+#ifndef NO_2618_XFS
lcounter = (long long)
mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+#else
+ lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
+#endif
res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);

if (delta > 0) { /* Putting blocks back */
@@ -1596,8 +1608,11 @@ xfs_mod_incore_sb_unlocked(
}
}
}
-
+#ifndef NO_2618_XFS
mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
+#else
+ mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
+#endif
return 0;
case XFS_SBS_FREXTENTS:
lcounter = (long long)mp->m_sb.sb_frextents;
@@ -2321,8 +2336,14 @@ xfs_icsb_sync_counters(
*/

#define XFS_ICSB_INO_CNTR_REENABLE (uint64_t)64
+
+#ifndef NO_2618_XFS
#define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \
(uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp))
+#else
+#define XFS_ICSB_FDBLK_CNTR_REENABLE 512
+#endif
+
STATIC void
xfs_icsb_balance_counter(
xfs_mount_t *mp,
@@ -2357,7 +2378,11 @@ xfs_icsb_balance_counter(
case XFS_SBS_FDBLOCKS:
count = mp->m_sb.sb_fdblocks;
resid = do_div(count, weight);
+#ifndef NO_2618_XFS
if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp)))
+#else
+ if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE))
+#endif
goto out;
break;
default:
@@ -2418,12 +2443,19 @@ again:

case XFS_SBS_FDBLOCKS:
BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0);
-
+#ifndef NO_2618_XFS
lcounter = icsbp->icsb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
+#else
+ lcounter = icsbp->icsb_fdblocks;
+#endif
lcounter += delta;
if (unlikely(lcounter < 0))
goto balance_counter;
+#ifndef NO_2618_XFS
icsbp->icsb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
+#else
+ icsbp->icsb_fdblocks = lcounter;
+#endif
break;
default:
BUG();