.. | .. |
---|
435 | 435 | return 0; |
---|
436 | 436 | } |
---|
437 | 437 | |
---|
| 438 | +/** |
---|
| 439 | + * nilfs_segctor_zeropad_segsum - zero pad the rest of the segment summary area |
---|
| 440 | + * @sci: segment constructor object |
---|
| 441 | + * |
---|
| 442 | + * nilfs_segctor_zeropad_segsum() zero-fills unallocated space at the end of |
---|
| 443 | + * the current segment summary block. |
---|
| 444 | + */ |
---|
| 445 | +static void nilfs_segctor_zeropad_segsum(struct nilfs_sc_info *sci) |
---|
| 446 | +{ |
---|
| 447 | + struct nilfs_segsum_pointer *ssp; |
---|
| 448 | + |
---|
| 449 | + ssp = sci->sc_blk_cnt > 0 ? &sci->sc_binfo_ptr : &sci->sc_finfo_ptr; |
---|
| 450 | + if (ssp->offset < ssp->bh->b_size) |
---|
| 451 | + memset(ssp->bh->b_data + ssp->offset, 0, |
---|
| 452 | + ssp->bh->b_size - ssp->offset); |
---|
| 453 | +} |
---|
| 454 | + |
---|
438 | 455 | static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci) |
---|
439 | 456 | { |
---|
440 | 457 | sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks; |
---|
.. | .. |
---|
443 | 460 | * The current segment is filled up |
---|
444 | 461 | * (internal code) |
---|
445 | 462 | */ |
---|
| 463 | + nilfs_segctor_zeropad_segsum(sci); |
---|
446 | 464 | sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg); |
---|
447 | 465 | return nilfs_segctor_reset_segment_buffer(sci); |
---|
448 | 466 | } |
---|
.. | .. |
---|
547 | 565 | goto retry; |
---|
548 | 566 | } |
---|
549 | 567 | if (unlikely(required)) { |
---|
| 568 | + nilfs_segctor_zeropad_segsum(sci); |
---|
550 | 569 | err = nilfs_segbuf_extend_segsum(segbuf); |
---|
551 | 570 | if (unlikely(err)) |
---|
552 | 571 | goto failed; |
---|
.. | .. |
---|
711 | 730 | struct page *page = pvec.pages[i]; |
---|
712 | 731 | |
---|
713 | 732 | lock_page(page); |
---|
| 733 | + if (unlikely(page->mapping != mapping)) { |
---|
| 734 | + /* Exclude pages removed from the address space */ |
---|
| 735 | + unlock_page(page); |
---|
| 736 | + continue; |
---|
| 737 | + } |
---|
714 | 738 | if (!page_has_buffers(page)) |
---|
715 | 739 | create_empty_buffers(page, i_blocksize(inode), 0); |
---|
716 | 740 | unlock_page(page); |
---|
.. | .. |
---|
965 | 989 | unsigned int isz, srsz; |
---|
966 | 990 | |
---|
967 | 991 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; |
---|
| 992 | + |
---|
| 993 | + lock_buffer(bh_sr); |
---|
968 | 994 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; |
---|
969 | 995 | isz = nilfs->ns_inode_size; |
---|
970 | 996 | srsz = NILFS_SR_BYTES(isz); |
---|
971 | 997 | |
---|
| 998 | + raw_sr->sr_sum = 0; /* Ensure initialization within this update */ |
---|
972 | 999 | raw_sr->sr_bytes = cpu_to_le16(srsz); |
---|
973 | 1000 | raw_sr->sr_nongc_ctime |
---|
974 | 1001 | = cpu_to_le64(nilfs_doing_gc() ? |
---|
.. | .. |
---|
982 | 1009 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + |
---|
983 | 1010 | NILFS_SR_SUFILE_OFFSET(isz), 1); |
---|
984 | 1011 | memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz); |
---|
| 1012 | + set_buffer_uptodate(bh_sr); |
---|
| 1013 | + unlock_buffer(bh_sr); |
---|
985 | 1014 | } |
---|
986 | 1015 | |
---|
987 | 1016 | static void nilfs_redirty_inodes(struct list_head *head) |
---|
.. | .. |
---|
1536 | 1565 | nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); |
---|
1537 | 1566 | sci->sc_stage = prev_stage; |
---|
1538 | 1567 | } |
---|
| 1568 | + nilfs_segctor_zeropad_segsum(sci); |
---|
1539 | 1569 | nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile); |
---|
1540 | 1570 | return 0; |
---|
1541 | 1571 | |
---|
.. | .. |
---|
1763 | 1793 | list_for_each_entry(segbuf, logs, sb_list) { |
---|
1764 | 1794 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
---|
1765 | 1795 | b_assoc_buffers) { |
---|
| 1796 | + clear_buffer_uptodate(bh); |
---|
1766 | 1797 | if (bh->b_page != bd_page) { |
---|
1767 | 1798 | if (bd_page) |
---|
1768 | 1799 | end_page_writeback(bd_page); |
---|
.. | .. |
---|
1774 | 1805 | b_assoc_buffers) { |
---|
1775 | 1806 | clear_buffer_async_write(bh); |
---|
1776 | 1807 | if (bh == segbuf->sb_super_root) { |
---|
| 1808 | + clear_buffer_uptodate(bh); |
---|
1777 | 1809 | if (bh->b_page != bd_page) { |
---|
1778 | 1810 | end_page_writeback(bd_page); |
---|
1779 | 1811 | bd_page = bh->b_page; |
---|
.. | .. |
---|
2023 | 2055 | { |
---|
2024 | 2056 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
---|
2025 | 2057 | int err; |
---|
| 2058 | + |
---|
| 2059 | + if (sb_rdonly(sci->sc_super)) |
---|
| 2060 | + return -EROFS; |
---|
2026 | 2061 | |
---|
2027 | 2062 | nilfs_sc_cstage_set(sci, NILFS_ST_INIT); |
---|
2028 | 2063 | sci->sc_cno = nilfs->ns_cno; |
---|
.. | .. |
---|
2614 | 2649 | goto loop; |
---|
2615 | 2650 | |
---|
2616 | 2651 | end_thread: |
---|
2617 | | - spin_unlock(&sci->sc_state_lock); |
---|
2618 | | - |
---|
2619 | 2652 | /* end sync. */ |
---|
2620 | 2653 | sci->sc_task = NULL; |
---|
2621 | 2654 | wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */ |
---|
| 2655 | + spin_unlock(&sci->sc_state_lock); |
---|
2622 | 2656 | return 0; |
---|
2623 | 2657 | } |
---|
2624 | 2658 | |
---|
.. | .. |
---|
2710 | 2744 | |
---|
2711 | 2745 | flush_work(&sci->sc_iput_work); |
---|
2712 | 2746 | |
---|
2713 | | - } while (ret && retrycount-- > 0); |
---|
| 2747 | + } while (ret && ret != -EROFS && retrycount-- > 0); |
---|
2714 | 2748 | } |
---|
2715 | 2749 | |
---|
2716 | 2750 | /** |
---|
.. | .. |
---|
2821 | 2855 | nilfs_segctor_destroy(nilfs->ns_writer); |
---|
2822 | 2856 | nilfs->ns_writer = NULL; |
---|
2823 | 2857 | } |
---|
| 2858 | + set_nilfs_purging(nilfs); |
---|
2824 | 2859 | |
---|
2825 | 2860 | /* Force to free the list of dirty files */ |
---|
2826 | 2861 | spin_lock(&nilfs->ns_inode_lock); |
---|
.. | .. |
---|
2833 | 2868 | up_write(&nilfs->ns_segctor_sem); |
---|
2834 | 2869 | |
---|
2835 | 2870 | nilfs_dispose_list(nilfs, &garbage_list, 1); |
---|
| 2871 | + clear_nilfs_purging(nilfs); |
---|
2836 | 2872 | } |
---|