diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-04 18:28:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-04 18:28:23 -0400 |
commit | 624720e09c9b7913ef4bc6989878a6fcb7ecdff8 (patch) | |
tree | be36dc1fc45a4cf5d5100ca5252e6aa3b465fbe2 | |
parent | 849c9caa60642095060e9c21f14687ae9149a6f3 (diff) | |
parent | 01a261e09a21e0ba342d3907a79cf5c78ee3f37a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
nilfs2: fix missing unlock in error path of nilfs_mdt_write_page
nilfs2: fix oops due to inconsistent state in page with discrete b-tree nodes
-rw-r--r-- | fs/nilfs2/mdt.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 16 |
2 files changed, 18 insertions, 2 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 3d3ddb3f5177..2dfd47714ae5 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -412,8 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
412 | return 0; /* Do not request flush for shadow page cache */ | 412 | return 0; /* Do not request flush for shadow page cache */ |
413 | if (!sb) { | 413 | if (!sb) { |
414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); |
415 | if (!writer) | 415 | if (!writer) { |
416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | ||
416 | return -EROFS; | 417 | return -EROFS; |
418 | } | ||
417 | sb = writer->s_super; | 419 | sb = writer->s_super; |
418 | } | 420 | } |
419 | 421 | ||
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 8b5e4778cf28..51ff3d0a4ee2 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) | |||
1859 | if (!page) | 1859 | if (!page) |
1860 | return; | 1860 | return; |
1861 | 1861 | ||
1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) { |
1863 | /* | 1863 | /* |
1864 | * For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
1865 | * or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
1866 | */ | 1866 | */ |
1867 | if (PageDirty(page)) { | ||
1868 | /* | ||
1869 | * For pages holding split b-tree node buffers, dirty | ||
1870 | * flag on the buffers may be cleared discretely. | ||
1871 | * In that case, the page is once redirtied for | ||
1872 | * remaining buffers, and it must be cancelled if | ||
1873 | * all the buffers get cleaned later. | ||
1874 | */ | ||
1875 | lock_page(page); | ||
1876 | if (nilfs_page_buffers_clean(page)) | ||
1877 | __nilfs_clear_page_dirty(page); | ||
1878 | unlock_page(page); | ||
1879 | } | ||
1867 | return; | 1880 | return; |
1881 | } | ||
1868 | 1882 | ||
1869 | __nilfs_end_page_io(page, err); | 1883 | __nilfs_end_page_io(page, err); |
1870 | } | 1884 | } |