Hi Andrea,
On Thu, 23 Jul 2009 23:02:47 +0200, Andrea Gelmini wrote:
> 2009/7/23 Ryusuke Konishi <[email protected]>:
> > It also suggests that an inconsistent state in page cache of B-tree
> > nodes hit the function; the function found a dirty page, but the page
> > didn't have buffer heads which was supposed to be impossible for the
> > b-tree of nilfs.
> 
> Well,
>    thanks for your quick reply.
>    Anyway, I can reproduce the same problem doing same things with
> stable kernel (2.6.29.6) and nilfs2-module from git repository.
>    I do this:
>    -> mkfs.nilfs2 -b 1024 /dev/mapper/VG-NilfHome (maybe the problem
> is the 1K block size?)
>    -> mount /dev/mapper/VG-NilfHome /tmp/test/
>    -> I run mirrordir (here's exactly as a "cp -a")
> 
>    It stucks at the same file as the crash before.
>    It's a 5G file, if it could help.

I found a bug which may cause the kernel oops you reported.
The bug can arise only if buffer size is smaller than page size.

Here I attach the patch that will hopefully fix this problem.

Could you test if the patch makes a difference for the same file ?

Regards,
Ryusuke Konishi
---
 fs/nilfs2/segment.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 8b5e477..51ff3d0 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1859,12 +1859,26 @@ static void nilfs_end_page_io(struct page *page, int 
err)
        if (!page)
                return;
 
-       if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page))
+       if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
                /*
                 * For b-tree node pages, this function may be called twice
                 * or more because they might be split in a segment.
                 */
+               if (PageDirty(page)) {
+                       /*
+                        * For pages holding split b-tree node buffers, dirty
+                        * flag on the buffers may be cleared discretely.
+                        * In that case, the page is once redirtied for
+                        * remaining buffers, and it must be cancelled if
+                        * all the buffers get cleaned later.
+                        */
+                       lock_page(page);
+                       if (nilfs_page_buffers_clean(page))
+                               __nilfs_clear_page_dirty(page);
+                       unlock_page(page);
+               }
                return;
+       }
 
        __nilfs_end_page_io(page, err);
 }
-- 
1.6.3.3

Attachment: nilfs2-fix-oops-due-to-inconsistent-page-state.patch.bz2
Description: Binary data

_______________________________________________
users mailing list
[email protected]
https://www.nilfs.org/mailman/listinfo/users

Reply via email to