1. 11 3月, 2014 15 次提交
    • F
      Btrfs: send, don't send rmdir for same target multiple times · 29d6d30f
      Filipe Manana 提交于
      When doing an incremental send, if we delete a directory that has N > 1
      hardlinks for the same file and that file has the highest inode number
      inside the directory contents, an incremental send would send N times an
      rmdir operation against the directory. This made the btrfs receive command
      fail on the second rmdir instruction, as the target directory didn't exist
      anymore.
      
      Steps to reproduce the issue:
      
          $ mkfs.btrfs -f /dev/sdb3
          $ mount /dev/sdb3 /mnt/btrfs
          $ mkdir -p /mnt/btrfs/a/b/c
          $ echo 'ola mundo' > /mnt/btrfs/a/b/c/foo.txt
          $ ln /mnt/btrfs/a/b/c/foo.txt /mnt/btrfs/a/b/c/bar.txt
          $ btrfs subvolume snapshot -r /mnt/btrfs /mnt/btrfs/snap1
          $ btrfs send /mnt/btrfs/snap1 -f /tmp/base.send
          $ rm -f /mnt/btrfs/a/b/c/foo.txt
          $ rm -f /mnt/btrfs/a/b/c/bar.txt
          $ rmdir /mnt/btrfs/a/b/c
          $ btrfs subvolume snapshot -r /mnt/btrfs /mnt/btrfs/snap2
          $ btrfs send -p /mnt/btrfs/snap1 /mnt/btrfs/snap2 -f /tmp/incremental.send
      
          $ umount /mnt/btrfs
          $ mkfs.btrfs -f /dev/sdb3
          $ mount /dev/sdb3 /mnt/btrfs
          $ btrfs receive /mnt/btrfs -f /tmp/base.send
          $ btrfs receive /mnt/btrfs -f /tmp/incremental.send
      
      The second btrfs receive command failed with:
      
          ERROR: rmdir o259-6-0 failed. No such file or directory
      
      A test case for xfstests follows.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      29d6d30f
    • F
      Btrfs: incremental send, fix invalid path after dir rename · 2b863a13
      Filipe Manana 提交于
      This fixes yet one more case not caught by the commit titled:
      
         Btrfs: fix infinite path build loops in incremental send
      
      In this case, even before the initial full send, we have a directory
      which is a child of a directory with a higher inode number. Then we
      perform the initial send, and after we rename both the child and the
      parent, without moving them around. After doing these 2 renames, an
      incremental send sent a rename instruction for the child directory
      which contained an invalid "from" path (referenced the parent's old
      name, not the new one), which made the btrfs receive command fail.
      
      Steps to reproduce:
      
          $ mkfs.btrfs -f /dev/sdb3
          $ mount /dev/sdb3 /mnt/btrfs
          $ mkdir -p /mnt/btrfs/a/b
          $ mkdir /mnt/btrfs/d
          $ mkdir /mnt/btrfs/a/b/c
          $ mv /mnt/btrfs/d /mnt/btrfs/a/b/c
          $ btrfs subvolume snapshot -r /mnt/btrfs /mnt/btrfs/snap1
          $ btrfs send /mnt/btrfs/snap1 -f /tmp/base.send
          $ mv /mnt/btrfs/a/b/c /mnt/btrfs/a/b/x
          $ mv /mnt/btrfs/a/b/x/d /mnt/btrfs/a/b/x/y
          $ btrfs subvolume snapshot -r /mnt/btrfs /mnt/btrfs/snap2
          $ btrfs send -p /mnt/btrfs/snap1 /mnt/btrfs/snap2 -f /tmp/incremental.send
      
          $ umout /mnt/btrfs
          $ mkfs.btrfs -f /dev/sdb3
          $ mount /dev/sdb3 /mnt/btrfs
          $ btrfs receive /mnt/btrfs -f /tmp/base.send
          $ btrfs receive /mnt/btrfs -f /tmp/incremental.send
      
      The second btrfs receive command failed with:
        "ERROR: rename a/b/c/d -> a/b/x/y failed. No such file or directory"
      
      A test case for xfstests follows.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      2b863a13
    • W
      Revert "Btrfs: remove transaction from btrfs send" · dcfd5ad2
      Wang Shilong 提交于
      This reverts commit 41ce9970.
      Previously i was thinking we can use readonly root's commit root
      safely while it is not true, readonly root may be cowed with the
      following cases.
      
      1.snapshot send root will cow source root.
      2.balance,device operations will also cow readonly send root
      to relocate.
      
      So i have two ideas to make us safe to use commit root.
      
      -->approach 1:
      make it protected by transaction and end transaction properly and we research
      next item from root node(see btrfs_search_slot_for_read()).
      
      -->approach 2:
      add another counter to local root structure to sync snapshot with send.
      and add a global counter to sync send with exclusive device operations.
      
      So with approach 2, send can use commit root safely, because we make sure
      send root can not be cowed during send. Unfortunately, it make codes *ugly*
      and more complex to maintain.
      
      To make snapshot and send exclusively, device operations and send operation
      exclusively with each other is a little confusing for common users.
      
      So why not drop into previous way.
      
      Cc: Josef Bacik <jbacik@fb.com>
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      dcfd5ad2
    • D
      btrfs: send: lower memory requirements in common case · ace01050
      David Sterba 提交于
      The fs_path structure uses an inline buffer and falls back to a chain of
      allocations, but vmalloc is not necessary because PATH_MAX fits into
      PAGE_SIZE.
      
      The size of fs_path has been reduced to 256 bytes from PAGE_SIZE,
      usually 4k. Experimental measurements show that most paths on a single
      filesystem do not exceed 200 bytes, and these get stored into the inline
      buffer directly, which is now 230 bytes. Longer paths are kmalloced when
      needed.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      ace01050
    • F
      Btrfs: make some tree searches in send.c more efficient · dff6d0ad
      Filipe David Borba Manana 提交于
      We have this pattern where we do search for a contiguous group of
      items in a tree and everytime we find an item, we process it, then
      we release our path, increment the offset of the search key, do
      another full tree search and repeat these steps until a tree search
      can't find more items we're interested in.
      
      Instead of doing these full tree searches after processing each item,
      just process the next item/slot in our leaf and don't release the path.
      Since all these trees are read only and we always use the commit root
      for a search and skip node/leaf locks, we're not affecting concurrency
      on the trees.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      dff6d0ad
    • F
      Btrfs: use right extent item position in send when finding extent clones · a0859c09
      Filipe David Borba Manana 提交于
      This was a leftover from the commit:
      
         74dd17fb
         (Btrfs: fix btrfs send for inline items and compression)
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      a0859c09
    • D
      btrfs: send: remove BUG_ON from name_cache_delete · 57fb8910
      David Sterba 提交于
      If cleaning the name cache fails, we could try to proceed at the cost of
      some memory leak. This is not expected to happen often.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      57fb8910
    • D
      btrfs: send: remove BUG from process_all_refs · 4d1a63b2
      David Sterba 提交于
      There are only 2 static callers, the BUG would normally be never
      reached, but let's be nice.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      4d1a63b2
    • D
      btrfs: send: squeeze bitfilelds in fs_path · 1f5a7ff9
      David Sterba 提交于
      We know that buf_len is at most PATH_MAX, 4k, and can merge it with the
      reversed member. This saves 3 bytes in favor of inline_buf.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      1f5a7ff9
    • D
      btrfs: send: remove virtual_mem member from fs_path · e25a8122
      David Sterba 提交于
      We don't need to keep track of that, it's available via is_vmalloc_addr.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      e25a8122
    • D
      btrfs: send: remove prepared member from fs_path · b23ab57d
      David Sterba 提交于
      The member is used only to return value back from
      fs_path_prepare_for_add, we can do it locally and save 8 bytes for the
      inline_buf path.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      b23ab57d
    • D
      btrfs: send: replace check with an assert in gen_unique_name · 64792f25
      David Sterba 提交于
      The buffer passed to snprintf can hold the fully expanded format string,
      64 = 3x largest ULL + 3x char + trailing null.  I don't think that removing the
      check entirely is a good idea, hence the ASSERT.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      64792f25
    • F
      Btrfs: more send support for parent/child dir relationship inversion · 5ed7f9ff
      Filipe David Borba Manana 提交于
      The commit titled "Btrfs: fix infinite path build loops in incremental send"
      didn't cover a particular case where the parent-child relationship inversion
      of directories doesn't imply a rename of the new parent directory. This was
      due to a simple logic mistake, a logical and instead of a logical or.
      
      Steps to reproduce:
      
        $ mkfs.btrfs -f /dev/sdb3
        $ mount /dev/sdb3 /mnt/btrfs
        $ mkdir -p /mnt/btrfs/a/b/bar1/bar2/bar3/bar4
        $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap1
        $ mv /mnt/btrfs/a/b/bar1/bar2/bar3/bar4 /mnt/btrfs/a/b/k44
        $ mv /mnt/btrfs/a/b/bar1/bar2/bar3 /mnt/btrfs/a/b/k44
        $ mv /mnt/btrfs/a/b/bar1/bar2 /mnt/btrfs/a/b/k44/bar3
        $ mv /mnt/btrfs/a/b/bar1 /mnt/btrfs/a/b/k44/bar3/bar2/k11
        $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap2
        $ btrfs send -p /mnt/btrfs/snap1 /mnt/btrfs/snap2 > /tmp/incremental.send
      
      A patch to update the test btrfs/030 from xfstests, so that it covers
      this case, will be submitted soon.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      5ed7f9ff
    • F
      Btrfs: fix send dealing with file renames and directory moves · 03cb4fb9
      Filipe David Borba Manana 提交于
      This fixes a case that the commit titled:
      
         Btrfs: fix infinite path build loops in incremental send
      
      didn't cover. If the parent-child relationship between 2 directories
      is inverted, both get renamed, and the former parent has a file that
      got renamed too (but remains a child of that directory), the incremental
      send operation would use the file's old path after sending an unlink
      operation for that old path, causing receive to fail on future operations
      like changing owner, permissions or utimes of the corresponding inode.
      
      This is not a regression from the commit mentioned before, as without
      that commit we would fall into the issues that commit fixed, so it's
      just one case that wasn't covered before.
      
      Simple steps to reproduce this issue are:
      
            $ mkfs.btrfs -f /dev/sdb3
            $ mount /dev/sdb3 /mnt/btrfs
            $ mkdir -p /mnt/btrfs/a/b/c/d
            $ touch /mnt/btrfs/a/b/c/d/file
            $ mkdir -p /mnt/btrfs/a/b/x
            $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap1
            $ mv /mnt/btrfs/a/b/x /mnt/btrfs/a/b/c/x2
            $ mv /mnt/btrfs/a/b/c/d /mnt/btrfs/a/b/c/x2/d2
            $ mv /mnt/btrfs/a/b/c/x2/d2/file /mnt/btrfs/a/b/c/x2/d2/file2
            $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap2
            $ btrfs send -p /mnt/btrfs/snap1 /mnt/btrfs/snap2 > /tmp/incremental.send
      
      A patch to update the test btrfs/030 from xfstests, so that it covers
      this case, will be submitted soon.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      03cb4fb9
    • F
      Btrfs: add missing error check in incremental send · d86477b3
      Filipe David Borba Manana 提交于
      Function wait_for_parent_move() returns negative value if an error
      happened, 0 if we don't need to wait for the parent's move, and
      1 if the wait is needed.
      Before this change an error return value was being treated like the
      return value 1, which was not correct.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      d86477b3
  2. 16 2月, 2014 1 次提交
    • F
      Btrfs: use right clone root offset for compressed extents · 93de4ba8
      Filipe David Borba Manana 提交于
      For non compressed extents, iterate_extent_inodes() gives us offsets
      that take into account the data offset from the file extent items, while
      for compressed extents it doesn't. Therefore we have to adjust them before
      placing them in a send clone instruction. Not doing this adjustment leads to
      the receiving end requesting for a wrong a file range to the clone ioctl,
      which results in different file content from the one in the original send
      root.
      
      Issue reproducible with the following excerpt from the test I made for
      xfstests:
      
        _scratch_mkfs
        _scratch_mount "-o compress-force=lzo"
      
        $XFS_IO_PROG -f -c "truncate 118811" $SCRATCH_MNT/foo
        $XFS_IO_PROG -c "pwrite -S 0x0d -b 39987 92267 39987" $SCRATCH_MNT/foo
      
        $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1
      
        $XFS_IO_PROG -c "pwrite -S 0x3e -b 80000 200000 80000" $SCRATCH_MNT/foo
        $BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT
        $XFS_IO_PROG -c "pwrite -S 0xdc -b 10000 250000 10000" $SCRATCH_MNT/foo
        $XFS_IO_PROG -c "pwrite -S 0xff -b 10000 300000 10000" $SCRATCH_MNT/foo
      
        # will be used for incremental send to be able to issue clone operations
        $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/clones_snap
      
        $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2
      
        $FSSUM_PROG -A -f -w $tmp/1.fssum $SCRATCH_MNT/mysnap1
        $FSSUM_PROG -A -f -w $tmp/2.fssum -x $SCRATCH_MNT/mysnap2/mysnap1 \
            -x $SCRATCH_MNT/mysnap2/clones_snap $SCRATCH_MNT/mysnap2
        $FSSUM_PROG -A -f -w $tmp/clones.fssum $SCRATCH_MNT/clones_snap \
            -x $SCRATCH_MNT/clones_snap/mysnap1 -x $SCRATCH_MNT/clones_snap/mysnap2
      
        $BTRFS_UTIL_PROG send $SCRATCH_MNT/mysnap1 -f $tmp/1.snap
        $BTRFS_UTIL_PROG send $SCRATCH_MNT/clones_snap -f $tmp/clones.snap
        $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/mysnap1 \
            -c $SCRATCH_MNT/clones_snap $SCRATCH_MNT/mysnap2 -f $tmp/2.snap
      
        _scratch_unmount
        _scratch_mkfs
        _scratch_mount
      
        $BTRFS_UTIL_PROG receive $SCRATCH_MNT -f $tmp/1.snap
        $FSSUM_PROG -r $tmp/1.fssum $SCRATCH_MNT/mysnap1 2>> $seqres.full
      
        $BTRFS_UTIL_PROG receive $SCRATCH_MNT -f $tmp/clones.snap
        $FSSUM_PROG -r $tmp/clones.fssum $SCRATCH_MNT/clones_snap 2>> $seqres.full
      
        $BTRFS_UTIL_PROG receive $SCRATCH_MNT -f $tmp/2.snap
        $FSSUM_PROG -r $tmp/2.fssum $SCRATCH_MNT/mysnap2 2>> $seqres.full
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      93de4ba8
  3. 09 2月, 2014 1 次提交
    • J
      Btrfs: fix assert screwup for the pending move stuff · 6cc98d90
      Josef Bacik 提交于
      Wang noticed that he was failing btrfs/030 even though me and Filipe couldn't
      reproduce.  Turns out this is because Wang didn't have CONFIG_BTRFS_ASSERT set,
      which meant that a key part of Filipe's original patch was not being built in.
      This appears to be a mess up with merging Filipe's patch as it does not exist in
      his original patch.  Fix this by changing how we make sure del_waiting_dir_move
      asserts that it did not error and take the function out of the ifdef check.
      This makes btrfs/030 pass with the assert on or off.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Reviewed-by: NFilipe Manana <fdmanana@gmail.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      6cc98d90
  4. 04 2月, 2014 1 次提交
  5. 29 1月, 2014 18 次提交
    • C
      Btrfs: don't use ram_bytes for uncompressed inline items · 514ac8ad
      Chris Mason 提交于
      If we truncate an uncompressed inline item, ram_bytes isn't updated to reflect
      the new size.  The fixe uses the size directly from the item header when
      reading uncompressed inlines, and also fixes truncate to update the
      size as it goes.
      Reported-by: NJens Axboe <axboe@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      CC: stable@vger.kernel.org
      514ac8ad
    • F
      Btrfs: fix send file hole detection leading to data corruption · bf54f412
      Filipe David Borba Manana 提交于
      There was a case where file hole detection was incorrect and it would
      cause an incremental send to override a section of a file with zeroes.
      
      This happened in the case where between the last leaf we processed which
      contained a file extent item for our current inode and the leaf we're
      currently are at (and has a file extent item for our current inode) there
      are only leafs containing exclusively file extent items for our current
      inode, and none of them was updated since the previous send operation.
      The file hole detection code would incorrectly consider the file range
      covered by these leafs as a hole.
      
      A test case for xfstests follows soon.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      bf54f412
    • F
      Btrfs: make send's file extent item search more efficient · 7fdd29d0
      Filipe David Borba Manana 提交于
      Instead of looking for a file extent item, process it, release the path
      and do a btree search for the next file extent item, just process all
      file extent items in a leaf without intermediate btree searches. This way
      we save cpu and we're not blocking other tasks or affecting concurrency on
      the btree, because send's paths use the commit root and skip btree node/leaf
      locking.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      7fdd29d0
    • F
      Btrfs: fix infinite path build loops in incremental send · 9f03740a
      Filipe David Borba Manana 提交于
      The send operation processes inodes by their ascending number, and assumes
      that any rename/move operation can be successfully performed (sent to the
      caller) once all previous inodes (those with a smaller inode number than the
      one we're currently processing) were processed.
      
      This is not true when an incremental send had to process an hierarchical change
      between 2 snapshots where the parent-children relationship between directory
      inodes was reversed - that is, parents became children and children became
      parents. This situation made the path building code go into an infinite loop,
      which kept allocating more and more memory that eventually lead to a krealloc
      warning being displayed in dmesg:
      
        WARNING: CPU: 1 PID: 5705 at mm/page_alloc.c:2477 __alloc_pages_nodemask+0x365/0xad0()
        Modules linked in: btrfs raid6_pq xor pci_stub vboxpci(O) vboxnetadp(O) vboxnetflt(O) vboxdrv(O) snd_hda_codec_hdmi snd_hda_codec_realtek joydev radeon snd_hda_intel snd_hda_codec snd_hwdep snd_seq_midi snd_pcm psmouse i915 snd_rawmidi serio_raw snd_seq_midi_event lpc_ich snd_seq snd_timer ttm snd_seq_device rfcomm drm_kms_helper parport_pc bnep bluetooth drm ppdev snd soundcore i2c_algo_bit snd_page_alloc binfmt_misc video lp parport r8169 mii hid_generic usbhid hid
        CPU: 1 PID: 5705 Comm: btrfs Tainted: G           O 3.13.0-rc7-fdm-btrfs-next-18+ #3
        Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./Z77 Pro4, BIOS P1.50 09/04/2012
        [ 5381.660441]  00000000000009ad ffff8806f6f2f4e8 ffffffff81777434 0000000000000007
        [ 5381.660447]  0000000000000000 ffff8806f6f2f528 ffffffff8104a9ec ffff8807038f36f0
        [ 5381.660452]  0000000000000000 0000000000000206 ffff8807038f2490 ffff8807038f36f0
        [ 5381.660457] Call Trace:
        [ 5381.660464]  [<ffffffff81777434>] dump_stack+0x4e/0x68
        [ 5381.660471]  [<ffffffff8104a9ec>] warn_slowpath_common+0x8c/0xc0
        [ 5381.660476]  [<ffffffff8104aa3a>] warn_slowpath_null+0x1a/0x20
        [ 5381.660480]  [<ffffffff81144995>] __alloc_pages_nodemask+0x365/0xad0
        [ 5381.660487]  [<ffffffff8108313f>] ? local_clock+0x4f/0x60
        [ 5381.660491]  [<ffffffff811430e8>] ? free_one_page+0x98/0x440
        [ 5381.660495]  [<ffffffff8108313f>] ? local_clock+0x4f/0x60
        [ 5381.660502]  [<ffffffff8113fae4>] ? __get_free_pages+0x14/0x50
        [ 5381.660508]  [<ffffffff81095fb8>] ? trace_hardirqs_off_caller+0x28/0xd0
        [ 5381.660515]  [<ffffffff81183caf>] alloc_pages_current+0x10f/0x1f0
        [ 5381.660520]  [<ffffffff8113fae4>] ? __get_free_pages+0x14/0x50
        [ 5381.660524]  [<ffffffff8113fae4>] __get_free_pages+0x14/0x50
        [ 5381.660530]  [<ffffffff8115dace>] kmalloc_order_trace+0x3e/0x100
        [ 5381.660536]  [<ffffffff81191ea0>] __kmalloc_track_caller+0x220/0x230
        [ 5381.660560]  [<ffffffffa0729fdb>] ? fs_path_ensure_buf.part.12+0x6b/0x200 [btrfs]
        [ 5381.660564]  [<ffffffff8178085c>] ? retint_restore_args+0xe/0xe
        [ 5381.660569]  [<ffffffff811580ef>] krealloc+0x6f/0xb0
        [ 5381.660586]  [<ffffffffa0729fdb>] fs_path_ensure_buf.part.12+0x6b/0x200 [btrfs]
        [ 5381.660601]  [<ffffffffa072a208>] fs_path_prepare_for_add+0x98/0xb0 [btrfs]
        [ 5381.660615]  [<ffffffffa072a2bc>] fs_path_add_path+0x2c/0x60 [btrfs]
        [ 5381.660628]  [<ffffffffa072c55c>] get_cur_path+0x7c/0x1c0 [btrfs]
      
      Even without this loop, the incremental send couldn't succeed, because it would attempt
      to send a rename/move operation for the lower inode before the highest inode number was
      renamed/move. This issue is easy to trigger with the following steps:
      
        $ mkfs.btrfs -f /dev/sdb3
        $ mount /dev/sdb3 /mnt/btrfs
        $ mkdir -p /mnt/btrfs/a/b/c/d
        $ mkdir /mnt/btrfs/a/b/c2
        $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap1
        $ mv /mnt/btrfs/a/b/c/d /mnt/btrfs/a/b/c2/d2
        $ mv /mnt/btrfs/a/b/c /mnt/btrfs/a/b/c2/d2/cc
        $ btrfs subvol snapshot -r /mnt/btrfs /mnt/btrfs/snap2
        $ btrfs send -p /mnt/btrfs/snap1 /mnt/btrfs/snap2 > /tmp/incremental.send
      
      The structure of the filesystem when the first snapshot is taken is:
      
      	 .                       (ino 256)
      	 |-- a                   (ino 257)
      	     |-- b               (ino 258)
      	         |-- c           (ino 259)
      	         |   |-- d       (ino 260)
                       |
      	         |-- c2          (ino 261)
      
      And its structure when the second snapshot is taken is:
      
      	 .                       (ino 256)
      	 |-- a                   (ino 257)
      	     |-- b               (ino 258)
      	         |-- c2          (ino 261)
      	             |-- d2      (ino 260)
      	                 |-- cc  (ino 259)
      
      Before the move/rename operation is performed for the inode 259, the
      move/rename for inode 260 must be performed, since 259 is now a child
      of 260.
      
      A test case for xfstests, with a more complex scenario, will follow soon.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      9f03740a
    • F
      Btrfs: fix snprintf usage by send's gen_unique_name · f74b86d8
      Filipe David Borba Manana 提交于
      The buffer size argument passed to snprintf must account for the
      trailing null byte added by snprintf, and it returns a value >= then
      sizeof(buffer) when the string can't fit in the buffer.
      
      Since our buffer has a size of 64 characters, and the maximum orphan
      name we can generate is 63 characters wide, we must pass 64 as the
      buffer size to snprintf, and not 63.
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      f74b86d8
    • W
      Btrfs: fix wrong search path initialization before searching tree root · ffcfaf81
      Wang Shilong 提交于
      To search tree root without transaction protection, we should neither search commit
      root nor skip locking here, fix it.
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      ffcfaf81
    • F
      Btrfs: fix send to not send non-aligned clone operations · 28e5dd8f
      Filipe David Borba Manana 提交于
      It is possible for the send feature to send clone operations that
      request a cloning range (offset + length) that is not aligned with
      the block size. This makes the btrfs receive command send issue a
      clone ioctl call that will fail, as the ioctl will return an -EINVAL
      error because of the unaligned range.
      
      Fix this by not sending clone operations for non block aligned ranges,
      and instead send regular write operation for these (less common) cases.
      
      The following xfstest reproduces this issue, which fails on the second
      btrfs receive command without this change:
      
        seq=`basename $0`
        seqres=$RESULT_DIR/$seq
        echo "QA output created by $seq"
      
        tmp=`mktemp -d`
      
        status=1	# failure is the default!
        trap "_cleanup; exit \$status" 0 1 2 3 15
      
        _cleanup()
        {
            rm -fr $tmp
        }
      
        # get standard environment, filters and checks
        . ./common/rc
        . ./common/filter
      
        # real QA test starts here
        _supported_fs btrfs
        _supported_os Linux
        _require_scratch
        _need_to_be_root
      
        rm -f $seqres.full
      
        _scratch_mkfs >/dev/null 2>&1
        _scratch_mount
      
        $XFS_IO_PROG -f -c "truncate 819200" $SCRATCH_MNT/foo | _filter_xfs_io
        $BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT | _filter_scratch
      
        $XFS_IO_PROG -c "falloc -k 819200 667648" $SCRATCH_MNT/foo | _filter_xfs_io
        $BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT | _filter_scratch
      
        $XFS_IO_PROG -f -c "pwrite 1482752 2978" $SCRATCH_MNT/foo | _filter_xfs_io
        $BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT | _filter_scratch
      
        $BTRFS_UTIL_PROG subvol snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap1 | \
            _filter_scratch
      
        $XFS_IO_PROG -f -c "truncate 883305" $SCRATCH_MNT/foo | _filter_xfs_io
        $BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT | _filter_scratch
      
        $BTRFS_UTIL_PROG subvol snapshot -r $SCRATCH_MNT $SCRATCH_MNT/mysnap2 | \
            _filter_scratch
      
        $BTRFS_UTIL_PROG send $SCRATCH_MNT/mysnap1 -f $tmp/1.snap 2>&1 | _filter_scratch
        $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/mysnap1 $SCRATCH_MNT/mysnap2 \
            -f $tmp/2.snap 2>&1 | _filter_scratch
      
        md5sum $SCRATCH_MNT/foo | _filter_scratch
        md5sum $SCRATCH_MNT/mysnap1/foo | _filter_scratch
        md5sum $SCRATCH_MNT/mysnap2/foo | _filter_scratch
      
        _scratch_unmount
        _check_btrfs_filesystem $SCRATCH_DEV
        _scratch_mkfs >/dev/null 2>&1
        _scratch_mount
      
        $BTRFS_UTIL_PROG receive $SCRATCH_MNT -f $tmp/1.snap
        md5sum $SCRATCH_MNT/mysnap1/foo | _filter_scratch
      
        $BTRFS_UTIL_PROG receive $SCRATCH_MNT -f $tmp/2.snap
        md5sum $SCRATCH_MNT/mysnap2/foo | _filter_scratch
      
        _scratch_unmount
        _check_btrfs_filesystem $SCRATCH_DEV
      
        status=0
        exit
      
      The tests expected output is:
      
        QA output created by 025
        FSSync 'SCRATCH_MNT'
        FSSync 'SCRATCH_MNT'
        wrote 2978/2978 bytes at offset 1482752
        XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
        FSSync 'SCRATCH_MNT'
        Create a readonly snapshot of 'SCRATCH_MNT' in 'SCRATCH_MNT/mysnap1'
        FSSync 'SCRATCH_MNT'
        Create a readonly snapshot of 'SCRATCH_MNT' in 'SCRATCH_MNT/mysnap2'
        At subvol SCRATCH_MNT/mysnap1
        At subvol SCRATCH_MNT/mysnap2
        129b8eaee8d3c2bcad49bec596591cb3  SCRATCH_MNT/foo
        42b6369eae2a8725c1aacc0440e597aa  SCRATCH_MNT/mysnap1/foo
        129b8eaee8d3c2bcad49bec596591cb3  SCRATCH_MNT/mysnap2/foo
        At subvol mysnap1
        42b6369eae2a8725c1aacc0440e597aa  SCRATCH_MNT/mysnap1/foo
        At snapshot mysnap2
        129b8eaee8d3c2bcad49bec596591cb3  SCRATCH_MNT/mysnap2/foo
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      28e5dd8f
    • W
      Btrfs: remove unnecessary transaction commit before send · 8e56338d
      Wang Shilong 提交于
      We will finish orphan cleanups during snapshot, so we don't
      have to commit transaction here.
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Reviewed-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      8e56338d
    • W
      Btrfs: fix protection between send and root deletion · 18f687d5
      Wang Shilong 提交于
      We should gurantee that parent and clone roots can not be destroyed
      during send, for this we have two ideas.
      
      1.by holding @subvol_sem, this might be a nightmare, because it will
      block all subvolumes deletion for a long time.
      
      2.Miao pointed out we can reuse @send_in_progress, that mean we will
      skip snapshot deletion if root sending is in progress.
      
      Here we adopt the second approach since it won't block other subvolumes
      deletion for a long time.
      
      Besides in btrfs_clean_one_deleted_snapshot(), we only check first root
      , if this root is involved in send, we return directly rather than
      continue to check.There are several reasons about it:
      
      1.this case happen seldomly.
      2.after sending,cleaner thread can continue to drop that root.
      3.make code simple
      
      Cc: David Sterba <dsterba@suse.cz>
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Reviewed-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      18f687d5
    • W
      Btrfs: fix wrong send_in_progress accounting · 896c14f9
      Wang Shilong 提交于
      Steps to reproduce:
       # mkfs.btrfs -f /dev/sda8
       # mount /dev/sda8 /mnt
       # btrfs sub snapshot -r /mnt /mnt/snap1
       # btrfs sub snapshot -r /mnt /mnt/snap2
       # btrfs send /mnt/snap1 -p /mnt/snap2 -f /mnt/1
       # dmesg
      
      The problem is that we will sort clone roots(include @send_root), it
      might push @send_root before thus @send_root's @send_in_progress will
      be decreased twice.
      
      Cc: David Sterba <dsterba@suse.cz>
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      896c14f9
    • F
      Btrfs: convert printk to btrfs_ and fix BTRFS prefix · efe120a0
      Frank Holton 提交于
      Convert all applicable cases of printk and pr_* to the btrfs_* macros.
      
      Fix all uses of the BTRFS prefix.
      Signed-off-by: NFrank Holton <fholton@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      efe120a0
    • D
      btrfs: check balance of send_in_progress · 66ef7d65
      David Sterba 提交于
      Warn if the balance goes below zero, which appears to be unlikely
      though. Otherwise cleans up the code a bit.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      66ef7d65
    • W
      Btrfs: remove transaction from btrfs send · 41ce9970
      Wang Shilong 提交于
      Since daivd did the work that force us to use readonly snapshot,
      we can safely remove transaction protection from btrfs send.
      Signed-off-by: NWang Shilong <wangsl.fnst@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      41ce9970
    • D
      btrfs: Check read-only status of roots during send · 2c686537
      David Sterba 提交于
      All the subvolues that are involved in send must be read-only during the
      whole operation. The ioctl SUBVOL_SETFLAGS could be used to change the
      status to read-write and the result of send stream is undefined if the
      data change unexpectedly.
      
      Fix that by adding a refcount for all involved roots and verify that
      there's no send in progress during SUBVOL_SETFLAGS ioctl call that does
      read-only -> read-write transition.
      
      We need refcounts because there are no restrictions on number of send
      parallel operations currently run on a single subvolume, be it source,
      parent or one of the multiple clone sources.
      
      Kernel is silent when the RO checks fail and returns EPERM. The same set
      of checks is done already in userspace before send starts.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      2c686537
    • D
      btrfs: remove unused mnt from send_ctx · a8d89f5b
      David Sterba 提交于
      Unused since ed259095
      "Btrfs: stop using vfs_read in send".
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      a8d89f5b
    • D
      btrfs: send: clean up dead code · 95bc79d5
      David Sterba 提交于
      Remove ifdefed code:
      
      - tlv_put for 8, 16 and 32, add a generic tempalte if needed in future
      - tlv_put_timespec - the btrfs_timespec fields are used
      - fs_path_remove obsoleted long ago
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      95bc79d5
    • F
      Btrfs: fix pass of transid with wrong endianness in send.c · 5a0f4e2c
      Filipe David Borba Manana 提交于
      fs/btrfs/send.c:2190:9: warning: incorrect type in argument 3 (different base types)
      fs/btrfs/send.c:2190:9:    expected unsigned long long [unsigned] [usertype] value
      fs/btrfs/send.c:2190:9:    got restricted __le64 [usertype] ctransid
      fs/btrfs/send.c:2195:17: warning: incorrect type in argument 3 (different base types)
      fs/btrfs/send.c:2195:17:    expected unsigned long long [unsigned] [usertype] value
      fs/btrfs/send.c:2195:17:    got restricted __le64 [usertype] ctransid
      fs/btrfs/send.c:3716:9: warning: incorrect type in argument 3 (different base types)
      fs/btrfs/send.c:3716:9:    expected unsigned long long [unsigned] [usertype] value
      fs/btrfs/send.c:3716:9:    got restricted __le64 [usertype] ctransid
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      5a0f4e2c
    • J
      Btrfs: incompatible format change to remove hole extents · 16e7549f
      Josef Bacik 提交于
      Btrfs has always had these filler extent data items for holes in inodes.  This
      has made somethings very easy, like logging hole punches and sending hole
      punches.  However for large holey files these extent data items are pure
      overhead.  So add an incompatible feature to no longer add hole extents to
      reduce the amount of metadata used by these sort of files.  This has a few
      changes for logging and send obviously since they will need to detect holes and
      log/send the holes if there are any.  I've tested this thoroughly with xfstests
      and it doesn't cause any issues with and without the incompat format set.
      Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      16e7549f
  6. 12 12月, 2013 1 次提交
  7. 12 11月, 2013 3 次提交