xfs: replace parent pointer diroffset with full dirent name

As I've mentioned in past comments on the parent pointers patchset, the
proposed ondisk parent pointer format presents a major difficulty for
online directory repair.  This difficulty derives from encoding the
directory offset of the dirent that the parent pointer is mirroring.
Recall that parent pointers are stored in extended attributes:

    (parent_ino, parent_gen, diroffset) -> (dirent_name)

If the directory is rebuilt, the offsets of the new directory entries
must match the diroffset encoded in the parent pointer, or the
filesystem becomes inconsistent.  This is difficult to guarantee in the
process of performing a repair and in the long terms is totally
pointless because the the parent pointer code doesn't use the diroffset,
nor does the online fsck code.  IOWs, this design decision increases the
complexity of repair solely to work around the xattr code being unable
to store a full dirent name in the xattr name or match on xattr values.

However, xattrs can now perform lookups on both the name and value of an
xattr.  This means we can redefine the parent pointer format like this:

For dirent names shorter than 243 bytes:

    (parent_ino, parent_gen, dirent_name) -> NULL

For dirent names longer than 243 bytes:

    (parent_ino, parent_gen, dirent_name[0:242]) -> (dirent_name[243:255])

and this works because a parent pointer lookup uses NVLOOKUP, which will
read those last twelve bytes of the dirent name if need be.

Replace the diroffset with this new format, thereby eliminating the need
for directory repair to update all the parent pointers after rebuilding
the directory.  We haven't merged parent pointers, so changes to the
ondisk format are easy.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
14 files changed