On Tue, 24 Jul 2012, Dave Chinner wrote:
...
Now in phase7.c it asserts if nlinks is over 65536 which 13006001
clearly is:
do_warn(_("resetting inode %" PRIu64 " nlinks from %u to %u\n"),
ino, dinoc->di_nlink, nrefs);
if (dinoc->di_version == 1 && nrefs > XFS_MAXLINK_1) {
ASSERT(fs_inode_nlink);
do_warn(
_("nlinks %u will overflow v1 ino, ino %" PRIu64 " will be converted to version 2\n"),
nrefs, ino);
}
dinoc->di_nlink = nrefs;
And that is saying that your superblock does not have the NLINK
feature bit set, so it can't use version 2 inodes which support link
counts of up to 2^32. Use xfs_db to set the NLINK bit, and re-run
repair.
FWIW, the mkfs default is to set the NLINK. That got changed some
4-5 years ago, IIRC...
Thanks for this.
The original filesystem is about 8 years old so it would have been created
before that change even if we had the latest versions of the xfsprogs at
the time.
While waiting for the data to copy (before I try anything else) I did a
quick scan though the xfsprogs 3.1.8 sources looking for things which
alter the sb version/versionnum to set the XFS_SB_VERSION_NLINKBIT flag
(assuming that one it right since it is what causes xfs_db to add NLINK to
the version output).
I can find only one piece of code which does it:
include/xfs_sb.h :
static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
{
if (sbp->sb_versionnum <= XFS_SB_VERSION_2)
sbp->sb_versionnum = XFS_SB_VERSION_3;
else
sbp->sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
}
and that function is only used in one place - and can't be reached:
repair/versions.c :
if (fs_inode_nlink && !xfs_sb_version_hasnlink(sb)) {
ASSERT(fs_inode_nlink_allowed);
xfs_sb_version_addnlink(sb);
}
...
Am I missing the obvious way to set this bit?
BTW on a fresh fs made with and older mkfs.xfs (the one from RHEL5) the
NLINK bit isn't set initially but seems to become set once I cause an
inode to have more than 65536 links...
# xfs_db -c version /dev/SpudSnaps/Test2
versionnum [0xb584+0x8] = V4,ALIGN,DALIGN,DIRV2,LOGV2,EXTFLG,MOREBITS,ATTR2
# mount /dev/SpudSnaps/Test2 /mnt/testing/
# mkdir /mnt/testing/foo
# for i in $(seq 1 65537); do mkdir /mnt/testing/foo/$i; done
# umount /mnt/testing
# xfs_db -c version /dev/SpudSnaps/Test2
versionnum [0xb5b4+0x8] = V4,ATTR,NLINK,ALIGN,DALIGN,DIRV2,LOGV2,EXTFLG,MOREBITS,ATTR2
So is it actually some other feature which needs to be set to allow NLINK
to be set?
Looking at the 'bad' fs it has:
# xfs_db -c version /dev/FornixRaid02/damtp-home
versionnum [0x35d4+0x0] = V4,ATTR,QUOTA,ALIGN,DALIGN,DIRV2,LOGV2,EXTFLG
so it seems to just be missing MOREBITS and ATTR2 compared to the earlier
output from the test fs - but neither seems very likely.
I'm sure that I'm missing something very obvious.
-- Jon
_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs