07 Nov, 2011

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (114 commits)
    Btrfs: check for a null fs root when writing to the backup root log
    Btrfs: fix race during transaction joins
    Btrfs: fix a potential btrfs_bio leak on scrub fixups
    Btrfs: rename btrfs_bio multi -> bbio for consistency
    Btrfs: stop leaking btrfs_bios on readahead
    Btrfs: stop the readahead threads on failed mount
    Btrfs: fix extent_buffer leak in the metadata IO error handling
    Btrfs: fix the new inspection ioctls for 32 bit compat
    Btrfs: fix delayed insertion reservation
    Btrfs: ClearPageError during writepage and clean_tree_block
    Btrfs: be smarter about committing the transaction in reserve_metadata_bytes
    Btrfs: make a delayed_block_rsv for the delayed item insertion
    Btrfs: add a log of past tree roots
    btrfs: separate superblock items out of fs_info
    Btrfs: use the global reserve when truncating the free space cache inode
    Btrfs: release metadata from global reserve if we have to fallback for unlink
    Btrfs: make sure to flush queued bios if write_cache_pages waits
    Btrfs: fix extent pinning bugs in the tree log
    Btrfs: make sure btrfs_remove_free_space doesn't leak EAGAIN
    Btrfs: don't wait as long for more batches during SSD log commit
    ...

    Linus Torvalds
     

06 Nov, 2011

3 commits

  • fs_info has now ~9kb, more than fits into one page. This will cause
    mount failure when memory is too fragmented. Top space consumers are
    super block structures super_copy and super_for_commit, ~2.8kb each.
    Allocate them dynamically. fs_info will be ~3.5kb. (measured on x86_64)

    Add a wrapper for freeing fs_info and all of it's dynamically allocated
    members.

    Signed-off-by: David Sterba

    David Sterba
     
  • The tree log had two important bugs that could cause corruptions after a
    crash. Sometimes we were allowing tree log blocks to be reused after
    the tree log was committed but before the transaction commit was done.

    This allowed a future metadata write to overwrite the tree log data. It
    is fixed by adding a new variant of freeing reserved extents that always
    pins them. Credit goes to Stefan Behrens and Arne Jansen for many many
    hours spent tracking this bug down.

    During tree log replay, we do a pass through the tree log and pin all
    the extents we find. This makes sure the replay code won't go in and
    use any of those blocks for new allocations during replay. The problem
    is the free space cache isn't honoring these pinned extents. So the
    allocator can end up handing them out, leading to all kinds of problems
    during replay.

    The fix here is to force any free space cache to load while we pin the
    extents, and then to make sure we remove the pinned extents from the
    free space rbtree.

    Signed-off-by: Chris Mason
    Reported-by: Stefan Behrens

    Chris Mason
     
  • When we're doing log commits, we try to wait for more writers to come in
    and make the commit bigger. This helps improve performance on rotating
    disks, but on SSDs it adds latencies.

    Signed-off-by: Chris Mason

    Chris Mason
     

02 Nov, 2011

1 commit


17 Aug, 2011

1 commit

  • 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
     

02 Aug, 2011

1 commit


28 Jul, 2011

1 commit

  • The btrfs metadata btree is the source of significant
    lock contention, especially in the root node. This
    commit changes our locking to use a reader/writer
    lock.

    The lock is built on top of rw spinlocks, and it
    extends the lock tracking to remember if we have a
    read lock or a write lock when we go to blocking. Atomics
    count the number of blocking readers or writers at any
    given time.

    It removes all of the adaptive spinning from the old code
    and uses only the spinning/blocking hints inside of btrfs
    to decide when it should continue spinning.

    In read heavy workloads this is dramatically faster. In write
    heavy workloads we're still faster because of less contention
    on the root node lock.

    We suffer slightly in dbench because we schedule more often
    during write locks, but all other benchmarks so far are improved.

    Signed-off-by: Chris Mason

    Chris Mason
     

15 Jul, 2011

1 commit


18 Jun, 2011

1 commit


24 May, 2011

5 commits


23 May, 2011

