diff options
Diffstat (limited to 'fs/nilfs2/inode.c')
-rw-r--r-- | fs/nilfs2/inode.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 689fb608648e..bccfec8343c5 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -219,13 +219,32 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) | |||
219 | 219 | ||
220 | static int nilfs_set_page_dirty(struct page *page) | 220 | static int nilfs_set_page_dirty(struct page *page) |
221 | { | 221 | { |
222 | int ret = __set_page_dirty_buffers(page); | 222 | int ret = __set_page_dirty_nobuffers(page); |
223 | 223 | ||
224 | if (ret) { | 224 | if (page_has_buffers(page)) { |
225 | struct inode *inode = page->mapping->host; | 225 | struct inode *inode = page->mapping->host; |
226 | unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); | 226 | unsigned nr_dirty = 0; |
227 | struct buffer_head *bh, *head; | ||
227 | 228 | ||
228 | nilfs_set_file_dirty(inode, nr_dirty); | 229 | /* |
230 | * This page is locked by callers, and no other thread | ||
231 | * concurrently marks its buffers dirty since they are | ||
232 | * only dirtied through routines in fs/buffer.c in | ||
233 | * which call sites of mark_buffer_dirty are protected | ||
234 | * by page lock. | ||
235 | */ | ||
236 | bh = head = page_buffers(page); | ||
237 | do { | ||
238 | /* Do not mark hole blocks dirty */ | ||
239 | if (buffer_dirty(bh) || !buffer_mapped(bh)) | ||
240 | continue; | ||
241 | |||
242 | set_buffer_dirty(bh); | ||
243 | nr_dirty++; | ||
244 | } while (bh = bh->b_this_page, bh != head); | ||
245 | |||
246 | if (nr_dirty) | ||
247 | nilfs_set_file_dirty(inode, nr_dirty); | ||
229 | } | 248 | } |
230 | return ret; | 249 | return ret; |
231 | } | 250 | } |