WSL2-Linux-Kernel/fs/xfs
Dave Chinner 160ae76fa1 libxfs: directory node splitting does not have an extra block
xfsprogs source commit 4280e59dcbc4cd8e01585efe788a68eb378048e8

xfs_da3_split() has to handle all three versions of the
directory/attribute btree structure. The attr tree is v1, the dir
tre is v2 or v3. The main difference between the v1 and v2/3 trees
is the way tree nodes are split - in the v1 tree we can require a
double split to occur because the object to be inserted may be
larger than the space made by splitting a leaf. In this case we need
to do a double split - one to split the full leaf, then another to
allocate an empty leaf block in the correct location for the new
entry.  This does not happen with dir (v2/v3) formats as the objects
being inserted are always guaranteed to fit into the new space in
the split blocks.

Indeed, for directories they *may* be an extra block on this buffer
pointer. However, it's guaranteed not to be a leaf block (i.e. a
directory data block) - the directory code only ever places hash
index or free space blocks in this pointer (as a cursor of
sorts), and so to use it as a directory data block will immediately
corrupt the directory.

The problem is that the code assumes that there may be extra blocks
that we need to link into the tree once we've split the root, but
this is not true for either dir or attr trees, because the extra
attr block is always consumed by the last node split before we split
the root. Hence the linking in an extra block is always wrong at the
root split level, and this manifests itself in repair as a directory
corruption in a repaired directory, leaving the directory rebuild
incomplete.

This is a dir v2 zero-day bug - it was in the initial dir v2 commit
that was made back in February 1998.