3 commits

  • The current code relogs the entire inode every time during fsync log,
    and it is much better suited to small files rather than large ones.

    During my performance test, the fsync performace of large files sucks,
    and we can ascribe this to the tremendous amount of csum infos of the
    large ones, cause we have to flush all of these csum infos into log trees
    even when there are only _one_ change in the whole file data. Apparently,
    to optimize fsync, we need to create a filter to skip the unnecessary csum
    ones, that is, the corresponding file data remains unchanged before this fsync.

    Here I have some test results to show, I use sysbench to do "random write + fsync".

    ===
    sysbench --test=fileio --num-threads=1 --file-num=2 --file-block-size=4K --file-total-size=8G --file-test-mode=rndwr --file-io-mode=sync --file-extra-flags= [prepare, run]
    ===

    Sysbench args:
    - Number of threads: 1
    - Extra file open flags: 0
    - 2 files, 4Gb each
    - Block size 4Kb
    - Number of random requests for random IO: 10000
    - Read/Write ratio for combined random IO test: 1.50
    - Periodic FSYNC enabled, calling fsync() each 100 requests.
    - Calling fsync() at the end of test, Enabled.
    - Using synchronous I/O mode
    - Doing random write test

    Sysbench results:
    ===
    Operations performed: 0 Read, 10000 Write, 200 Other = 10200 Total
    Read 0b Written 39.062Mb Total transferred 39.062Mb
    ===
    a) without patch: (*SPEED* : 451.01Kb/sec)
    112.75 Requests/sec executed

    b) with patch: (*SPEED* : 4.7533Mb/sec)
    1216.84 Requests/sec executed

    PS: I've made a _sub transid_ stuff patch, but it does not perform as effectively as this patch,
    and I'm wanderring where the problem is and trying to improve it more.

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

    liubo
     
  • …trfs-unstable-arne into inode_numbers

    Conflicts:
    fs/btrfs/Makefile
    fs/btrfs/ctree.h
    fs/btrfs/volumes.h

    Signed-off-by: Chris Mason <chris.mason@oracle.com>

    Chris Mason
     
  • Conflicts:
    fs/btrfs/extent-tree.c
    fs/btrfs/free-space-cache.c
    fs/btrfs/inode.c
    fs/btrfs/tree-log.c

    Signed-off-by: Chris Mason

    Chris Mason
     

22 May, 2011

1 commit


21 May, 2011

