linux_dsm_epyc7002/fs/btrfs
Robbie Ko 99ea42ddb1 Btrfs: incremental send, fix premature rmdir operations
Under certain situations, an incremental send operation can contain
a rmdir operation that will make the receiving end fail when attempting
to execute it, because the target directory is not yet empty.

Consider the following example:

  Parent snapshot:

  .                                                             (ino 256)
  |--- a/                                                       (ino 257)
  |    |--- c/                                                  (ino 260)
  |
  |--- del/                                                     (ino 259)
        |--- tmp/                                               (ino 258)
        |--- x/                                                 (ino 261)

  Send snapshot:

  .                                                             (ino 256)
  |--- a/                                                       (ino 257)
  |    |--- x/                                                  (ino 261)
  |
  |--- c/                                                       (ino 260)
       |--- tmp/                                                (ino 258)

1) When processing inode 258, we delay its rename operation because inode
   260 is its new parent in the send snapshot and it was not yet renamed
   (since 260 > 258, that is, beyond the current progress);

2) When processing inode 259, we realize we can not yet send an rmdir
   operation (against inode 259) because inode 258 was still not yet
   renamed/moved away from inode 259. Therefore we update data structures
   so that after inode 258 is renamed, we try again to see if we can
   finally send an rmdir operation for inode 259;

3) When we process inode 260, we send a rename operation for it followed
   by a rename operation for inode 258. Once we send the rename operation
   for inode 258 we then check if we can finally issue an rmdir for its
   previous parent, inode 259, by calling the can_rmdir() function with
   a value of sctx->cur_ino + 1 (260 + 1 = 261) for its "progress"
   argument. This makes can_rmdir() return true (value 1) because even
   though there's still a child inode of inode 259 that was not yet
   renamed/moved, which is inode 261, the given value of progress (261)
   is not lower then 261 (that is, not lower than the inode number of
   some child of inode 259). So we end up sending a rmdir operation for
   inode 259 before its child inode 261 is processed and renamed.

So fix this by passing the correct progress value to the call to
can_rmdir() from within apply_dir_move() (where we issue delayed rename
operations), which should match stcx->cur_ino (the number of the inode
currently being processed) and not sctx->cur_ino + 1.

A test case for fstests follows soon.

Signed-off-by: Robbie Ko <robbieko@synology.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
[Rewrote change log to be more detailed, clear and well formatted]

Signed-off-by: Filipe Manana <fdmanana@suse.com>
2016-08-01 07:25:12 +01:00
..
tests Btrfs: fix error return code in btrfs_init_test_fs() 2016-06-23 10:44:39 -07:00
acl.c
async-thread.c
async-thread.h
backref.c Merge branch 'cleanups-4.7' into for-chris-4.7-20160525 2016-05-25 22:51:03 +02:00
backref.h
btrfs_inode.h Merge branch 'cleanups-4.7' into for-chris-4.7-20160525 2016-05-25 22:51:03 +02:00
check-integrity.c btrfs: Use correct format specifier 2016-06-17 18:32:40 +02:00
check-integrity.h
compression.c btrfs: make find_workspace warn if there are no workspaces 2016-05-10 09:46:16 +02:00
compression.h
ctree.c Btrfs: fix error handling in map_private_extent_buffer 2016-06-23 10:44:40 -07:00
ctree.h Btrfs: add tracepoints for flush events 2016-07-07 18:45:53 +02:00
delayed-inode.c Btrfs: change delayed reservation fallback behavior 2016-07-07 18:45:53 +02:00
delayed-inode.h Btrfs: fix ->iterate_shared() by upgrading i_rwsem for delayed nodes 2016-06-25 06:20:10 -07:00
delayed-ref.c
delayed-ref.h btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
dev-replace.c Merge branch 'cleanups-4.7' into for-chris-4.7-20160525 2016-05-25 22:51:03 +02:00
dev-replace.h
dir-item.c
disk-io.c Btrfs: Force stripesize to the value of sectorsize 2016-06-23 10:44:42 -07:00
disk-io.h Btrfs: self-tests: Support non-4k page size 2016-06-02 19:23:14 +02:00
export.c
export.h
extent_io.c Btrfs: fix error handling in map_private_extent_buffer 2016-06-23 10:44:40 -07:00
extent_io.h Btrfs: self-tests: Support non-4k page size 2016-06-02 19:23:14 +02:00
extent_map.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
extent_map.h
extent-tree.c Btrfs: avoid deadlocks during reservations in btrfs_truncate_block 2016-07-20 16:58:04 -07:00
file-item.c
file.c Btrfs: add missing check for writeback errors on fsync 2016-08-01 07:21:13 +01:00
free-space-cache.c Btrfs: self-tests: Support non-4k page size 2016-06-02 19:23:14 +02:00
free-space-cache.h btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
free-space-tree.c
free-space-tree.h
hash.c btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
hash.h btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
inode-item.c
inode-map.c
inode-map.h
inode.c Btrfs: fix callers of btrfs_block_rsv_migrate 2016-07-07 18:45:53 +02:00
ioctl.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
Kconfig
locking.c
locking.h
lzo.c
Makefile
math.h
ordered-data.c btrfs: fix disk_i_size update bug when fallocate() fails 2016-06-23 10:44:41 -07:00
ordered-data.h Btrfs: fix race setting block group readonly during device replace 2016-05-30 12:58:21 +01:00
orphan.c
print-tree.c
print-tree.h
props.c
props.h
qgroup.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
qgroup.h
raid56.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
raid56.h
rcu-string.h
reada.c Btrfs: fix race between readahead and device replace/removal 2016-05-30 12:58:18 +01:00
relocation.c Btrfs: use FLUSH_LIMIT for relocation in reserve_metadata_bytes 2016-07-07 18:45:53 +02:00
root-tree.c Merge branch 'cleanups-4.7' into for-chris-4.7-20160525 2016-05-25 22:51:03 +02:00
scrub.c Btrfs: fix race setting block group back to RW mode during device replace 2016-05-30 12:58:24 +01:00
send.c Btrfs: incremental send, fix premature rmdir operations 2016-08-01 07:25:12 +01:00
send.h
struct-funcs.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
super.c btrfs: avoid blocking open_ctree from cleaner_kthread 2016-06-17 18:32:40 +02:00
sysfs.c btrfs: sysfs: protect reading label by lock 2016-05-06 15:22:49 +02:00
sysfs.h
transaction.c Btrfs: track transid for delayed ref flushing 2016-06-22 17:54:18 -07:00
transaction.h btrfs: account for non-CoW'd blocks in btrfs_abort_transaction 2016-06-17 18:32:40 +02:00
tree-defrag.c
tree-log.c Merge branch 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2016-06-18 05:57:59 -10:00
tree-log.h
ulist.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
ulist.h
uuid-tree.c
volumes.c Merge branch 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2016-06-25 08:42:31 -07:00
volumes.h Merge branch 'foreign/jeffm/uapi' into for-chris-4.7-20160516 2016-05-16 15:46:29 +02:00
xattr.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr.h btrfs: Switch to generic xattr handlers 2016-05-17 19:17:09 -04:00
zlib.c