ext4: fix same-dir rename when inline data directory overflows
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 27 Aug 2014 22:40:09 +0000 (18:40 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 29 Aug 2014 02:22:29 +0000 (22:22 -0400)
commitd80d448c6c5bdd32605b78a60fe8081d82d4da0f
tree81126dbb0bead4385659eae05916ad922293b80c
parentdb9ee220361de03ee86388f9ea5e529eaad5323c
ext4: fix same-dir rename when inline data directory overflows

When performing a same-directory rename, it's possible that adding or
setting the new directory entry will cause the directory to overflow
the inline data area, which causes the directory to be converted to an
extent-based directory.  Under this circumstance it is necessary to
re-read the directory when deleting the old dirent because the "old
directory" context still points to i_block in the inode table, which
is now an extent tree root!  The delete fails with an FS error, and
the subsequent fsck complains about incorrect link counts and
hardlinked directories.

Test case (originally found with flat_dir_test in the metadata_csum
test program):

# mkfs.ext4 -O inline_data /dev/sda
# mount /dev/sda /mnt
# mkdir /mnt/x
# touch /mnt/x/changelog.gz /mnt/x/copyright /mnt/x/README.Debian
# sync
# for i in /mnt/x/*; do mv $i $i.longer; done
# ls -la /mnt/x/
total 0
-rw-r--r-- 1 root root 0 Aug 25 12:03 changelog.gz.longer
-rw-r--r-- 1 root root 0 Aug 25 12:03 copyright
-rw-r--r-- 1 root root 0 Aug 25 12:03 copyright.longer
-rw-r--r-- 1 root root 0 Aug 25 12:03 README.Debian.longer

(Hey!  Why are there four files now??)

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org
fs/ext4/namei.c