2 commits

  • Changelog V5 -> V6:
    - Fix oom when the memory load is high, by storing the delayed nodes into the
    root's radix tree, and letting btrfs inodes go.

    Changelog V4 -> V5:
    - Fix the race on adding the delayed node to the inode, which is spotted by
    Chris Mason.
    - Merge Chris Mason's incremental patch into this patch.
    - Fix deadlock between readdir() and memory fault, which is reported by
    Itaru Kitayama.

    Changelog V3 -> V4:
    - Fix nested lock, which is reported by Itaru Kitayama, by updating space cache
    inode in time.

    Changelog V2 -> V3:
    - Fix the race between the delayed worker and the task which does delayed items
    balance, which is reported by Tsutomu Itoh.
    - Modify the patch address David Sterba's comment.
    - Fix the bug of the cpu recursion spinlock, reported by Chris Mason

    Changelog V1 -> V2:
    - break up the global rb-tree, use a list to manage the delayed nodes,
    which is created for every directory and file, and used to manage the
    delayed directory name index items and the delayed inode item.
    - introduce a worker to deal with the delayed nodes.

    Compare with Ext3/4, the performance of file creation and deletion on btrfs
    is very poor. the reason is that btrfs must do a lot of b+ tree insertions,
    such as inode item, directory name item, directory name index and so on.

    If we can do some delayed b+ tree insertion or deletion, we can improve the
    performance, so we made this patch which implemented delayed directory name
    index insertion/deletion and delayed inode update.

    Implementation:
    - introduce a delayed root object into the filesystem, that use two lists to
    manage the delayed nodes which are created for every file/directory.
    One is used to manage all the delayed nodes that have delayed items. And the
    other is used to manage the delayed nodes which is waiting to be dealt with
    by the work thread.
    - Every delayed node has two rb-tree, one is used to manage the directory name
    index which is going to be inserted into b+ tree, and the other is used to
    manage the directory name index which is going to be deleted from b+ tree.
    - introduce a worker to deal with the delayed operation. This worker is used
    to deal with the works of the delayed directory name index items insertion
    and deletion and the delayed inode update.
    When the delayed items is beyond the lower limit, we create works for some
    delayed nodes and insert them into the work queue of the worker, and then
    go back.
    When the delayed items is beyond the upper bound, we create works for all
    the delayed nodes that haven't been dealt with, and insert them into the work
    queue of the worker, and then wait for that the untreated items is below some
    threshold value.
    - When we want to insert a directory name index into b+ tree, we just add the
    information into the delayed inserting rb-tree.
    And then we check the number of the delayed items and do delayed items
    balance. (The balance policy is above.)
    - When we want to delete a directory name index from the b+ tree, we search it
    in the inserting rb-tree at first. If we look it up, just drop it. If not,
    add the key of it into the delayed deleting rb-tree.
    Similar to the delayed inserting rb-tree, we also check the number of the
    delayed items and do delayed items balance.
    (The same to inserting manipulation)
    - When we want to update the metadata of some inode, we cached the data of the
    inode into the delayed node. the worker will flush it into the b+ tree after
    dealing with the delayed insertion and deletion.
    - We will move the delayed node to the tail of the list after we access the
    delayed node, By this way, we can cache more delayed items and merge more
    inode updates.
    - If we want to commit transaction, we will deal with all the delayed node.
    - the delayed node will be freed when we free the btrfs inode.
    - Before we log the inode items, we commit all the directory name index items
    and the delayed inode update.

    I did a quick test by the benchmark tool[1] and found we can improve the
    performance of file creation by ~15%, and file deletion by ~20%.

    Before applying this patch:
    Create files:
    Total files: 50000
    Total time: 1.096108
    Average time: 0.000022
    Delete files:
    Total files: 50000
    Total time: 1.510403
    Average time: 0.000030

    After applying this patch:
    Create files:
    Total files: 50000
    Total time: 0.932899
    Average time: 0.000019
    Delete files:
    Total files: 50000
    Total time: 1.215732
    Average time: 0.000024

    [1] http://marc.info/?l=linux-btrfs&m=128212635122920&q=p3

    Many thanks for Kitayama-san's help!

    Signed-off-by: Miao Xie
    Reviewed-by: David Sterba
    Tested-by: Tsutomu Itoh
    Tested-by: Itaru Kitayama
    Signed-off-by: Chris Mason

    Miao Xie
     
  • Conflicts:
    fs/btrfs/free-space-cache.c

    Signed-off-by: Chris Mason

    Chris Mason
     

12 May, 2011

1 commit

  • This adds an initial implementation for scrub. It works quite
    straightforward. The usermode issues an ioctl for each device in the
    fs. For each device, it enumerates the allocated device chunks. For
    each chunk, the contained extents are enumerated and the data checksums
    fetched. The extents are read sequentially and the checksums verified.
    If an error occurs (checksum or EIO), a good copy is searched for. If
    one is found, the bad copy will be rewritten.
    All enumerations happen from the commit roots. During a transaction
    commit, the scrubs get paused and afterwards continue from the new
    roots.

    This commit is based on the series originally posted to linux-btrfs
    with some improvements that resulted from comments from David Sterba,
    Ilya Dryomov and Jan Schmidt.

    Signed-off-by: Arne Jansen

    Arne Jansen
     

02 May, 2011

2 commits


26 Apr, 2011

1 commit


25 Apr, 2011

1 commit

  • There's a potential problem in 32bit system when we exhaust 32bit inode
    numbers and start to allocate big inode numbers, because btrfs uses
    inode->i_ino in many places.

    So here we always use BTRFS_I(inode)->location.objectid, which is an
    u64 variable.

    There are 2 exceptions that BTRFS_I(inode)->location.objectid !=
    inode->i_ino: the btree inode (0 vs 1) and empty subvol dirs (256 vs 2),
    and inode->i_ino will be used in those cases.

    Another reason to make this change is I'm going to use a special inode
    to save free ino cache, and the inode number must be > (u64)-256.

    Signed-off-by: Li Zefan

    Li Zefan
     

