[PATCH 2/2] btrfs: fix oops when leafsize is greator than nodesize
oops occured when we ran the following commands on the filesystem whose leafsize is greater than its nodesize. # mkfs.btrfs -l 8192 /dev/sda1 2 * PAGESIZE # mount /dev/sda1 /mnt # cat /dev/zero /mnt/tmp_file0 # umount /mnt Oops occured. (Sometimes we must do the loop of mount/umount several times to hit this bug) Oops infomation: [ cut here ] WARNING: at fs/btrfs/extent_io.c:3685 copy_extent_buffer+0x48/0x192() Hardware name: FF Modules linked in: [snip] Pid: 3743, comm: umount Not tainted 2.6.35-rc4 #22 Call Trace: [8103782e] warn_slowpath_common+0x80/0x98 [8103785b] warn_slowpath_null+0x15/0x17 [811713a3] copy_extent_buffer+0x48/0x192 [81140488] __btrfs_cow_block+0x16f/0x559 [81140ee7] btrfs_cow_block+0x189/0x1a6 [81157cf0] commit_cowonly_roots+0x54/0x193 [811587d5] btrfs_commit_transaction+0x380/0x610 [81050a67] ? autoremove_wake_function+0x0/0x34 [811554bf] btrfs_commit_super+0xa2/0xc3 [8115551a] close_ctree+0x3a/0x330 [810545e8] ? up_write+0x1e/0x36 [810f4818] ? invalidate_inodes+0x120/0x132 [8113b233] btrfs_put_super+0x18/0x27 [810e395c] generic_shutdown_super+0x51/0xd2 [810e3a28] kill_anon_super+0x11/0x4f [810e2af8] deactivate_locked_super+0x21/0x41 [810e2cd0] deactivate_super+0x40/0x44 [810f7a4b] mntput_no_expire+0xb8/0xe5 [810f7fea] sys_umount+0x2c8/0x2f3 [8106062a] ? trace_hardirqs_on_caller+0x10c/0x130 [81001f2b] system_call_fastpath+0x16/0x1b ---[ end trace 5f7f4dbc8bcadbc3 ]--- The reason is that: In order to reuse the extent buffer, the btrfs doesn't release the extent buffer, When the btrfs releases its device space. So if the btrfs allocates the device space that has been released just now, the btrfs will get the old extent buffer mapping to the device space. But if the length of the new space is greator than the old extent buffer, a BUG() will be touched. The patch fixes this problem by change the length of the old extent buffer. Signed-off-by: Miao Xie mi...@cn.fujitsu.com --- fs/btrfs/extent_io.c | 90 +++-- 1 files changed, 86 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 70b7cc5..b4f1c42 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3130,6 +3130,45 @@ static inline void btrfs_release_extent_buffer(struct extent_buffer *eb) __free_extent_buffer(eb); } +/* + * we may reuse a extent buffer whose device space has been released, if the len + * of the extent buffer is smaller than we expect, we must enlarge the extent + * buffer, and before doing that, we must release the extent buffer that + * intersects it. + * + * Don't worry about the state of the extent buffer that is going to be release. + * because it is just an image left in the memory, and its device space has been + * released, or the btrfs can't allocate its device space for other extent + * buffer. + * + * Note: Must hold io_tree-buffer_lock + */ +static int btrfs_enlarge_extent_buffer(struct extent_io_tree *tree, + struct extent_buffer *eb, + unsigned long newlen) +{ + struct rb_node *next; + struct extent_buffer *next_eb; + + eb-len = newlen; + set_page_extent_head(eb-first_page, newlen); + + next = rb_next(eb-rb_node); + while (next) { + next_eb = rb_entry(next, struct extent_buffer, rb_node); + if (next_eb-start = eb-start + eb-len) + break; + + if (atomic_read(next_eb-refs) 1) + return 1; + + next = rb_next(next); + rb_erase(next_eb-rb_node, tree-buffer); + btrfs_release_extent_buffer(next_eb); + } + return 0; +} + struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, u64 start, unsigned long len, struct page *page0, @@ -3147,10 +3186,49 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, spin_lock(tree-buffer_lock); eb = buffer_search(tree, start); if (eb) { - atomic_inc(eb-refs); - spin_unlock(tree-buffer_lock); - mark_page_accessed(eb-first_page); - return eb; + /* +* If this extent buffer's device space has been released some +* time ago, and is reallocated again to store other metadata, +* but it hasn't been release, we may get the old entent buffer +* and reuse it. +* +* But, we must change it according the new len. +*/ + if (eb-len = len) { +
[PATCH 1/2] btrfs: restructure try_release_extent_buffer()
restructure try_release_extent_buffer() and write a function to release the extent buffer. It will be used later. Signed-off-by: Miao Xie mi...@cn.fujitsu.com --- fs/btrfs/extent_io.c | 48 +--- 1 files changed, 37 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 41277d6..70b7cc5 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3097,6 +3097,39 @@ static void __free_extent_buffer(struct extent_buffer *eb) kmem_cache_free(extent_buffer_cache, eb); } +/* + * Helper for releasing extent buffer page. + */ +static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, + unsigned long start_idx) +{ + unsigned long index; + struct page *page; + + if (!eb-first_page) + return; + + index = num_extent_pages(eb-start, eb-len); + if (start_idx = index) + return; + + do { + index--; + page = extent_buffer_page(eb, index); + if (page) + page_cache_release(page); + } while (index != start_idx); +} + +/* + * Helper for releasing the extent buffer. + */ +static inline void btrfs_release_extent_buffer(struct extent_buffer *eb) +{ + btrfs_release_extent_buffer_page(eb, 0); + __free_extent_buffer(eb); +} + struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, u64 start, unsigned long len, struct page *page0, @@ -3174,10 +3207,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, free_eb: if (!atomic_dec_and_test(eb-refs)) return exists; - for (index = 1; index i; index++) - page_cache_release(extent_buffer_page(eb, index)); - page_cache_release(extent_buffer_page(eb, 0)); - __free_extent_buffer(eb); + btrfs_release_extent_buffer(eb); return exists; } @@ -3831,8 +3861,6 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page) u64 start = page_offset(page); struct extent_buffer *eb; int ret = 1; - unsigned long i; - unsigned long num_pages; spin_lock(tree-buffer_lock); eb = buffer_search(tree, start); @@ -3847,12 +3875,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page) ret = 0; goto out; } - /* at this point we can safely release the extent buffer */ - num_pages = num_extent_pages(eb-start, eb-len); - for (i = 0; i num_pages; i++) - page_cache_release(extent_buffer_page(eb, i)); + rb_erase(eb-rb_node, tree-buffer); - __free_extent_buffer(eb); + /* at this point we can safely release the extent buffer */ + btrfs_release_extent_buffer(eb); out: spin_unlock(tree-buffer_lock); return ret; -- 1.7.0.1 -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] btrfs-progs: fix wrong extent buffer size when reading tree block
the root extent buffer of a tree may not be a leaf, so we must get the right size by its level when reading it. Signed-off-by: Miao Xie mi...@cn.fujitsu.com --- debug-tree.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/debug-tree.c b/debug-tree.c index 40628e0..cf637ab 100644 --- a/debug-tree.c +++ b/debug-tree.c @@ -208,7 +208,9 @@ again: read_extent_buffer(leaf, ri, offset, sizeof(ri)); buf = read_tree_block(tree_root_scan, btrfs_root_bytenr(ri), - tree_root_scan-leafsize, 0); + btrfs_level_size(tree_root_scan, + btrfs_root_level(ri)), + 0); switch(found_key.objectid) { case BTRFS_ROOT_TREE_OBJECTID: if (!skip) -- 1.7.0.1 -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: slow deletion of files
Clemens Eisserer wrote (ao): Another reason I moved away was btrfs corrupted, and btrfsck is still not able to repair it. I really like btrfs but in my opinion it has still a long road to go and declaring it stable in 2.6.35 is quite optimistic at best. Please allow me to report in favor of btrfs. I use btrfs since February 2009 on my workstation, since September 2009 on my home server, and since December 2009 on several ARM computers. Recently I've started to use btrfs on production servers. Btrfs has not let me down yet. I do make hourly incremental backups and keep a close eye on the btrfs mailinglist though. Sander -- Humilis IT Services and Solutions http://www.humilis.net -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kernel BUG at fs/btrfs/extent-tree.c:1353
Am Sonntag 11 Juli 2010, 14:28:09 schrieb Johannes Hirte: ... I've three systems running with btrfs, a dual Opteron (252), a Pentium 4 system and a netbook with N270 Atom. The netbook is the only one that shows the errors. It's also the only system where I'm using gcc-4.5. Perhaps it's related, but I doubt it's the only reason as I'm using gcc-4.5 since May. On the Opteron system I got now csum errors. I've synced some data from the netbook to the Opteron yesteray. After hitting ENOSPC with 4GB free, I've run 'btrfs-vol -b' on this fs in hope to get some more free space. It worked but the command failed and I found in dmesg: btrfs csum failed ino 339 off 935280640 csum 337776576 private 337776575 btrfs csum failed ino 339 off 935280640 csum 337776576 private 337776575 btrfs csum failed ino 339 off 935280640 csum 337776576 private 337776575 btrfs csum failed ino 339 off 935280640 csum 337776576 private 337776575 So I've tested the new synced data by syncing them to another disk on the Optoern system (XFS). As I've expected (or better feared), some data wasn't readable and I found more csum errors in dmesg: btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1849137 off 368640 csum 3354885689 private 3354885688 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1912210 off 5095424 csum 847944548 private 847944547 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 252362752 csum 686735346 private 686735345 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 651108352 csum 2851505977 private 2851505976 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 btrfs csum failed ino 1959333 off 898342912 csum 4271223884 private 4271223883 I suspect something goes horribly wrong on writing to disc within btrfs. On the netbook I got missing blocks, on the Opteron System bad csums. Both systems are running linux-2.6.35-rc4, the netbook with gcc-4.5.0 the Opteron system with gcc-4.4.4. I'll test the P4 system later, if there are similar errors too. regards, Johannes -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Removing snapshots
On ubuntu-10.04, the standard package for btrfs-tools is 0.19-8. This version apparently lacks the -D option to btrfsctl. In this configuration, how do I remove snapshots? --rich -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Removing snapshots
On Tue, Jul 13, 2010 at 3:58 PM, K. Richard Pixley r...@noir.com wrote: On ubuntu-10.04, the standard package for btrfs-tools is 0.19-8. This version apparently lacks the -D option to btrfsctl. In this configuration, how do I remove snapshots? I'm not sure you can. However the btrfs tools from this address compile and run well on Ubuntu 10.04: https://btrfs.wiki.kernel.org/index.php/Btrfs_source_repositories Cheers, =a= -- === Aaron Straus aa...@merfinllc.com -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html