13 Oct, 2011

1 commit


11 Oct, 2011

2 commits

  • The btrfs file defrag code will loop through the extents and
    force COW on them. But there is a concurrent truncate in the middle of
    the defrag, it might end up defragging the same range over and over
    again.

    The problem is that writepage won't go through and do anything on pages
    past i_size, so the cow won't happen, so the file will appear to still
    be fragmented. defrag will end up hitting the same extents again and
    again.

    In the worst case, the truncate can actually live lock with the defrag
    because the defrag keeps creating new ordered extents which the truncate
    code keeps waiting on.

    The fix here is to make defrag check for i_size inside the main loop,
    instead of just once before the looping starts.

    Signed-off-by: Chris Mason

    Chris Mason
     
  • Follow those steps:

    # mount -o autodefrag /dev/sda7 /mnt
    # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1
    # sync
    # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notrunc

    and then it'll go into a loop: writeback -> defrag -> writeback ...

    It's because writeback writes [8K, 200K] and then writes [0, 8K].

    I tried to make writeback know if the pages are dirtied by defrag,
    but the patch was a bit intrusive. Here I simply set writeback_index
    when we defrag a file.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     

04 Oct, 2011

1 commit


01 Oct, 2011

1 commit

  • A user reported a problem where ceph was getting into 100% cpu usage while doing
    some writing. It turns out it's because we were doing a short write on a not
    uptodate page, which means we'd fall back at one page at a time and fault the
    page in. The problem is our position is on the page boundary, so our fault in
    logic wasn't actually reading the page, so we'd just spin forever or until the
    page got read in by somebody else. This will force a readpage if we end up
    doing a short copy. Alexandre could reproduce this easily with ceph and reports
    it fixes his problem. I also wrote a reproducer that no longer hangs my box
    with this patch. Thanks,

    Reported-and-tested-by: Alexandre Oliva
    Signed-off-by: Josef Bacik
    Signed-off-by: Chris Mason

    Josef Bacik
     

21 Sep, 2011

2 commits


18 Sep, 2011

7 commits

  • We can race with readdir and the RCU path walking stuff. This is because we
    clear the need lookup flag before actually instantiating the inode. This will
    lead the RCU path walk stuff to find a dentry it thinks is valid without a
    d_inode attached. So instead unhash the dentry when we first start the lookup,
    and then clear the flag after we've instantiated the dentry so we're garunteed
    to either try the slow lookup, or have the d_inode set properly.

    Signed-off-by: Josef Bacik
    Signed-off-by: Chris Mason

    Josef Bacik
     
  • The recent reworking of btrfs' lseek lead to incorrect
    values being returned. This adds checks for seeking
    beyond EOF in SEEK_HOLE and makes sure the error
    values come back correct.

    Andi Kleen also sent in similar patches.

    Signed-off-by: Jie Liu
    Reported-by: Andi Kleen
    Signed-off-by: Chris Mason

    Jeff Liu
     
  • Chris Mason
     
  • The dst file will have the same inode flags with dst file after
    file clone, and I think it's unexpected.

    For example, the dst file will suddenly become immutable after
    getting some share of data with src file, if the src is immutable.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • To reproduce the bug:

    # mount /dev/sda7 /mnt
    # dd if=/dev/zero of=/mnt/src bs=4K count=1
    # umount /mnt

    # mount -o nodatasum /dev/sda7 /mnt
    # dd if=/dev/zero of=/mnt/dst bs=4K count=1
    # clone_range -s 4K -l 4K /mnt/src /mnt/dst

    # echo 3 > /proc/sys/vm/drop_caches
    # cat /mnt/dst
    # dmesg
    ...
    btrfs no csum found for inode 258 start 0
    btrfs csum failed ino 258 off 0 csum 2566472073 private 0

    It's because part of the file is checksummed and the other part is not,
    and then btrfs will complain checksum is not found when we read the file.

    Disallow file clone if src and dst file have different checksum flag,
    so we ensure a file is completely checksummed or unchecksummed.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • It's a bug in commit f81c9cdc567cd3160ff9e64868d9a1a7ee226480
    (Btrfs: truncate pages from clone ioctl target range)

    We should pass the dest range to the truncate function, but not the
    src range.

    Also move the function before locking extent state.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • Since the d_off in the first dirent for "." (that originates from
    the 4th argument "offset" of filldir() for the 2nd dirent for "..")
    is wrongly assigned in btrfs_real_readdir(), telldir returns same
    offset for different locations.

    | # mkfs.btrfs /dev/sdb1
    | # mount /dev/sdb1 fs0
    | # cd fs0
    | # touch file0 file1
    | # ../test
    | telldir: 0
    | readdir: d_off = 2, d_name = "."
    | telldir: 2
    | readdir: d_off = 2, d_name = ".."
    | telldir: 2
    | readdir: d_off = 3, d_name = "file0"
    | telldir: 3
    | readdir: d_off = 2147483647, d_name = "file1"
    | telldir: 2147483647

    To fix this problem, pass filp->f_pos (which is loff_t) instead.

    | # ../test
    | telldir: 0
    | readdir: d_off = 1, d_name = "."
    | telldir: 1
    | readdir: d_off = 2, d_name = ".."
    | telldir: 2
    | readdir: d_off = 3, d_name = "file0"
    :

    At the moment the "offset" for "." is unused because there is no
    preceding dirent, however it is better to pass filp->f_pos to follow
    grammatical usage.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Chris Mason

    Hidetoshi Seto
     

13 Sep, 2011

1 commit

  • * 'for-linus' of git://github.com/chrismason/linux:
    Btrfs: add dummy extent if dst offset excceeds file end in
    Btrfs: calc file extent num_bytes correctly in file clone
    btrfs: xattr: fix attribute removal
    Btrfs: fix wrong nbytes information of the inode
    Btrfs: fix the file extent gap when doing direct IO
    Btrfs: fix unclosed transaction handle in btrfs_cont_expand
    Btrfs: fix misuse of trans block rsv
    Btrfs: reset to appropriate block rsv after orphan operations
    Btrfs: skip locking if searching the commit root in csum lookup
    btrfs: fix warning in iput for bad-inode
    Btrfs: fix an oops when deleting snapshots

    Linus Torvalds
     

11 Sep, 2011

11 commits

  • You can see there's no file extent with range [0, 4096]. Check this by
    btrfsck:

    # btrfsck /dev/sda7
    root 5 inode 258 errors 100
    ...

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • num_bytes should be 4096 not 12288.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • An attribute is not removed by 'setfattr -x attr file' and remains
    visible in attr list. This makes xfstests/062 pass again.

    Signed-off-by: David Sterba
    Signed-off-by: Chris Mason

    David Sterba
     
  • If we write some data into the data hole of the file(no preallocation for this
    hole), Btrfs will allocate some disk space, and update nbytes of the inode, but
    the other element--disk_i_size needn't be updated. At this condition, we must
    update inode metadata though disk_i_size is not changed(btrfs_ordered_update_i_size()
    return 1).

    # mkfs.btrfs /dev/sdb1
    # mount /dev/sdb1 /mnt
    # touch /mnt/a
    # truncate -s 856002 /mnt/a
    # dd if=/dev/zero of=/mnt/a bs=4K count=1 conv=nocreat,notrunc
    # umount /mnt
    # btrfsck /dev/sdb1
    root 5 inode 257 errors 400
    found 32768 bytes used err is 1

    Signed-off-by: Miao Xie
    Signed-off-by: Chris Mason

    Miao Xie
     
  • When we write some data to the place that is beyond the end of the file
    in direct I/O mode, a data hole will be created. And Btrfs should insert
    a file extent item that point to this hole into the fs tree. But unfortunately
    Btrfs forgets doing it.

    The following is a simple way to reproduce it:
    # mkfs.btrfs /dev/sdc2
    # mount /dev/sdc2 /test4
    # touch /test4/a
    # dd if=/dev/zero of=/test4/a seek=8 count=1 bs=4K oflag=direct conv=nocreat,notrunc
    # umount /test4
    # btrfsck /dev/sdc2
    root 5 inode 257 errors 100

    Reported-by: Tsutomu Itoh
    Signed-off-by: Miao Xie
    Tested-by: Tsutomu Itoh
    Signed-off-by: Chris Mason

    Miao Xie
     
  • The function - btrfs_cont_expand() forgot to close the transaction handle before
    it jump out the while loop. Fix it.

    Signed-off-by: Miao Xie
    Signed-off-by: Chris Mason

    Miao Xie
     
  • At the beginning of create_pending_snapshot, trans->block_rsv is set
    to pending->block_rsv and is used for snapshot things, however, when
    it is done, we do not recover it as will.

    Signed-off-by: Liu Bo
    Signed-off-by: Chris Mason

    Liu Bo
     
  • While truncating free space cache, we forget to change trans->block_rsv
    back to the original one, but leave it with the orphan_block_rsv, and
    then with option inode_cache enable, it leads to countless warnings of
    btrfs_alloc_free_block and btrfs_orphan_commit_root:

    WARNING: at fs/btrfs/extent-tree.c:5711 btrfs_alloc_free_block+0x180/0x350 [btrfs]()
    ...
    WARNING: at fs/btrfs/inode.c:2193 btrfs_orphan_commit_root+0xb0/0xc0 [btrfs]()

    Signed-off-by: Liu Bo
    Signed-off-by: Chris Mason

    Liu Bo
     
  • It's not enough to just search the commit root, since we could be cow'ing the
    very block we need to search through, which would mean that its locked and we'll
    still deadlock. So use path->skip_locking as well. Thanks,

    Signed-off-by: Josef Bacik
    Signed-off-by: Chris Mason

    Josef Bacik
     
  • iput() shouldn't be called for inodes in I_NEW state.
    We need to mark inode as constructed first.

    WARNING: at fs/inode.c:1309 iput+0x20b/0x210()
    Call Trace:
    [] warn_slowpath_common+0x7a/0xb0
    [] warn_slowpath_null+0x15/0x20
    [] iput+0x20b/0x210
    [] btrfs_iget+0x1eb/0x4a0
    [] btrfs_run_defrag_inodes+0x136/0x210
    [] cleaner_kthread+0x17f/0x1a0
    [] ? sub_preempt_count+0x9d/0xd0
    [] ? transaction_kthread+0x280/0x280
    [] kthread+0x96/0xa0
    [] kernel_thread_helper+0x4/0x10
    [] ? kthread_worker_fn+0x190/0x190
    [] ? gs_change+0xb/0xb

    Signed-off-by: Sergei Trofimovich
    CC: Konstantin Khlebnikov
    Tested-by: David Sterba
    CC: Josef Bacik
    CC: Chris Mason
    Signed-off-by: Chris Mason

    Sergei Trofimovich
     
  • We can reproduce this oops via the following steps:

    $ mkfs.btrfs /dev/sdb7
    $ mount /dev/sdb7 /mnt/btrfs
    $ for ((i=0; ii_ino
    to BTRFS_EMPTY_SUBVOL_DIR_OBJECTID instead of BTRFS_FIRST_FREE_OBJECTID,
    while the snapshot's location.objectid remains unchanged.

    However, btrfs_ino() does not take this into account, and returns a wrong ino,
    and causes the oops.

    Signed-off-by: Liu Bo
    Signed-off-by: Chris Mason

    Liu Bo
     

21 Aug, 2011

1 commit

  • This fixes a regression introduced by commit cdcb725c05fe ("Btrfs: check
    if there is enough space for balancing smarter"). We can't do 64-bit
    divides on 32-bit architectures.

    In cases where we need to divide/multiply by 2 we should just left/right
    shift respectively, and in cases where theres N number of devices use
    do_div. Also make the counters u64 to match up with rw_devices.
    Thanks,

    Signed-off-by: Josef Bacik
    Acked-and-tested-by: Ingo Molnar
    Signed-off-by: Linus Torvalds

    Josef Bacik
     

18 Aug, 2011

4 commits


17 Aug, 2011

9 commits

  • We need to truncate page cache pages for the clone ioctl target range or
    else we'll confuse ourselves to no end. If the old data was cached, we
    used to still see it (until remount). If the page was partially updated
    we used to get a mix of old and new data.

    Signed-off-by: Sage Weil
    Signed-off-by: Chris Mason

    Sage Weil
     
  • sync_pending is uninitialized before it be used, fix it.

    Signed-off-by: Miao Xie
    Signed-off-by: Chris Mason

    Miao Xie
     
  • Btrfs subtracted the size of the allocated space twice when it allocated
    the space from the bitmap in the cluster, it broke the free space information
    and led to oops finally.

    And this patch also fixes the bug that ctl->free_space was subtracted
    without lock.

    Reported-by: Liu Bo
    Signed-off-by: Miao Xie
    Signed-off-by: Chris Mason

    Miao Xie
     
  • We don't use the defrag struct on this path.

    Signed-off-by: Dan Carpenter
    Signed-off-by: Chris Mason

    Dan Carpenter
     
  • We've stopped using highmem for extent buffers.

    Signed-off-by: Li Zefan
    Signed-off-by: Chris Mason

    Li Zefan
     
  • The filesystem turns readonly instead of returning the error to the
    caller when detected error in btrfs_drop_snapshot().
    and, because the caller doesn't check the error, the function type is
    changed to 'void'.

    Signed-off-by: Tsutomu Itoh
    Signed-off-by: Chris Mason

    Tsutomu Itoh
     
  • When checking if there is enough space for balancing a block group,
    since we do not take raid types into consideration, we do not account
    corrent amounts of space that we needed. This makes us do some extra
    work before we get ENOSPC.

    Signed-off-by: Liu Bo
    Signed-off-by: Chris Mason

    liubo
     
  • When balancing, we'll first try to shrink devices for some space,
    but if it is working on a full multi-disk partition with raid protection,
    we may encounter a bug, that is, while shrinking, total_bytes may be less
    than bytes_used, and btrfs may allocate a dev extent that accesses out of
    device's bounds.

    Then we will not be able to write or read the data which stores at the end
    of the device, and get the followings:

    device fsid 0939f071-7ea3-46c8-95df-f176d773bfb6 devid 1 transid 10 /dev/sdb5
    Btrfs detected SSD devices, enabling SSD mode
    btrfs: relocating block group 476315648 flags 9
    btrfs: found 4 extents
    attempt to access beyond end of device
    sdb5: rw=145, want=546176, limit=546147
    attempt to access beyond end of device
    sdb5: rw=145, want=546304, limit=546147
    attempt to access beyond end of device
    sdb5: rw=145, want=546432, limit=546147
    attempt to access beyond end of device
    sdb5: rw=145, want=546560, limit=546147
    attempt to access beyond end of device

    Signed-off-by: Liu Bo
    Signed-off-by: Chris Mason

    liubo
     
  • When btrfs recovers from a crash, it may hit the oops below:

    ------------[ cut here ]------------
    kernel BUG at fs/btrfs/inode.c:4580!
    [...]
    RIP: 0010:[] [] btrfs_add_link+0x161/0x1c0 [btrfs]
    [...]
    Call Trace:
    [] ? btrfs_inode_ref_index+0x31/0x80 [btrfs]
    [] add_inode_ref+0x319/0x3f0 [btrfs]
    [] replay_one_buffer+0x2c7/0x390 [btrfs]
    [] walk_down_log_tree+0x32a/0x480 [btrfs]
    [] walk_log_tree+0xf5/0x240 [btrfs]
    [] btrfs_recover_log_trees+0x250/0x350 [btrfs]
    [] ? btrfs_recover_log_trees+0x350/0x350 [btrfs]
    [] open_ctree+0x1442/0x17d0 [btrfs]
    [...]

    This comes from that while replaying an inode ref item, we forget to
    check those old conflicting DIR_ITEM and DIR_INDEX items in fs/file tree,
    then we will come to conflict corners which lead to BUG_ON().

    Signed-off-by: Liu Bo
    Tested-by: Andy Lutomirski
    Signed-off-by: Chris Mason

    liubo