28 Mar, 2011

2 commits

  • When we recover from crash via write-ahead log tree and process
    the inode refs, for each btrfs_inode_ref item, we will
    1) check if we already have a perfect match in fs/file tree, if
    we have, then we're done.
    2) search the corresponding back reference in fs/file tree, and
    check all the names in this back reference to see if they are
    also in the log to avoid conflict corners.
    3) recover the logged inode refs to fs/file tree.

    In current btrfs, however,
    - for 2)'s check, once is enough, since the checked back reference
    will remain unchanged after processing all the inode refs belonged
    to the key.
    - it has no need to do another 1) between 2) and 3).

    I've made a small test to show how it improves,

    $dd if=/dev/zero of=foobar bs=4K count=1
    $sync
    $make 100 hard links continuously, like ln foobar link_i
    $fsync foobar
    $echo b > /proc/sysrq-trigger
    after reboot
    $time mount DEV PATH

    without patch:
    real 0m0.285s
    user 0m0.001s
    sys 0m0.009s

    with patch:
    real 0m0.123s
    user 0m0.000s
    sys 0m0.010s

    Changelog v1->v2:
    - fix double free - pointed by David Sterba
    Changelog v2->v3:
    - adjust free order

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

    liubo
     
  • This patch changes some BUG_ON() to the error return.
    (but, most callers still use BUG_ON())

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

    Tsutomu Itoh
     

18 Mar, 2011

1 commit


01 Feb, 2011

3 commits


29 Jan, 2011

1 commit

  • To make btrfs more stable, add several missing necessary memory allocation
    checks, and when no memory, return proper errno.

    We've checked that some of those -ENOMEM errors will be returned to
    userspace, and some will be catched by BUG_ON() in the upper callers,
    and none will be ignored silently.

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

    liubo
     

22 Nov, 2010

1 commit

  • There are lots of places where we do dentry->d_parent->d_inode without holding
    the dentry->d_lock. This could cause problems with rename. So instead we need
    to use dget_parent() and hold the reference to the parent as long as we are
    going to use it's inode and then dput it at the end.

    Signed-off-by: Josef Bacik
    Cc: raven@themaw.net
    Signed-off-by: Chris Mason

    Josef Bacik
     

30 Oct, 2010

2 commits

  • These are all the cases where a variable is set, but not read which are
    not bugs as far as I can see, but simply leftovers.

    Still needs more review.

    Found by gcc 4.6's new warnings

    Signed-off-by: Andi Kleen
    Cc: Chris Mason
    Signed-off-by: Andrew Morton
    Signed-off-by: Chris Mason

    Andi Kleen
     
  • These are all the cases where a variable is set, but not
    read which are really bugs.

    - Couple of incorrect error handling fixed.
    - One incorrect use of a allocation policy
    - Some other things

    Still needs more review.

    Found by gcc 4.6's new warnings.

    [akpm@linux-foundation.org: fix build. Might have been bitrot]
    Signed-off-by: Andi Kleen
    Cc: Chris Mason
    Signed-off-by: Andrew Morton
    Signed-off-by: Chris Mason

    Andi Kleen
     

25 May, 2010

1 commit


30 Mar, 2010