Fix this by ensuring the linking of the blocks after the root split
never tries to make use of the extra blocks that may be held in the
cursor. They are held there for other purposes and should never be
touched by the root splitting code.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2016-07-22 09:51:05 +10:00
..
libxfs libxfs: directory node splitting does not have an extra block 2016-07-22 09:51:05 +10:00
Kconfig
Makefile nfsd: add SCSI layout support 2016-03-18 11:42:53 -04:00
kmem.c xfs: improve kmem_realloc 2016-04-06 09:47:01 +10:00
kmem.h xfs: improve kmem_realloc 2016-04-06 09:47:01 +10:00
mrlock.h
uuid.c
uuid.h
xfs.h
xfs_acl.c posix_acl: Inode acl caching fixes 2016-03-31 00:30:15 -04:00
xfs_acl.h xfs: Change how listxattr generates synthetic attributes 2015-12-06 21:34:16 -05:00
xfs_aops.c xfs: skip dirty pages in ->releasepage() 2016-07-22 09:50:38 +10:00
xfs_aops.h xfs: direct calls in the direct I/O path 2016-07-20 11:38:01 +10:00
xfs_attr.h xfs: remove put_value from attr ->put_listent context 2016-04-06 07:57:45 +10:00
xfs_attr_inactive.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_attr_list.c xfs: collapse cases in xfs_attr3_leaf_list_int 2016-04-06 07:57:47 +10:00
xfs_bmap_util.c DAX error handling for 4.7 2016-05-26 19:34:26 -07:00
xfs_bmap_util.h
xfs_buf.c xfs: buffer ->bi_end_io function requires irq-safe lock 2016-05-18 10:56:41 +10:00
xfs_buf.h xfs: add configuration of error failure speed 2016-05-18 11:08:15 +10:00
xfs_buf_item.c xfs: add "fail at unmount" error handling configuration 2016-05-18 11:11:27 +10:00
xfs_buf_item.h
xfs_dir2_readdir.c xfs: concurrent readdir hangs on data buffer locks 2016-05-18 13:20:21 -04:00
xfs_discard.c xfs: fix format specifier , should be %llx and not %llu 2016-03-02 09:57:04 +11:00
xfs_discard.h
xfs_dquot.c Merge branch 'xfs-4.7-misc-fixes' into for-next 2016-05-20 10:33:17 +10:00
xfs_dquot.h
xfs_dquot_item.c
xfs_dquot_item.h
xfs_error.c xfs: print name of verifier if it fails 2016-01-04 16:10:19 +11:00
xfs_error.h
xfs_export.c Various bugfixes, a RDMA update from Chuck Lever, and support for a new 2016-03-24 19:50:32 -07:00
xfs_export.h
xfs_extent_busy.c
xfs_extent_busy.h
xfs_extfree_item.c
xfs_extfree_item.h
xfs_file.c xfs: remove dax code from object file when disabled 2016-07-22 09:50:55 +10:00
xfs_filestream.c xfs: mode di_mode to vfs inode 2016-02-09 16:54:58 +11:00
xfs_filestream.h
xfs_fsops.c Merge branch 'xfs-4.7-trans-type-cleanup' into for-next 2016-05-20 10:31:52 +10:00
xfs_fsops.h xfs: remove unused function definitions 2016-02-08 14:58:07 +11:00
xfs_globals.c
xfs_icache.c xfs: move reclaim tagging functions 2016-05-18 14:20:08 +10:00
xfs_icache.h
xfs_icreate_item.c
xfs_icreate_item.h
xfs_inode.c Merge branch 'xfs-4.7-inode-reclaim' into for-next 2016-05-20 10:34:00 +10:00
xfs_inode.h xfs: kill ioflags 2016-07-20 11:31:42 +10:00
xfs_inode_item.c Merge branch 'xfs-4.7-misc-fixes' into for-next 2016-05-20 10:33:17 +10:00
xfs_inode_item.h xfs: remove timestamps from incore inode 2016-02-09 16:54:58 +11:00
xfs_ioctl.c xfs: don't pass ioflags around in the ioctl path 2016-07-20 11:29:35 +10:00
xfs_ioctl.h xfs: don't pass ioflags around in the ioctl path 2016-07-20 11:29:35 +10:00
xfs_ioctl32.c xfs: don't pass ioflags around in the ioctl path 2016-07-20 11:29:35 +10:00
xfs_ioctl32.h
xfs_iomap.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_iomap.h
xfs_iops.c Merge branch 'xfs-4.7-optimise-inline-symlinks' into for-next 2016-05-20 10:32:10 +10:00
xfs_iops.h
xfs_itable.c xfs: mode di_mode to vfs inode 2016-02-09 16:54:58 +11:00
xfs_itable.h
xfs_linux.h mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
xfs_log.c Merge branch 'xfs-4.7-misc-fixes' into for-next 2016-05-20 10:33:17 +10:00
xfs_log.h xfs: remove transaction types 2016-04-06 09:20:36 +10:00
xfs_log_cil.c xfs: remove transaction types 2016-04-06 09:20:36 +10:00
xfs_log_priv.h xfs: remove transaction types 2016-04-06 09:20:36 +10:00
xfs_log_recover.c Merge branch 'xfs-4.7-misc-fixes' into for-next 2016-05-20 10:33:17 +10:00
xfs_message.c
xfs_message.h
xfs_mount.c xfs: update for 4.7-rc1 2016-05-26 10:13:40 -07:00
xfs_mount.h xfs: update for 4.7-rc1 2016-05-26 10:13:40 -07:00
xfs_mru_cache.c
xfs_mru_cache.h
xfs_ondisk.h xfs: check sizes of XFS on-disk structures at compile time 2016-03-09 08:15:14 +11:00
xfs_pnfs.c xfs: update for 4.7-rc1 2016-05-26 10:13:40 -07:00
xfs_pnfs.h nfsd: add SCSI layout support 2016-03-18 11:42:53 -04:00
xfs_qm.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_qm.h xfs: Split default quota limits by quota type 2016-02-08 11:27:55 +11:00
xfs_qm_bhv.c
xfs_qm_syscalls.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_quota.h
xfs_quotaops.c xfs: wire up Q_XGETNEXTQUOTA / get_nextdqblk 2016-02-08 11:27:38 +11:00
xfs_rtalloc.c xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_rtalloc.h
xfs_stats.c
xfs_stats.h
xfs_super.c DAX error handling for 4.7 2016-05-26 19:34:26 -07:00
xfs_super.h xfs: fix up inode32/64 (re)mount handling 2016-03-02 09:58:09 +11:00
xfs_symlink.c Merge branch 'xfs-4.7-optimise-inline-symlinks' into for-next 2016-05-20 10:32:10 +10:00
xfs_symlink.h
xfs_sysctl.c
xfs_sysctl.h
xfs_sysfs.c xfs: add "fail at unmount" error handling configuration 2016-05-18 11:11:27 +10:00
xfs_sysfs.h xfs: configurable error behavior via sysfs 2016-05-18 10:58:51 +10:00
xfs_trace.c
xfs_trace.h xfs: split direct I/O and DAX path 2016-07-20 11:38:55 +10:00
xfs_trans.c xfs: remove transaction types 2016-04-06 09:20:36 +10:00
xfs_trans.h xfs: better xfs_trans_alloc interface 2016-04-06 09:19:55 +10:00
xfs_trans_ail.c xfs: Make xfsaild freezeable again 2016-02-08 14:59:07 +11:00
xfs_trans_buf.c xfs: remove XBF_STALE flag wrapper macros 2016-02-10 15:01:11 +11:00
xfs_trans_dquot.c xfs: Split default quota limits by quota type 2016-02-08 11:27:55 +11:00
xfs_trans_extfree.c
xfs_trans_inode.c xfs: move di_changecount to VFS inode 2016-02-09 16:54:58 +11:00
xfs_trans_priv.h
xfs_xattr.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-05-27 17:14:05 -07:00