[PATCH 2/2] btrfs: fix oops when leafsize is greator than nodesize

2010-07-13 Thread Miao Xie

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()

2010-07-13 Thread Miao Xie

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

2010-07-13 Thread Miao Xie
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

2010-07-13 Thread Sander
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

2010-07-13 Thread Johannes Hirte
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

2010-07-13 Thread K. Richard Pixley
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

2010-07-13 Thread Aaron Straus
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