- Jul 30, 2009
-
-
Yan Zheng authored
The async block group caching code uses the commit_root pointer to get a stable version of the extent allocation tree for scanning. This copy of the tree root isn't going to change and it significantly reduces the complexity of the scanning code. During a commit, we have a loop where we update the extent allocation tree root. We need to loop because updating the root pointer in the tree of tree roots may allocate blocks which may change the extent allocation tree. Right now the commit_root pointer is changed inside this loop. It is more correct to change the commit_root pointer only after all the looping is done. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 28, 2009
-
-
Yan Zheng authored
- don't stop the caching thread until btrfs_commit_super return. - if caching is interrupted by umount, set last to (u64)-1. otherwise the un-scanned range of block group will be considered as free extent. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Josef Bacik authored
We are racy with async block caching and unpinning extents. This patch makes things much less complicated by only unpinning the extent if the block group is cached. We check the block_group->cached var under the block_group->lock spin lock. If it is set to BTRFS_CACHE_FINISHED then we update the pinned counters, and unpin the extent and add the free space back. If it is not set to this, we start the caching of the block group so the next time we unpin extents we can unpin the extent. This keeps us from racing with the async caching threads, lets us kill the fs wide async thread counter, and keeps us from having to set DELALLOC bits for every extent we hit if there are caching kthreads going. One thing that needed to be changed was btrfs_free_super_mirror_extents. Now instead of just looking for LOCKED extents, we also look for DIRTY extents, since we could have left some extents pinned in the previous transaction that will never get freed now that we are unmounting, which would cause us to leak memory. So btrfs_free_super_mirror_extents has been changed to btrfs_free_pinned_extents, and it will clear the extents locked for the super mirror, and any remaining pinned extents that may be present. Thank you, Signed-off-by:
Josef Bacik <jbacik@redhat.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Julia Lawall authored
dir has already been tested. It seems that this test should be on the recently returned value inode. A simplified version of the semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) Signed-off-by:
Julia Lawall <julia@diku.dk> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 25, 2009
-
-
Chris Mason authored
Allocating new block group is easy when the disk has plenty of space. But things get difficult as the disk fills up, especially if the FS has been run through btrfs-vol -b. The balance operation is likely to make the total bytes available on the device greater than the largest extent we'll actually be able to allocate. But the device extent allocation code incorrectly assumes that a device with 5G free will be able to allocate a 5G extent. It isn't normally a problem because device extents don't get freed unless btrfs-vol -b is run. This fixes the device extent allocator to remember the largest free extent it can find, and then uses that value as a fallback. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
Btrfs allocates individual extents from block groups, and each block group has a specific type. It may hold metadata, data mirrored or striped etc. When we balance space (btrfs-vol -b) or remove a drive (btrfs-vol -r) we free block groups. Once a block group is freed, the space it was using on the device may be available for use by new block groups. btrfs_remove_block_group was clearing the flag that said 'our devices are full, don't even try to allocate new block groups', but it was only clearing that flag for a specific type of block group. This commit clears the full flag for all of the types of block groups, making it much more likely that we'll be able to balance space when the drive is close to full. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Sage Weil authored
The commit_transaction call to wait_ordered_extents when snap_pending passes nocow_only=1 to process only NOCOW or PREALLOC extents. This isn't correct for the 'flushoncommit' mode, as it skips extents we just started IO on in start_delalloc_inodes. So, in the flushoncommit case, wait on all ordered extents. Otherwise, only pass the nocow_only flag to wait_ordered_extents if snap_pending. Signed-off-by:
Sage Weil <sage@newdream.net> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
btrfs_split_leaf and btrfs_del_items can end up in a loop where one is constantly spliting a given leaf and the other is constantly merging it back with the adjacent nodes. There is a better fix for this, but in the interest of something small, this patch just changes btrfs_del_items back to balancing less often. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 24, 2009
-
-
Yan Zheng authored
Check objectid of item before checking the item type, otherwise we may return zero for a key that is actually too low. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
find_free_dev_extent does not properly handle the case where the device is not complete free, and there is a free extent at the beginning of the device. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Diego Calleja authored
comp_keys is duplicating what is done in btrfs_comp_cpu_keys, so just call it. Signed-off-by:
Diego Calleja <diegocg@gmail.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Josef Bacik authored
This patch moves the caching of the block group off to a kthread in order to allow people to allocate sooner. Instead of blocking up behind the caching mutex, we instead kick of the caching kthread, and then attempt to make an allocation. If we cannot, we wait on the block groups caching waitqueue, which the caching kthread will wake the waiting threads up everytime it finds 2 meg worth of space, and then again when its finished caching. This is how I tested the speedup from this mkfs the disk mount the disk fill the disk up with fs_mark unmount the disk mount the disk time touch /mnt/foo Without my changes this took 11 seconds on my box, with these changes it now takes 1 second. Another change thats been put in place is we lock the super mirror's in the pinned extent map in order to keep us from adding that stuff as free space when caching the block group. This doesn't really change anything else as far as the pinned extent map is concerned, since for actual pinned extents we use EXTENT_DIRTY, but it does mean that when we unmount we have to go in and unlock those extents to keep from leaking memory. I've also added a check where when we are reading block groups from disk, if the amount of space used == the size of the block group, we go ahead and mark the block group as cached. This drastically reduces the amount of time it takes to cache the block groups. Using the same test as above, except doing a dd to a file and then unmounting, it used to take 33 seconds to umount, now it takes 3 seconds. This version uses the commit_root in the caching kthread, and then keeps track of how many async caching threads are running at any given time so if one of the async threads is still running as we cross transactions we can wait until its finished before handling the pinned extents. Thank you, Signed-off-by:
Josef Bacik <jbacik@redhat.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Josef Bacik authored
Currently btrfs has a problem where it can use a ridiculous amount of RAM simply tracking free space. As free space gets fragmented, we end up with thousands of entries on an rb-tree per block group, which usually spans 1 gig of area. Since we currently don't ever flush free space cache back to disk this gets to be a bit unweildly on large fs's with lots of fragmentation. This patch solves this problem by using PAGE_SIZE bitmaps for parts of the free space cache. Initially we calculate a threshold of extent entries we can handle, which is however many extent entries we can cram into 16k of ram. The maximum amount of RAM that should ever be used to track 1 gigabyte of diskspace will be 32k of RAM, which scales much better than we did before. Once we pass the extent threshold, we start adding bitmaps and using those instead for tracking the free space. This patch also makes it so that any free space thats less than 4 * sectorsize we go ahead and put into a bitmap. This is nice since we try and allocate out of the front of a block group, so if the front of a block group is heavily fragmented and then has a huge chunk of free space at the end, we go ahead and add the fragmented areas to bitmaps and use a normal extent entry to track the big chunk at the back of the block group. I've also taken the opportunity to revamp how we search for free space. Previously we indexed free space via an offset indexed rb tree and a bytes indexed rb tree. I've dropped the bytes indexed rb tree and use only the offset indexed rb tree. This cuts the number of tree operations we were doing previously down by half, and gives us a little bit of a better allocation pattern since we will always start from a specific offset and search forward from there, instead of searching for the size we need and try and get it as close as possible to the offset we want. I've given this a healthy amount of testing pre-new format stuff, as well as post-new format stuff. I've booted up my fedora box which is installed on btrfs with this patch and ran with it for a few days without issues. I've not seen any performance regressions in any of my tests. Since the last patch Yan Zheng fixed a problem where we could have overlapping entries, so updating their offset inline would cause problems. Thanks, Signed-off-by:
Josef Bacik <jbacik@redhat.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 23, 2009
-
-
David Woodhouse authored
If the tree roots hit read errors during mount, btrfs is not properly erroring out. We need to check the uptodate bits after reading in the tree root node. Signed-off-by:
David Woodhouse <David.Woodhouse@intel.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Daniel Cadete authored
This removes the continues call's of btrfs_header_level. One call of btrfs_header_level(c) its enough. Signed-off-by Daniel Cadete <danielncadete10@gmail.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Julia Lawall authored
Move the call to BUG_ON to before the dereference of the tested value. Signed-off-by:
Julia Lawall <julia@diku.dk> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
David Woodhouse authored
It was never actually doing anything anyway (see the loop condition), and it would be difficult to make it work for RAID[56]. Even if it was actually working, it's checking for the wrong thing anyway. Instead of checking whether we list a block which _doesn't_ land at the relevant physical location, it should be checking that we _have_ listed all the logical blocks which refer to the required physical location on all devices. This function is only called from remove_sb_from_cache() to ensure that we reserve the logical blocks which would reside at the same physical location as the superblock copies. So listing more blocks than we need is actually OK. With RAID[56] we're going to throw away an entire stripe for each block we have to ignore, so we _are_ going to list blocks other than the ones which actually contain the superblock. Signed-off-by:
David Woodhouse <David.Woodhouse@intel.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Julia Lawall authored
If spin_lock_irqsave is called twice in a row with the same second argument, the interrupt state at the point of the second call overwrites the value saved by the first call. Indeed, the second call does not need to save the interrupt state, so it is changed to a simple spin_lock. Signed-off-by:
Julia Lawall <julia@diku.dk> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 22, 2009
-
-
Yan Zheng authored
Write dirty block groups may allocate new block, and so may add new delayed back ref. btrfs_run_delayed_refs may make some block groups dirty. commit_cowonly_roots does not handle the recursion properly, and some dirty blocks can be left unwritten at commit time. This patch moves btrfs_run_delayed_refs into the loop that writes dirty block groups, and makes the code not break out of the loop until there are no dirty block groups or delayed back refs. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
When walking up the tree, btrfs_find_next_key assumes the upper level tree block is properly locked. This isn't always true even path->keep_locks is 1. This is because btrfs_find_next_key may advance path->slots[] several times instead of only once. When 'path->slots[level] >= btrfs_header_nritems(path->nodes[level])' is found, we can't guarantee the original value of 'path->slots[level]' is 'btrfs_header_nritems(path->nodes[level]) - 1'. If it's not, the tree block at 'level + 1' isn't locked. This patch fixes the issue by explicitly checking the locking state, re-searching the tree if it's not locked. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
if 1 is returned by btrfs_search_slot, the path already points to the first item with 'key > searching key'. So increasing path->slots[0] by one is superfluous in that case. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
Change 'goto done' to 'break' for the case of all device extents have been freed, so that the code updates space information will be execute. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
use __le64 instead of u64 in on-disk structure definition. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jul 03, 2009
-
-
Hu Tao authored
Make an error msg look nicer by inserting a space between number and word. Signed-off-by:
Hu Tao <hu.taoo@gmail.com> Signed-off-by:
Jiri Kosina <jkosina@suse.cz> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Jiri Slaby authored
worker memory is already freed on one fail path in btrfs_start_workers, but is still dereferenced. Switch the dereference and kfree. Signed-off-by:
Jiri Slaby <jirislaby@gmail.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
The btrfs attr patches unconditionally inherited the inode flags field without honoring nodatacow and nodatasum. This fix makes sure we properly record the nodatacow/sum mount options in new inodes. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
The new backref format has restriction on type of backref item. If a tree block isn't referenced by its owner tree, full backrefs must be used for the pointers in it. When a tree block loses its owner tree's reference, backrefs for the pointers in it should be updated to full backrefs. Current btrfs_drop_snapshot misses the code that updates backrefs, so it's unsafe for general use. This patch adds backrefs update code to btrfs_drop_snapshot. It isn't a problem in the restricted form btrfs_drop_snapshot is used today, but for general snapshot deletion this update is required. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Josef Bacik authored
Using Eric Sandeen's xfstest for fallocate, you can easily trigger a ENOSPC panic on btrfs. This is because we do not account for data we may use when doing the fallocate. This patch fixes the problem by properly reserving space, and then just freeing it when we are done. The reservation stuff was made with delalloc in mind, so its a little crude for this case, but it keeps the box from panicing. Signed-off-by:
Josef Bacik <jbacik@redhat.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
-
Chris Mason authored
-
- Jun 16, 2009
-
-
Yan Zheng authored
commit_fs_roots skips updating root items for fs trees that aren't modified. This is unsafe now that relocation code modifies root item's last_snapshot field without modifying corresponding fs tree. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jun 11, 2009
-
-
Chris Mason authored
During tree log replay, we read in the tree log roots, process them and then free them. A recent change takes an extra reference on the root node of the tree when the root is read in, and stores that reference in root->commit_root. This reference was not being freed, leaving us with one buffer pinned in ram for each subvol with a tree log root after a crash. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
This happens during subvol creation. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
It was printing nodatacsum, which was not the correct option name. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Yan Zheng authored
lookup_inline_extent_backref only checks for duplicate backref for data extents. It assumes backrefs for tree block never conflict. This patch makes lookup_inline_extent_backref check for duplicate backrefs for both data and tree block, so that we can detect potential bug earlier. This is a safety check, strictly speaking it is not required. Signed-off-by:
Yan Zheng <zheng.yan@oracle.com> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Shin Hong authored
This patch fixes a bug which may result race condition between btrfs_start_workers() and worker_loop(). btrfs_start_workers() executed in a parent thread writes on workers->worker and worker_loop() in a child thread reads workers->worker. However, there is no synchronization enforcing the order of two operations. This patch makes btrfs_start_workers() fill workers->worker before it starts a child thread with worker_loop() Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Hisashi Hifumi authored
write_dev_supers is called in sequence. First is it called with wait == 0, which starts IO on all of the super blocks for a given device. Then it is called with wait == 1 to make sure they all reach the disk. It doesn't currently pin the buffers between the two calls, and it also assumes the buffers won't go away between the two calls, leading to an oops if the VM manages to free the buffers in the middle of the sync. This fixes that assumption and updates the code to return an error if things are not up to date when the wait == 1 run is done. Signed-off-by:
Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Chris Mason authored
On multi-device filesystems, btrfs writes supers to all of the devices before considering a sync complete. There wasn't any additional locking between super writeout and the device list management code because device management was done inside a transaction and super writeout only happened with no transation writers running. With the btrfs fsync log and other async transaction updates, this has been racey for some time. This adds a mutex to protect the device list. The existing volume mutex could not be reused due to transaction lock ordering requirements. Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
- Jun 10, 2009
-
-
Al Viro authored
... otherwise generic_permission() will allow *anything* for all files you don't own and that have some group permissions. Signed-off-by:
Al Viro <viro@zeniv.linux.org.uk> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-
Hisashi Hifumi authored
In btrfs, fdatasync and fsync are identical, but fdatasync should skip committing transaction when inode->i_state is set just I_DIRTY_SYNC and this indicates only atime or/and mtime updates. Following patch improves fdatasync throughput. --file-block-size=4K --file-total-size=16G --file-test-mode=rndwr --file-fsync-mode=fdatasync run Results: -2.6.30-rc8 Test execution summary: total time: 1980.6540s total number of events: 10001 total time taken by event execution: 1192.9804 per-request statistics: min: 0.0000s avg: 0.1193s max: 15.3720s approx. 95 percentile: 0.7257s Threads fairness: events (avg/stddev): 625.0625/151.32 execution time (avg/stddev): 74.5613/9.46 -2.6.30-rc8-patched Test execution summary: total time: 1695.9118s total number of events: 10000 total time taken by event execution: 871.3214 per-request statistics: min: 0.0000s avg: 0.0871s max: 10.4644s approx. 95 percentile: 0.4787s Threads fairness: events (avg/stddev): 625.0000/131.86 execution time (avg/stddev): 54.4576/8.98 Signed-off-by:
Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp> Signed-off-by:
Chris Mason <chris.mason@oracle.com>
-