hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nilfs2/segment.c
....@@ -158,7 +158,7 @@
158158 * it is saved and will be restored on
159159 * nilfs_transaction_commit().
160160 */
161
- nilfs_msg(sb, KERN_WARNING, "journal info from a different FS");
161
+ nilfs_warn(sb, "journal info from a different FS");
162162 save = current->journal_info;
163163 }
164164 if (!ti) {
....@@ -322,7 +322,7 @@
322322 struct the_nilfs *nilfs = sb->s_fs_info;
323323 struct nilfs_sc_info *sci = nilfs->ns_writer;
324324
325
- if (!sci || !sci->sc_flush_request)
325
+ if (sb_rdonly(sb) || unlikely(!sci) || !sci->sc_flush_request)
326326 return;
327327
328328 set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
....@@ -435,6 +435,23 @@
435435 return 0;
436436 }
437437
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
+
438455 static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
439456 {
440457 sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
....@@ -443,6 +460,7 @@
443460 * The current segment is filled up
444461 * (internal code)
445462 */
463
+ nilfs_segctor_zeropad_segsum(sci);
446464 sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
447465 return nilfs_segctor_reset_segment_buffer(sci);
448466 }
....@@ -547,6 +565,7 @@
547565 goto retry;
548566 }
549567 if (unlikely(required)) {
568
+ nilfs_segctor_zeropad_segsum(sci);
550569 err = nilfs_segbuf_extend_segsum(segbuf);
551570 if (unlikely(err))
552571 goto failed;
....@@ -711,6 +730,11 @@
711730 struct page *page = pvec.pages[i];
712731
713732 lock_page(page);
733
+ if (unlikely(page->mapping != mapping)) {
734
+ /* Exclude pages removed from the address space */
735
+ unlock_page(page);
736
+ continue;
737
+ }
714738 if (!page_has_buffers(page))
715739 create_empty_buffers(page, i_blocksize(inode), 0);
716740 unlock_page(page);
....@@ -738,15 +762,18 @@
738762 struct list_head *listp)
739763 {
740764 struct nilfs_inode_info *ii = NILFS_I(inode);
741
- struct address_space *mapping = &ii->i_btnode_cache;
765
+ struct inode *btnc_inode = ii->i_assoc_inode;
742766 struct pagevec pvec;
743767 struct buffer_head *bh, *head;
744768 unsigned int i;
745769 pgoff_t index = 0;
746770
771
+ if (!btnc_inode)
772
+ return;
773
+
747774 pagevec_init(&pvec);
748775
749
- while (pagevec_lookup_tag(&pvec, mapping, &index,
776
+ while (pagevec_lookup_tag(&pvec, btnc_inode->i_mapping, &index,
750777 PAGECACHE_TAG_DIRTY)) {
751778 for (i = 0; i < pagevec_count(&pvec); i++) {
752779 bh = head = page_buffers(pvec.pages[i]);
....@@ -877,9 +904,11 @@
877904 nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
878905 nilfs_cpfile_put_checkpoint(
879906 nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
880
- } else
881
- WARN_ON(err == -EINVAL || err == -ENOENT);
882
-
907
+ } else if (err == -EINVAL || err == -ENOENT) {
908
+ nilfs_error(sci->sc_super,
909
+ "checkpoint creation failed due to metadata corruption.");
910
+ err = -EIO;
911
+ }
883912 return err;
884913 }
885914
....@@ -893,7 +922,11 @@
893922 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0,
894923 &raw_cp, &bh_cp);
895924 if (unlikely(err)) {
896
- WARN_ON(err == -EINVAL || err == -ENOENT);
925
+ if (err == -EINVAL || err == -ENOENT) {
926
+ nilfs_error(sci->sc_super,
927
+ "checkpoint finalization failed due to metadata corruption.");
928
+ err = -EIO;
929
+ }
897930 goto failed_ibh;
898931 }
899932 raw_cp->cp_snapshot_list.ssl_next = 0;
....@@ -956,10 +989,13 @@
956989 unsigned int isz, srsz;
957990
958991 bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
992
+
993
+ lock_buffer(bh_sr);
959994 raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
960995 isz = nilfs->ns_inode_size;
961996 srsz = NILFS_SR_BYTES(isz);
962997
998
+ raw_sr->sr_sum = 0; /* Ensure initialization within this update */
963999 raw_sr->sr_bytes = cpu_to_le16(srsz);
9641000 raw_sr->sr_nongc_ctime
9651001 = cpu_to_le64(nilfs_doing_gc() ?
....@@ -973,6 +1009,8 @@
9731009 nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
9741010 NILFS_SR_SUFILE_OFFSET(isz), 1);
9751011 memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
1012
+ set_buffer_uptodate(bh_sr);
1013
+ unlock_buffer(bh_sr);
9761014 }
9771015
9781016 static void nilfs_redirty_inodes(struct list_head *head)
....@@ -1138,7 +1176,8 @@
11381176 nilfs_sc_cstage_set(sci, NILFS_ST_DAT);
11391177 goto dat_stage;
11401178 }
1141
- nilfs_sc_cstage_inc(sci); /* Fall through */
1179
+ nilfs_sc_cstage_inc(sci);
1180
+ fallthrough;
11421181 case NILFS_ST_GC:
11431182 if (nilfs_doing_gc()) {
11441183 head = &sci->sc_gc_inodes;
....@@ -1159,7 +1198,8 @@
11591198 }
11601199 sci->sc_stage.gc_inode_ptr = NULL;
11611200 }
1162
- nilfs_sc_cstage_inc(sci); /* Fall through */
1201
+ nilfs_sc_cstage_inc(sci);
1202
+ fallthrough;
11631203 case NILFS_ST_FILE:
11641204 head = &sci->sc_dirty_files;
11651205 ii = list_prepare_entry(sci->sc_stage.dirty_file_ptr, head,
....@@ -1186,7 +1226,7 @@
11861226 }
11871227 nilfs_sc_cstage_inc(sci);
11881228 sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
1189
- /* Fall through */
1229
+ fallthrough;
11901230 case NILFS_ST_IFILE:
11911231 err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile,
11921232 &nilfs_sc_file_ops);
....@@ -1197,13 +1237,14 @@
11971237 err = nilfs_segctor_create_checkpoint(sci);
11981238 if (unlikely(err))
11991239 break;
1200
- /* Fall through */
1240
+ fallthrough;
12011241 case NILFS_ST_CPFILE:
12021242 err = nilfs_segctor_scan_file(sci, nilfs->ns_cpfile,
12031243 &nilfs_sc_file_ops);
12041244 if (unlikely(err))
12051245 break;
1206
- nilfs_sc_cstage_inc(sci); /* Fall through */
1246
+ nilfs_sc_cstage_inc(sci);
1247
+ fallthrough;
12071248 case NILFS_ST_SUFILE:
12081249 err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs,
12091250 sci->sc_nfreesegs, &ndone);
....@@ -1219,7 +1260,8 @@
12191260 &nilfs_sc_file_ops);
12201261 if (unlikely(err))
12211262 break;
1222
- nilfs_sc_cstage_inc(sci); /* Fall through */
1263
+ nilfs_sc_cstage_inc(sci);
1264
+ fallthrough;
12231265 case NILFS_ST_DAT:
12241266 dat_stage:
12251267 err = nilfs_segctor_scan_file(sci, nilfs->ns_dat,
....@@ -1230,7 +1272,8 @@
12301272 nilfs_sc_cstage_set(sci, NILFS_ST_DONE);
12311273 return 0;
12321274 }
1233
- nilfs_sc_cstage_inc(sci); /* Fall through */
1275
+ nilfs_sc_cstage_inc(sci);
1276
+ fallthrough;
12341277 case NILFS_ST_SR:
12351278 if (mode == SC_LSEG_SR) {
12361279 /* Appending a super root */
....@@ -1522,6 +1565,7 @@
15221565 nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
15231566 sci->sc_stage = prev_stage;
15241567 }
1568
+ nilfs_segctor_zeropad_segsum(sci);
15251569 nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
15261570 return 0;
15271571
....@@ -1749,6 +1793,7 @@
17491793 list_for_each_entry(segbuf, logs, sb_list) {
17501794 list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
17511795 b_assoc_buffers) {
1796
+ clear_buffer_uptodate(bh);
17521797 if (bh->b_page != bd_page) {
17531798 if (bd_page)
17541799 end_page_writeback(bd_page);
....@@ -1760,6 +1805,7 @@
17601805 b_assoc_buffers) {
17611806 clear_buffer_async_write(bh);
17621807 if (bh == segbuf->sb_super_root) {
1808
+ clear_buffer_uptodate(bh);
17631809 if (bh->b_page != bd_page) {
17641810 end_page_writeback(bd_page);
17651811 bd_page = bh->b_page;
....@@ -1940,9 +1986,9 @@
19401986 err = nilfs_ifile_get_inode_block(
19411987 ifile, ii->vfs_inode.i_ino, &ibh);
19421988 if (unlikely(err)) {
1943
- nilfs_msg(sci->sc_super, KERN_WARNING,
1944
- "log writer: error %d getting inode block (ino=%lu)",
1945
- err, ii->vfs_inode.i_ino);
1989
+ nilfs_warn(sci->sc_super,
1990
+ "log writer: error %d getting inode block (ino=%lu)",
1991
+ err, ii->vfs_inode.i_ino);
19461992 return err;
19471993 }
19481994 spin_lock(&nilfs->ns_inode_lock);
....@@ -2009,6 +2055,9 @@
20092055 {
20102056 struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
20112057 int err;
2058
+
2059
+ if (sb_rdonly(sci->sc_super))
2060
+ return -EROFS;
20122061
20132062 nilfs_sc_cstage_set(sci, NILFS_ST_INIT);
20142063 sci->sc_cno = nilfs->ns_cno;
....@@ -2234,7 +2283,7 @@
22342283 struct nilfs_transaction_info *ti;
22352284 int err;
22362285
2237
- if (!sci)
2286
+ if (sb_rdonly(sb) || unlikely(!sci))
22382287 return -EROFS;
22392288
22402289 /* A call inside transactions causes a deadlock. */
....@@ -2273,7 +2322,7 @@
22732322 struct nilfs_transaction_info ti;
22742323 int err = 0;
22752324
2276
- if (!sci)
2325
+ if (sb_rdonly(sb) || unlikely(!sci))
22772326 return -EROFS;
22782327
22792328 nilfs_transaction_lock(sb, &ti, 0);
....@@ -2410,7 +2459,7 @@
24102459 continue;
24112460 list_del_init(&ii->i_dirty);
24122461 truncate_inode_pages(&ii->vfs_inode.i_data, 0);
2413
- nilfs_btnode_cache_clear(&ii->i_btnode_cache);
2462
+ nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping);
24142463 iput(&ii->vfs_inode);
24152464 }
24162465 }
....@@ -2449,7 +2498,7 @@
24492498 if (likely(!err))
24502499 break;
24512500
2452
- nilfs_msg(sb, KERN_WARNING, "error %d cleaning segments", err);
2501
+ nilfs_warn(sb, "error %d cleaning segments", err);
24532502 set_current_state(TASK_INTERRUPTIBLE);
24542503 schedule_timeout(sci->sc_interval);
24552504 }
....@@ -2457,9 +2506,9 @@
24572506 int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs,
24582507 sci->sc_nfreesegs);
24592508 if (ret) {
2460
- nilfs_msg(sb, KERN_WARNING,
2461
- "error %d on discard request, turning discards off for the device",
2462
- ret);
2509
+ nilfs_warn(sb,
2510
+ "error %d on discard request, turning discards off for the device",
2511
+ ret);
24632512 nilfs_clear_opt(nilfs, DISCARD);
24642513 }
24652514 }
....@@ -2540,9 +2589,9 @@
25402589 /* start sync. */
25412590 sci->sc_task = current;
25422591 wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */
2543
- nilfs_msg(sci->sc_super, KERN_INFO,
2544
- "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
2545
- sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
2592
+ nilfs_info(sci->sc_super,
2593
+ "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
2594
+ sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
25462595
25472596 spin_lock(&sci->sc_state_lock);
25482597 loop:
....@@ -2600,11 +2649,10 @@
26002649 goto loop;
26012650
26022651 end_thread:
2603
- spin_unlock(&sci->sc_state_lock);
2604
-
26052652 /* end sync. */
26062653 sci->sc_task = NULL;
26072654 wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
2655
+ spin_unlock(&sci->sc_state_lock);
26082656 return 0;
26092657 }
26102658
....@@ -2616,8 +2664,8 @@
26162664 if (IS_ERR(t)) {
26172665 int err = PTR_ERR(t);
26182666
2619
- nilfs_msg(sci->sc_super, KERN_ERR,
2620
- "error %d creating segctord thread", err);
2667
+ nilfs_err(sci->sc_super, "error %d creating segctord thread",
2668
+ err);
26212669 return err;
26222670 }
26232671 wait_event(sci->sc_wait_task, sci->sc_task != NULL);
....@@ -2696,7 +2744,7 @@
26962744
26972745 flush_work(&sci->sc_iput_work);
26982746
2699
- } while (ret && retrycount-- > 0);
2747
+ } while (ret && ret != -EROFS && retrycount-- > 0);
27002748 }
27012749
27022750 /**
....@@ -2727,14 +2775,14 @@
27272775 nilfs_segctor_write_out(sci);
27282776
27292777 if (!list_empty(&sci->sc_dirty_files)) {
2730
- nilfs_msg(sci->sc_super, KERN_WARNING,
2731
- "disposed unprocessed dirty file(s) when stopping log writer");
2778
+ nilfs_warn(sci->sc_super,
2779
+ "disposed unprocessed dirty file(s) when stopping log writer");
27322780 nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
27332781 }
27342782
27352783 if (!list_empty(&sci->sc_iput_queue)) {
2736
- nilfs_msg(sci->sc_super, KERN_WARNING,
2737
- "disposed unprocessed inode(s) in iput queue when stopping log writer");
2784
+ nilfs_warn(sci->sc_super,
2785
+ "disposed unprocessed inode(s) in iput queue when stopping log writer");
27382786 nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1);
27392787 }
27402788
....@@ -2769,11 +2817,12 @@
27692817
27702818 if (nilfs->ns_writer) {
27712819 /*
2772
- * This happens if the filesystem was remounted
2773
- * read/write after nilfs_error degenerated it into a
2774
- * read-only mount.
2820
+ * This happens if the filesystem is made read-only by
2821
+ * __nilfs_error or nilfs_remount and then remounted
2822
+ * read/write. In these cases, reuse the existing
2823
+ * writer.
27752824 */
2776
- nilfs_detach_log_writer(sb);
2825
+ return 0;
27772826 }
27782827
27792828 nilfs->ns_writer = nilfs_segctor_new(sb, root);
....@@ -2783,10 +2832,9 @@
27832832 inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL);
27842833
27852834 err = nilfs_segctor_start_thread(nilfs->ns_writer);
2786
- if (err) {
2787
- kfree(nilfs->ns_writer);
2788
- nilfs->ns_writer = NULL;
2789
- }
2835
+ if (unlikely(err))
2836
+ nilfs_detach_log_writer(sb);
2837
+
27902838 return err;
27912839 }
27922840
....@@ -2807,16 +2855,18 @@
28072855 nilfs_segctor_destroy(nilfs->ns_writer);
28082856 nilfs->ns_writer = NULL;
28092857 }
2858
+ set_nilfs_purging(nilfs);
28102859
28112860 /* Force to free the list of dirty files */
28122861 spin_lock(&nilfs->ns_inode_lock);
28132862 if (!list_empty(&nilfs->ns_dirty_files)) {
28142863 list_splice_init(&nilfs->ns_dirty_files, &garbage_list);
2815
- nilfs_msg(sb, KERN_WARNING,
2816
- "disposed unprocessed dirty file(s) when detaching log writer");
2864
+ nilfs_warn(sb,
2865
+ "disposed unprocessed dirty file(s) when detaching log writer");
28172866 }
28182867 spin_unlock(&nilfs->ns_inode_lock);
28192868 up_write(&nilfs->ns_segctor_sem);
28202869
28212870 nilfs_dispose_list(nilfs, &garbage_list, 1);
2871
+ clear_nilfs_purging(nilfs);
28222872 }