1 commit

  • …it slab.h inclusion from percpu.h

    percpu.h is included by sched.h and module.h and thus ends up being
    included when building most .c files. percpu.h includes slab.h which
    in turn includes gfp.h making everything defined by the two files
    universally available and complicating inclusion dependencies.

    percpu.h -> slab.h dependency is about to be removed. Prepare for
    this change by updating users of gfp and slab facilities include those
    headers directly instead of assuming availability. As this conversion
    needs to touch large number of source files, the following script is
    used as the basis of conversion.

    http://userweb.kernel.org/~tj/misc/slabh-sweep.py

    The script does the followings.

    * Scan files for gfp and slab usages and update includes such that
    only the necessary includes are there. ie. if only gfp is used,
    gfp.h, if slab is used, slab.h.

    * When the script inserts a new include, it looks at the include
    blocks and try to put the new include such that its order conforms
    to its surrounding. It's put in the include block which contains
    core kernel includes, in the same order that the rest are ordered -
    alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
    doesn't seem to be any matching order.

    * If the script can't find a place to put a new include (mostly
    because the file doesn't have fitting include block), it prints out
    an error message indicating which .h file needs to be added to the
    file.

    The conversion was done in the following steps.

    1. The initial automatic conversion of all .c files updated slightly
    over 4000 files, deleting around 700 includes and adding ~480 gfp.h
    and ~3000 slab.h inclusions. The script emitted errors for ~400
    files.

    2. Each error was manually checked. Some didn't need the inclusion,
    some needed manual addition while adding it to implementation .h or
    embedding .c file was more appropriate for others. This step added
    inclusions to around 150 files.

    3. The script was run again and the output was compared to the edits
    from #2 to make sure no file was left behind.

    4. Several build tests were done and a couple of problems were fixed.
    e.g. lib/decompress_*.c used malloc/free() wrappers around slab
    APIs requiring slab.h to be added manually.

    5. The script was run on all .h files but without automatically
    editing them as sprinkling gfp.h and slab.h inclusions around .h
    files could easily lead to inclusion dependency hell. Most gfp.h
    inclusion directives were ignored as stuff from gfp.h was usually
    wildly available and often used in preprocessor macros. Each
    slab.h inclusion directive was examined and added manually as
    necessary.

    6. percpu.h was updated not to include slab.h.

    7. Build test were done on the following configurations and failures
    were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
    distributed build env didn't work with gcov compiles) and a few
    more options had to be turned off depending on archs to make things
    build (like ipr on powerpc/64 which failed due to missing writeq).

    * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
    * powerpc and powerpc64 SMP allmodconfig
    * sparc and sparc64 SMP allmodconfig
    * ia64 SMP allmodconfig
    * s390 SMP allmodconfig
    * alpha SMP allmodconfig
    * um on x86_64 SMP allmodconfig

    8. percpu.h modifications were reverted so that it could be applied as
    a separate patch and serve as bisection point.

    Given the fact that I had only a couple of failures from tests on step
    6, I'm fairly confident about the coverage of this conversion patch.
    If there is a breakage, it's likely to be something in one of the arch
    headers which should be easily discoverable easily on most builds of
    the specific arch.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>

    Tejun Heo
     

15 Mar, 2010

1 commit

  • This work is in preperation for being able to set a different root as the
    default mounting root.

    There is currently a problem with how we mount subvolumes. We cannot currently
    mount a subvolume of a subvolume, you can only mount subvolumes/snapshots of the
    default subvolume. So say you take a snapshot of the default subvolume and call
    it snap1, and then take a snapshot of snap1 and call it snap2, so now you have

    /
    /snap1
    /snap1/snap2

    as your available volumes. Currently you can only mount / and /snap1,
    you cannot mount /snap1/snap2. To fix this problem instead of passing
    subvolid= you must pass in subvolid=, where is
    the tree id that gets spit out via the subvolume listing you get from
    the subvolume listing patches (btrfs filesystem list). This allows us
    to mount /, /snap1 and /snap1/snap2 as the root volume.

    In addition to the above, we also now read the default dir item in the
    tree root to get the root key that it points to. For now this just
    points at what has always been the default subvolme, but later on I plan
    to change it to point at whatever root you want to be the new default
    root, so you can just set the default mount and not have to mount with
    -o subvolid=. I tested this out with the above scenario and it
    worked perfectly. Thanks,

    mount -o subvol operates inside the selected subvolid. For example:

    mount -o subvol=snap1,subvolid=256 /dev/xxx /mnt

    /mnt will have the snap1 directory for the subvolume with id
    256.

    mount -o subvol=snap /dev/xxx /mnt

    /mnt will be the snap directory of whatever the default subvolume
    is.

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

    Josef Bacik
     

18 Dec, 2009

1 commit

  • We do log replay in a single transaction, so it's not good to do unbound
    operations. This patch cleans up orphan inodes cleanup after replaying
    the log. It also avoids doing other unbound operations such as truncating
    a file during replaying log. These unbound operations are postponed to
    the orphan inode cleanup stage.

    Signed-off-by: Yan Zheng
    Signed-off-by: Chris Mason

    Yan, Zheng