linux-bl808/fs
Filipe Manana 3821f34888 Btrfs: update commit root on snapshot creation after orphan cleanup
On snapshot creation (either writable or read-only), we do orphan cleanup
against the root of the snapshot. If the cleanup did remove any orphans,
then the current root node will be different from the commit root node
until the next transaction commit happens.

A send operation always uses the commit root of a snapshot - this means
it will see the orphans if it starts computing the send stream before the
next transaction commit happens (triggered by a timer or sync() for .e.g),
which is when the commit root gets assigned a reference to current root,
where the orphans are not visible anymore. The consequence of send seeing
the orphans is explained below.

For example:

    mkfs.btrfs -f /dev/sdd
    mount -o commit=999 /dev/sdd /mnt

    # open a file with O_TMPFILE and leave it open
    # write some data to the file
    btrfs subvolume snapshot -r /mnt /mnt/snap1

    btrfs send /mnt/snap1 -f /tmp/send.data

The send operation will fail with the following error:

    ERROR: send ioctl failed with -116: Stale file handle

What happens here is that our snapshot has an orphan inode still visible
through the commit root, that corresponds to the tmpfile. However send
will attempt to call inode.c:btrfs_iget(), with the goal of reading the
file's data, which will return -ESTALE because it will use the current
root (and not the commit root) of the snapshot.

Of course, there are other cases where we can get orphans, but this
example using a tmpfile makes it much easier to reproduce the issue.

Therefore on snapshot creation, after calling btrfs_orphan_cleanup, if
the commit root is different from the current root, just commit the
transaction associated with the snapshot's root (if it exists), so that
a send will not see any orphans that don't exist anymore. This also
guarantees a send will always see the same content regardless of whether
a transaction commit happened already before the send was requested and
after the orphan cleanup (meaning the commit root and current roots are
the same) or it hasn't happened yet (commit and current roots are
different).

Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: Chris Mason <clm@fb.com>
2014-06-09 17:21:05 -07:00
..
9p
adfs
affs fs/affs/super.c: bugfix / double free 2014-05-06 13:05:00 -07:00
afs AFS: Pass an afs_call* to call->async_workfn() instead of a work_struct* 2014-05-23 13:05:22 +01:00
autofs4 autofs: fix lockref lookup 2014-05-06 13:04:59 -07:00
befs
bfs
btrfs Btrfs: update commit root on snapshot creation after orphan cleanup 2014-06-09 17:21:05 -07:00
cachefiles
ceph Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client 2014-05-05 15:17:02 -07:00
cifs cifs: fix actimeo=0 corner case when cifs_i->time == jiffies 2014-04-24 22:37:03 -05:00
coda
configfs
cramfs
debugfs
devpts
dlm
ecryptfs
efivarfs
efs
exofs
exportfs
ext2
ext3
ext4 These are regression and bug fixes for ext4. 2014-04-20 20:43:47 -07:00
f2fs
fat
freevxfs
fscache
fuse fuse: add renameat2 support 2014-04-28 16:43:44 +02:00
gfs2
hfs
hfsplus
hostfs
hpfs
hppfs
hugetlbfs hugetlb: ensure hugepage access is denied if hugepages are not supported 2014-05-06 13:04:58 -07:00
isofs
jbd
jbd2
jffs2
jfs
kernfs kernfs: move the last knowledge of sysfs out from kernfs 2014-06-03 08:11:18 -07:00
lockd
logfs
minix
ncpfs Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-04-12 17:31:22 -07:00
nfs
nfs_common
nfsd nfsd4: warn on finding lockowner without stateid's 2014-05-21 11:11:21 -04:00
nilfs2
nls
notify fanotify: fix -EOVERFLOW with large files on 64-bit 2014-05-06 13:04:59 -07:00
ntfs
ocfs2 ocfs2: fix double kmem_cache_destroy in dlm_init 2014-05-23 09:37:30 -07:00
omfs
openpromfs
proc mm: add !pte_present() check on existing hugetlb_entry callbacks 2014-06-06 13:21:16 -07:00
pstore
qnx4
qnx6
quota
ramfs
reiserfs
romfs
squashfs
sysfs kernfs: move the last knowledge of sysfs out from kernfs 2014-06-03 08:11:18 -07:00
sysv
ubifs UBIFS: fix remount error path 2014-05-05 09:31:33 +03:00
udf
ufs
xfs xfs: list_lru_init returns a negative error 2014-05-15 09:23:24 +10:00
aio.c aio: fix potential leak in aio_run_iocb(). 2014-05-01 08:37:43 -04:00
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio-integrity.c
bio.c
block_dev.c
buffer.c
char_dev.c
compat.c locks: rename file-private locks to "open file description locks" 2014-04-22 08:23:58 -04:00
compat_binfmt_elf.c
compat_ioctl.c
coredump.c coredump: fix va_list corruption 2014-04-19 13:23:31 -07:00
dcache.c dcache: add missing lockdep annotation 2014-05-31 09:13:21 -07:00
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c
exec.c metag: Reduce maximum stack size to 256MB 2014-05-15 00:00:35 +01:00
fcntl.c locks: rename file-private locks to "open file description locks" 2014-04-22 08:23:58 -04:00
fhandle.c
file.c
file_table.c
filesystems.c
fs-writeback.c
fs_struct.c
inode.c
internal.h
ioctl.c
ioprio.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c locks: only validate the lock vs. f_mode in F_SETLK codepaths 2014-05-09 11:41:54 -04:00
Makefile
mbcache.c
mount.h
mpage.c
namei.c fix races between __d_instantiate() and checks of dentry flags 2014-04-19 12:30:58 -04:00
namespace.c
no-block.c
open.c These are regression and bug fixes for ext4. 2014-04-20 20:43:47 -07:00
pipe.c
pnode.c
pnode.h
posix_acl.c posix_acl: handle NULL ACL in posix_acl_equiv_mode 2014-05-06 13:58:42 -04:00
proc_namespace.c
read_write.c
readdir.c
select.c
seq_file.c
signalfd.c
splice.c vfs: fix vmplice_to_user() 2014-05-28 01:54:52 -04:00
stack.c
stat.c
statfs.c
super.c fs: Don't return 0 from get_anon_bdev 2014-04-16 11:53:08 -07:00
sync.c
timerfd.c
utimes.c
xattr.c