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
This commit is contained in:
Linus Torvalds 2009-08-04 15:28:23 -07:00
commit 624720e09c
2 changed files with 18 additions and 2 deletions

View file

@ -412,8 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
return 0; /* Do not request flush for shadow page cache */
if (!sb) {
writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs);
if (!writer)
if (!writer) {
nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
return -EROFS;
}
sb = writer->s_super;
}

View file

@ -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);
}