summaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/inode.c17
-rw-r--r--fs/nilfs2/mdt.c19
-rw-r--r--fs/nilfs2/page.c70
-rw-r--r--fs/nilfs2/page.h3
4 files changed, 86 insertions, 23 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 6b49f14eac8c..ba7a1da7634b 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -175,6 +175,11 @@ static int nilfs_writepages(struct address_space *mapping,
175 struct inode *inode = mapping->host; 175 struct inode *inode = mapping->host;
176 int err = 0; 176 int err = 0;
177 177
178 if (inode->i_sb->s_flags & MS_RDONLY) {
179 nilfs_clear_dirty_pages(mapping, false);
180 return -EROFS;
181 }
182
178 if (wbc->sync_mode == WB_SYNC_ALL) 183 if (wbc->sync_mode == WB_SYNC_ALL)
179 err = nilfs_construct_dsync_segment(inode->i_sb, inode, 184 err = nilfs_construct_dsync_segment(inode->i_sb, inode,
180 wbc->range_start, 185 wbc->range_start,
@@ -187,6 +192,18 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
187 struct inode *inode = page->mapping->host; 192 struct inode *inode = page->mapping->host;
188 int err; 193 int err;
189 194
195 if (inode && (inode->i_sb->s_flags & MS_RDONLY)) {
196 /*
197 * It means that filesystem was remounted in read-only
198 * mode because of error or metadata corruption. But we
199 * have dirty pages that try to be flushed in background.
200 * So, here we simply discard this dirty page.
201 */
202 nilfs_clear_dirty_page(page, false);
203 unlock_page(page);
204 return -EROFS;
205 }
206
190 redirty_page_for_writepage(wbc, page); 207 redirty_page_for_writepage(wbc, page);
191 unlock_page(page); 208 unlock_page(page);
192 209
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index f9897d09c693..c4dcd1db57ee 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -375,14 +375,25 @@ int nilfs_mdt_fetch_dirty(struct inode *inode)
375static int 375static int
376nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) 376nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
377{ 377{
378 struct inode *inode; 378 struct inode *inode = page->mapping->host;
379 struct super_block *sb; 379 struct super_block *sb;
380 int err = 0; 380 int err = 0;
381 381
382 if (inode && (inode->i_sb->s_flags & MS_RDONLY)) {
383 /*
384 * It means that filesystem was remounted in read-only
385 * mode because of error or metadata corruption. But we
386 * have dirty pages that try to be flushed in background.
387 * So, here we simply discard this dirty page.
388 */
389 nilfs_clear_dirty_page(page, false);
390 unlock_page(page);
391 return -EROFS;
392 }
393
382 redirty_page_for_writepage(wbc, page); 394 redirty_page_for_writepage(wbc, page);
383 unlock_page(page); 395 unlock_page(page);
384 396
385 inode = page->mapping->host;
386 if (!inode) 397 if (!inode)
387 return 0; 398 return 0;
388 399
@@ -561,10 +572,10 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode)
561 if (mi->mi_palloc_cache) 572 if (mi->mi_palloc_cache)
562 nilfs_palloc_clear_cache(inode); 573 nilfs_palloc_clear_cache(inode);
563 574
564 nilfs_clear_dirty_pages(inode->i_mapping); 575 nilfs_clear_dirty_pages(inode->i_mapping, true);
565 nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data); 576 nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data);
566 577
567 nilfs_clear_dirty_pages(&ii->i_btnode_cache); 578 nilfs_clear_dirty_pages(&ii->i_btnode_cache, true);
568 nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes); 579 nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes);
569 580
570 nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store); 581 nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 07f76db04ec7..131a5841a070 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -370,7 +370,12 @@ repeat:
370 goto repeat; 370 goto repeat;
371} 371}
372 372
373void nilfs_clear_dirty_pages(struct address_space *mapping) 373/**
374 * nilfs_clear_dirty_pages - discard dirty pages in address space
375 * @mapping: address space with dirty pages for discarding
376 * @silent: suppress [true] or print [false] warning messages
377 */
378void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
374{ 379{
375 struct pagevec pvec; 380 struct pagevec pvec;
376 unsigned int i; 381 unsigned int i;
@@ -382,25 +387,9 @@ void nilfs_clear_dirty_pages(struct address_space *mapping)
382 PAGEVEC_SIZE)) { 387 PAGEVEC_SIZE)) {
383 for (i = 0; i < pagevec_count(&pvec); i++) { 388 for (i = 0; i < pagevec_count(&pvec); i++) {
384 struct page *page = pvec.pages[i]; 389 struct page *page = pvec.pages[i];
385 struct buffer_head *bh, *head;
386 390
387 lock_page(page); 391 lock_page(page);
388 ClearPageUptodate(page); 392 nilfs_clear_dirty_page(page, silent);
389 ClearPageMappedToDisk(page);
390 bh = head = page_buffers(page);
391 do {
392 lock_buffer(bh);
393 clear_buffer_dirty(bh);
394 clear_buffer_nilfs_volatile(bh);
395 clear_buffer_nilfs_checked(bh);
396 clear_buffer_nilfs_redirected(bh);
397 clear_buffer_uptodate(bh);
398 clear_buffer_mapped(bh);
399 unlock_buffer(bh);
400 bh = bh->b_this_page;
401 } while (bh != head);
402
403 __nilfs_clear_page_dirty(page);
404 unlock_page(page); 393 unlock_page(page);
405 } 394 }
406 pagevec_release(&pvec); 395 pagevec_release(&pvec);
@@ -408,6 +397,51 @@ void nilfs_clear_dirty_pages(struct address_space *mapping)
408 } 397 }
409} 398}
410 399
400/**
401 * nilfs_clear_dirty_page - discard dirty page
402 * @page: dirty page that will be discarded
403 * @silent: suppress [true] or print [false] warning messages
404 */
405void nilfs_clear_dirty_page(struct page *page, bool silent)
406{
407 struct inode *inode = page->mapping->host;
408 struct super_block *sb = inode->i_sb;
409
410 BUG_ON(!test_bit(PG_locked, &page->flags));
411
412 if (!silent) {
413 nilfs_warning(sb, __func__,
414 "discard page: offset %lld, ino %lu",
415 page_offset(page), inode->i_ino);
416 }
417
418 ClearPageUptodate(page);
419 ClearPageMappedToDisk(page);
420
421 if (page_has_buffers(page)) {
422 struct buffer_head *bh, *head;
423
424 bh = head = page_buffers(page);
425 do {
426 lock_buffer(bh);
427 if (!silent) {
428 nilfs_warning(sb, __func__,
429 "discard block %llu, size %zu",
430 (u64)bh->b_blocknr, bh->b_size);
431 }
432 clear_buffer_dirty(bh);
433 clear_buffer_nilfs_volatile(bh);
434 clear_buffer_nilfs_checked(bh);
435 clear_buffer_nilfs_redirected(bh);
436 clear_buffer_uptodate(bh);
437 clear_buffer_mapped(bh);
438 unlock_buffer(bh);
439 } while (bh = bh->b_this_page, bh != head);
440 }
441
442 __nilfs_clear_page_dirty(page);
443}
444
411unsigned nilfs_page_count_clean_buffers(struct page *page, 445unsigned nilfs_page_count_clean_buffers(struct page *page,
412 unsigned from, unsigned to) 446 unsigned from, unsigned to)
413{ 447{
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
index fb7de71605a0..ef30c5c2426f 100644
--- a/fs/nilfs2/page.h
+++ b/fs/nilfs2/page.h
@@ -55,7 +55,8 @@ void nilfs_page_bug(struct page *);
55 55
56int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); 56int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
57void nilfs_copy_back_pages(struct address_space *, struct address_space *); 57void nilfs_copy_back_pages(struct address_space *, struct address_space *);
58void nilfs_clear_dirty_pages(struct address_space *); 58void nilfs_clear_dirty_page(struct page *, bool);
59void nilfs_clear_dirty_pages(struct address_space *, bool);
59void nilfs_mapping_init(struct address_space *mapping, struct inode *inode, 60void nilfs_mapping_init(struct address_space *mapping, struct inode *inode,
60 struct backing_dev_info *bdi); 61 struct backing_dev_info *bdi);
61unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); 62unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned);