aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nilfs2/recovery.c12
-rw-r--r--fs/nilfs2/segbuf.c24
-rw-r--r--fs/nilfs2/segbuf.h6
-rw-r--r--fs/nilfs2/segment.c173
-rw-r--r--fs/nilfs2/segment.h5
-rw-r--r--fs/nilfs2/sufile.c8
-rw-r--r--fs/nilfs2/super.c4
-rw-r--r--fs/nilfs2/the_nilfs.h5
8 files changed, 29 insertions, 208 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index ef387b19682c..6ab4c8fc5e9f 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -463,16 +463,6 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
463 nilfs_free_segment_entry(ent); 463 nilfs_free_segment_entry(ent);
464 } 464 }
465 465
466 /*
467 * The segment having the latest super root is active, and
468 * should be deactivated on the next construction for recovery.
469 */
470 err = -ENOMEM;
471 ent = nilfs_alloc_segment_entry(segnum[0]);
472 if (unlikely(!ent))
473 goto failed;
474 list_add_tail(&ent->list, &ri->ri_used_segments);
475
476 /* Allocate new segments for recovery */ 466 /* Allocate new segments for recovery */
477 err = nilfs_sufile_alloc(sufile, &segnum[0]); 467 err = nilfs_sufile_alloc(sufile, &segnum[0]);
478 if (unlikely(err)) 468 if (unlikely(err))
@@ -757,7 +747,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
757 goto failed; 747 goto failed;
758 } 748 }
759 749
760 err = nilfs_attach_segment_constructor(sbi, ri); 750 err = nilfs_attach_segment_constructor(sbi);
761 if (unlikely(err)) 751 if (unlikely(err))
762 goto failed; 752 goto failed;
763 753
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 3d3ea8351f6d..1e68821b4a9b 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -64,27 +64,17 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
64 INIT_LIST_HEAD(&segbuf->sb_list); 64 INIT_LIST_HEAD(&segbuf->sb_list);
65 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); 65 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
66 INIT_LIST_HEAD(&segbuf->sb_payload_buffers); 66 INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
67 segbuf->sb_segent = NULL;
68 return segbuf; 67 return segbuf;
69} 68}
70 69
71void nilfs_segbuf_free(struct nilfs_segment_buffer *segbuf) 70void nilfs_segbuf_free(struct nilfs_segment_buffer *segbuf)
72{ 71{
73 struct nilfs_segment_entry *ent = segbuf->sb_segent;
74
75 if (ent != NULL && list_empty(&ent->list)) {
76 /* free isolated segment list head */
77 nilfs_free_segment_entry(segbuf->sb_segent);
78 segbuf->sb_segent = NULL;
79 }
80 kmem_cache_free(nilfs_segbuf_cachep, segbuf); 72 kmem_cache_free(nilfs_segbuf_cachep, segbuf);
81} 73}
82 74
83int nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum, 75void nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum,
84 unsigned long offset, struct the_nilfs *nilfs) 76 unsigned long offset, struct the_nilfs *nilfs)
85{ 77{
86 struct nilfs_segment_entry *ent;
87
88 segbuf->sb_segnum = segnum; 78 segbuf->sb_segnum = segnum;
89 nilfs_get_segment_range(nilfs, segnum, &segbuf->sb_fseg_start, 79 nilfs_get_segment_range(nilfs, segnum, &segbuf->sb_fseg_start,
90 &segbuf->sb_fseg_end); 80 &segbuf->sb_fseg_end);
@@ -92,18 +82,6 @@ int nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum,
92 segbuf->sb_pseg_start = segbuf->sb_fseg_start + offset; 82 segbuf->sb_pseg_start = segbuf->sb_fseg_start + offset;
93 segbuf->sb_rest_blocks = 83 segbuf->sb_rest_blocks =
94 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1; 84 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
95
96 /* Attach a segment list head */
97 ent = segbuf->sb_segent;
98 if (ent == NULL) {
99 segbuf->sb_segent = nilfs_alloc_segment_entry(segnum);
100 if (unlikely(!segbuf->sb_segent))
101 return -ENOMEM;
102 } else {
103 BUG_ON(ent->bh_su || !list_empty(&ent->list));
104 ent->segnum = segnum;
105 }
106 return 0;
107} 85}
108 86
109void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf, 87void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf,
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 25f2a5faa483..0c3076f4e592 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -68,7 +68,6 @@ struct nilfs_segsum_info {
68 * struct nilfs_segment_buffer - Segment buffer 68 * struct nilfs_segment_buffer - Segment buffer
69 * @sb_super: back pointer to a superblock struct 69 * @sb_super: back pointer to a superblock struct
70 * @sb_list: List head to chain this structure 70 * @sb_list: List head to chain this structure
71 * @sb_segent: Pointer for attaching a segment entry
72 * @sb_sum: On-memory segment summary 71 * @sb_sum: On-memory segment summary
73 * @sb_segnum: Index number of the full segment 72 * @sb_segnum: Index number of the full segment
74 * @sb_nextnum: Index number of the next full segment 73 * @sb_nextnum: Index number of the next full segment
@@ -83,7 +82,6 @@ struct nilfs_segsum_info {
83struct nilfs_segment_buffer { 82struct nilfs_segment_buffer {
84 struct super_block *sb_super; 83 struct super_block *sb_super;
85 struct list_head sb_list; 84 struct list_head sb_list;
86 struct nilfs_segment_entry *sb_segent;
87 85
88 /* Segment information */ 86 /* Segment information */
89 struct nilfs_segsum_info sb_sum; 87 struct nilfs_segsum_info sb_sum;
@@ -125,8 +123,8 @@ int __init nilfs_init_segbuf_cache(void);
125void nilfs_destroy_segbuf_cache(void); 123void nilfs_destroy_segbuf_cache(void);
126struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); 124struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *);
127void nilfs_segbuf_free(struct nilfs_segment_buffer *); 125void nilfs_segbuf_free(struct nilfs_segment_buffer *);
128int nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, 126void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long,
129 struct the_nilfs *); 127 struct the_nilfs *);
130void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, 128void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
131 struct the_nilfs *); 129 struct the_nilfs *);
132int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t); 130int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t);
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 2879704509fd..e43558d50e78 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1304,25 +1304,6 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
1304 return err; 1304 return err;
1305} 1305}
1306 1306
1307static int nilfs_segctor_terminate_segment(struct nilfs_sc_info *sci,
1308 struct nilfs_segment_buffer *segbuf,
1309 struct inode *sufile)
1310{
1311 struct nilfs_segment_entry *ent = segbuf->sb_segent;
1312 int err;
1313
1314 err = nilfs_open_segment_entry(ent, sufile);
1315 if (unlikely(err))
1316 return err;
1317 nilfs_mdt_mark_buffer_dirty(ent->bh_su);
1318 nilfs_mdt_mark_dirty(sufile);
1319 nilfs_close_segment_entry(ent, sufile);
1320
1321 list_add_tail(&ent->list, &sci->sc_active_segments);
1322 segbuf->sb_segent = NULL;
1323 return 0;
1324}
1325
1326static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum) 1307static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum)
1327{ 1308{
1328 struct buffer_head *bh_su; 1309 struct buffer_head *bh_su;
@@ -1342,7 +1323,6 @@ static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
1342 struct the_nilfs *nilfs) 1323 struct the_nilfs *nilfs)
1343{ 1324{
1344 struct nilfs_segment_buffer *segbuf, *n; 1325 struct nilfs_segment_buffer *segbuf, *n;
1345 struct inode *sufile = nilfs->ns_sufile;
1346 __u64 nextnum; 1326 __u64 nextnum;
1347 int err; 1327 int err;
1348 1328
@@ -1354,28 +1334,22 @@ static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
1354 } else 1334 } else
1355 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1335 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
1356 1336
1357 err = nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 1337 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset,
1358 nilfs->ns_pseg_offset, nilfs); 1338 nilfs);
1359 if (unlikely(err))
1360 return err;
1361 1339
1362 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { 1340 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
1363 err = nilfs_segctor_terminate_segment(sci, segbuf, sufile);
1364 if (unlikely(err))
1365 return err;
1366
1367 nilfs_shift_to_next_segment(nilfs); 1341 nilfs_shift_to_next_segment(nilfs);
1368 err = nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs); 1342 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
1369 } 1343 }
1370 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks; 1344 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
1371 1345
1372 err = nilfs_touch_segusage(sufile, segbuf->sb_segnum); 1346 err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum);
1373 if (unlikely(err)) 1347 if (unlikely(err))
1374 return err; 1348 return err;
1375 1349
1376 if (nilfs->ns_segnum == nilfs->ns_nextnum) { 1350 if (nilfs->ns_segnum == nilfs->ns_nextnum) {
1377 /* Start from the head of a new full segment */ 1351 /* Start from the head of a new full segment */
1378 err = nilfs_sufile_alloc(sufile, &nextnum); 1352 err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
1379 if (unlikely(err)) 1353 if (unlikely(err))
1380 return err; 1354 return err;
1381 } else 1355 } else
@@ -1390,7 +1364,7 @@ static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
1390 list_del_init(&segbuf->sb_list); 1364 list_del_init(&segbuf->sb_list);
1391 nilfs_segbuf_free(segbuf); 1365 nilfs_segbuf_free(segbuf);
1392 } 1366 }
1393 return err; 1367 return 0;
1394} 1368}
1395 1369
1396static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, 1370static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
@@ -1421,10 +1395,7 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1421 goto failed; 1395 goto failed;
1422 1396
1423 /* map this buffer to region of segment on-disk */ 1397 /* map this buffer to region of segment on-disk */
1424 err = nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs); 1398 nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
1425 if (unlikely(err))
1426 goto failed_segbuf;
1427
1428 sci->sc_segbuf_nblocks += segbuf->sb_rest_blocks; 1399 sci->sc_segbuf_nblocks += segbuf->sb_rest_blocks;
1429 1400
1430 /* allocate the next next full segment */ 1401 /* allocate the next next full segment */
@@ -2178,102 +2149,6 @@ static void nilfs_segctor_check_out_files(struct nilfs_sc_info *sci,
2178} 2149}
2179 2150
2180/* 2151/*
2181 * Nasty routines to manipulate active flags on sufile.
2182 * These would be removed in a future release.
2183 */
2184static void nilfs_segctor_reactivate_segments(struct nilfs_sc_info *sci,
2185 struct the_nilfs *nilfs)
2186{
2187 struct nilfs_segment_buffer *segbuf, *last;
2188 struct nilfs_segment_entry *ent, *n;
2189 struct inode *sufile = nilfs->ns_sufile;
2190 struct list_head *head;
2191
2192 last = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
2193 nilfs_for_each_segbuf_before(segbuf, last, &sci->sc_segbufs) {
2194 ent = segbuf->sb_segent;
2195 if (!ent)
2196 break; /* ignore unmapped segments (should check it?)*/
2197 nilfs_segment_usage_set_active(ent->raw_su);
2198 nilfs_close_segment_entry(ent, sufile);
2199 }
2200
2201 head = &sci->sc_active_segments;
2202 list_for_each_entry_safe(ent, n, head, list) {
2203 nilfs_segment_usage_set_active(ent->raw_su);
2204 nilfs_close_segment_entry(ent, sufile);
2205 }
2206}
2207
2208static int nilfs_segctor_deactivate_segments(struct nilfs_sc_info *sci,
2209 struct the_nilfs *nilfs)
2210{
2211 struct nilfs_segment_buffer *segbuf, *last;
2212 struct nilfs_segment_entry *ent;
2213 struct inode *sufile = nilfs->ns_sufile;
2214 int err;
2215
2216 last = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
2217 nilfs_for_each_segbuf_before(segbuf, last, &sci->sc_segbufs) {
2218 /*
2219 * Deactivate ongoing full segments. The last segment is kept
2220 * active because it is a start point of recovery, and is not
2221 * relocatable until the super block points to a newer
2222 * checkpoint.
2223 */
2224 ent = segbuf->sb_segent;
2225 if (!ent)
2226 break; /* ignore unmapped segments (should check it?)*/
2227 err = nilfs_open_segment_entry(ent, sufile);
2228 if (unlikely(err))
2229 goto failed;
2230 nilfs_segment_usage_clear_active(ent->raw_su);
2231 BUG_ON(!buffer_dirty(ent->bh_su));
2232 }
2233
2234 list_for_each_entry(ent, &sci->sc_active_segments, list) {
2235 err = nilfs_open_segment_entry(ent, sufile);
2236 if (unlikely(err))
2237 goto failed;
2238 nilfs_segment_usage_clear_active(ent->raw_su);
2239 WARN_ON(!buffer_dirty(ent->bh_su));
2240 }
2241 return 0;
2242
2243 failed:
2244 nilfs_segctor_reactivate_segments(sci, nilfs);
2245 return err;
2246}
2247
2248static void nilfs_segctor_bead_completed_segments(struct nilfs_sc_info *sci)
2249{
2250 struct nilfs_segment_buffer *segbuf, *last;
2251 struct nilfs_segment_entry *ent;
2252
2253 /* move each segbuf->sb_segent to the list of used active segments */
2254 last = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
2255 nilfs_for_each_segbuf_before(segbuf, last, &sci->sc_segbufs) {
2256 ent = segbuf->sb_segent;
2257 if (!ent)
2258 break; /* ignore unmapped segments (should check it?)*/
2259 list_add_tail(&ent->list, &sci->sc_active_segments);
2260 segbuf->sb_segent = NULL;
2261 }
2262}
2263
2264static void nilfs_segctor_commit_deactivate_segments(struct nilfs_sc_info *sci,
2265 struct the_nilfs *nilfs)
2266{
2267 struct nilfs_segment_entry *ent, *n;
2268
2269 list_for_each_entry_safe(ent, n, &sci->sc_active_segments, list) {
2270 list_del(&ent->list);
2271 nilfs_close_segment_entry(ent, nilfs->ns_sufile);
2272 nilfs_free_segment_entry(ent);
2273 }
2274}
2275
2276/*
2277 * Main procedure of segment constructor 2152 * Main procedure of segment constructor
2278 */ 2153 */
2279static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) 2154static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
@@ -2322,11 +2197,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2322 if (unlikely(err)) 2197 if (unlikely(err))
2323 goto failed; 2198 goto failed;
2324 2199
2325 if (has_sr) {
2326 err = nilfs_segctor_deactivate_segments(sci, nilfs);
2327 if (unlikely(err))
2328 goto failed;
2329 }
2330 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) 2200 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
2331 nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); 2201 nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile);
2332 2202
@@ -2353,12 +2223,10 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2353 nilfs_segctor_complete_write(sci); 2223 nilfs_segctor_complete_write(sci);
2354 2224
2355 /* Commit segments */ 2225 /* Commit segments */
2356 nilfs_segctor_bead_completed_segments(sci);
2357 if (has_sr) { 2226 if (has_sr) {
2358 down_write(&nilfs->ns_sem); 2227 down_write(&nilfs->ns_sem);
2359 nilfs_update_last_segment(sbi, 1); 2228 nilfs_update_last_segment(sbi, 1);
2360 up_write(&nilfs->ns_sem); 2229 up_write(&nilfs->ns_sem);
2361 nilfs_segctor_commit_deactivate_segments(sci, nilfs);
2362 nilfs_segctor_commit_free_segments(sci); 2230 nilfs_segctor_commit_free_segments(sci);
2363 nilfs_segctor_clear_metadata_dirty(sci); 2231 nilfs_segctor_clear_metadata_dirty(sci);
2364 } 2232 }
@@ -2379,8 +2247,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2379 failed_to_make_up: 2247 failed_to_make_up:
2380 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) 2248 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
2381 nilfs_redirty_inodes(&sci->sc_dirty_files); 2249 nilfs_redirty_inodes(&sci->sc_dirty_files);
2382 if (has_sr)
2383 nilfs_segctor_reactivate_segments(sci, nilfs);
2384 2250
2385 failed: 2251 failed:
2386 if (nilfs_doing_gc()) 2252 if (nilfs_doing_gc())
@@ -2942,23 +2808,11 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci)
2942 } 2808 }
2943} 2809}
2944 2810
2945static int nilfs_segctor_init(struct nilfs_sc_info *sci, 2811static int nilfs_segctor_init(struct nilfs_sc_info *sci)
2946 struct nilfs_recovery_info *ri)
2947{ 2812{
2948 int err;
2949
2950 sci->sc_seq_done = sci->sc_seq_request; 2813 sci->sc_seq_done = sci->sc_seq_request;
2951 if (ri)
2952 list_splice_init(&ri->ri_used_segments,
2953 sci->sc_active_segments.prev);
2954 2814
2955 err = nilfs_segctor_start_thread(sci); 2815 return nilfs_segctor_start_thread(sci);
2956 if (err) {
2957 if (ri)
2958 list_splice_init(&sci->sc_active_segments,
2959 ri->ri_used_segments.prev);
2960 }
2961 return err;
2962} 2816}
2963 2817
2964/* 2818/*
@@ -2982,7 +2836,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
2982 INIT_LIST_HEAD(&sci->sc_dirty_files); 2836 INIT_LIST_HEAD(&sci->sc_dirty_files);
2983 INIT_LIST_HEAD(&sci->sc_segbufs); 2837 INIT_LIST_HEAD(&sci->sc_segbufs);
2984 INIT_LIST_HEAD(&sci->sc_gc_inodes); 2838 INIT_LIST_HEAD(&sci->sc_gc_inodes);
2985 INIT_LIST_HEAD(&sci->sc_active_segments);
2986 INIT_LIST_HEAD(&sci->sc_cleaning_segments); 2839 INIT_LIST_HEAD(&sci->sc_cleaning_segments);
2987 INIT_LIST_HEAD(&sci->sc_copied_buffers); 2840 INIT_LIST_HEAD(&sci->sc_copied_buffers);
2988 2841
@@ -3048,8 +2901,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
3048 "dirty file(s) after the final construction\n"); 2901 "dirty file(s) after the final construction\n");
3049 nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1); 2902 nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1);
3050 } 2903 }
3051 if (!list_empty(&sci->sc_active_segments))
3052 nilfs_dispose_segment_list(&sci->sc_active_segments);
3053 2904
3054 if (!list_empty(&sci->sc_cleaning_segments)) 2905 if (!list_empty(&sci->sc_cleaning_segments))
3055 nilfs_dispose_segment_list(&sci->sc_cleaning_segments); 2906 nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
@@ -3064,7 +2915,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
3064/** 2915/**
3065 * nilfs_attach_segment_constructor - attach a segment constructor 2916 * nilfs_attach_segment_constructor - attach a segment constructor
3066 * @sbi: nilfs_sb_info 2917 * @sbi: nilfs_sb_info
3067 * @ri: nilfs_recovery_info
3068 * 2918 *
3069 * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, 2919 * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
3070 * initilizes it, and starts the segment constructor. 2920 * initilizes it, and starts the segment constructor.
@@ -3074,8 +2924,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
3074 * 2924 *
3075 * %-ENOMEM - Insufficient memory available. 2925 * %-ENOMEM - Insufficient memory available.
3076 */ 2926 */
3077int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, 2927int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi)
3078 struct nilfs_recovery_info *ri)
3079{ 2928{
3080 struct the_nilfs *nilfs = sbi->s_nilfs; 2929 struct the_nilfs *nilfs = sbi->s_nilfs;
3081 int err; 2930 int err;
@@ -3087,7 +2936,7 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi,
3087 return -ENOMEM; 2936 return -ENOMEM;
3088 2937
3089 nilfs_attach_writer(nilfs, sbi); 2938 nilfs_attach_writer(nilfs, sbi);
3090 err = nilfs_segctor_init(NILFS_SC(sbi), ri); 2939 err = nilfs_segctor_init(NILFS_SC(sbi));
3091 if (err) { 2940 if (err) {
3092 nilfs_detach_writer(nilfs, sbi); 2941 nilfs_detach_writer(nilfs, sbi);
3093 kfree(sbi->s_sc_info); 2942 kfree(sbi->s_sc_info);
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index bb7d417fec62..4a64eb82f1f5 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -90,7 +90,6 @@ struct nilfs_segsum_pointer {
90 * @sc_nblk_inc: Block count of current generation 90 * @sc_nblk_inc: Block count of current generation
91 * @sc_dirty_files: List of files to be written 91 * @sc_dirty_files: List of files to be written
92 * @sc_gc_inodes: List of GC inodes having blocks to be written 92 * @sc_gc_inodes: List of GC inodes having blocks to be written
93 * @sc_active_segments: List of active segments that were already written out
94 * @sc_cleaning_segments: List of segments to be freed through construction 93 * @sc_cleaning_segments: List of segments to be freed through construction
95 * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data 94 * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data
96 * @sc_dsync_inode: inode whose data pages are written for a sync operation 95 * @sc_dsync_inode: inode whose data pages are written for a sync operation
@@ -132,7 +131,6 @@ struct nilfs_sc_info {
132 131
133 struct list_head sc_dirty_files; 132 struct list_head sc_dirty_files;
134 struct list_head sc_gc_inodes; 133 struct list_head sc_gc_inodes;
135 struct list_head sc_active_segments;
136 struct list_head sc_cleaning_segments; 134 struct list_head sc_cleaning_segments;
137 struct list_head sc_copied_buffers; 135 struct list_head sc_copied_buffers;
138 136
@@ -232,8 +230,7 @@ extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
232 __u64 *, size_t); 230 __u64 *, size_t);
233extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *); 231extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *);
234 232
235extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *, 233extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
236 struct nilfs_recovery_info *);
237extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); 234extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
238 235
239/* recovery.c */ 236/* recovery.c */
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 4cf47e03a3ab..c774cf397e2f 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -158,7 +158,6 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
158 if (!nilfs_segment_usage_clean(su)) 158 if (!nilfs_segment_usage_clean(su))
159 continue; 159 continue;
160 /* found a clean segment */ 160 /* found a clean segment */
161 nilfs_segment_usage_set_active(su);
162 nilfs_segment_usage_set_dirty(su); 161 nilfs_segment_usage_set_dirty(su);
163 kunmap_atomic(kaddr, KM_USER0); 162 kunmap_atomic(kaddr, KM_USER0);
164 163
@@ -591,6 +590,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
591 struct buffer_head *su_bh; 590 struct buffer_head *su_bh;
592 struct nilfs_segment_usage *su; 591 struct nilfs_segment_usage *su;
593 size_t susz = NILFS_MDT(sufile)->mi_entry_size; 592 size_t susz = NILFS_MDT(sufile)->mi_entry_size;
593 struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
594 void *kaddr; 594 void *kaddr;
595 unsigned long nsegs, segusages_per_block; 595 unsigned long nsegs, segusages_per_block;
596 ssize_t n; 596 ssize_t n;
@@ -623,7 +623,11 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
623 for (j = 0; j < n; j++, su = (void *)su + susz) { 623 for (j = 0; j < n; j++, su = (void *)su + susz) {
624 si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod); 624 si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod);
625 si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks); 625 si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
626 si[i + j].sui_flags = le32_to_cpu(su->su_flags); 626 si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
627 ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
628 if (nilfs_segment_is_active(nilfs, segnum + i + j))
629 si[i + j].sui_flags |=
630 (1UL << NILFS_SEGMENT_USAGE_ACTIVE);
627 } 631 }
628 kunmap_atomic(kaddr, KM_USER0); 632 kunmap_atomic(kaddr, KM_USER0);
629 brelse(su_bh); 633 brelse(su_bh);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index b7519c327ba7..ef31e9a51c84 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -868,7 +868,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
868 } 868 }
869 869
870 if (!(sb->s_flags & MS_RDONLY)) { 870 if (!(sb->s_flags & MS_RDONLY)) {
871 err = nilfs_attach_segment_constructor(sbi, NULL); 871 err = nilfs_attach_segment_constructor(sbi);
872 if (err) 872 if (err)
873 goto failed_checkpoint; 873 goto failed_checkpoint;
874 } 874 }
@@ -1001,7 +1001,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
1001 nilfs_clear_opt(sbi, SNAPSHOT); 1001 nilfs_clear_opt(sbi, SNAPSHOT);
1002 sbi->s_snapshot_cno = 0; 1002 sbi->s_snapshot_cno = 0;
1003 1003
1004 err = nilfs_attach_segment_constructor(sbi, NULL); 1004 err = nilfs_attach_segment_constructor(sbi);
1005 if (err) 1005 if (err)
1006 goto rw_remount_failed; 1006 goto rw_remount_failed;
1007 1007
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index af566e78f7af..d750e48257c9 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -280,4 +280,9 @@ static inline __u64 nilfs_last_cno(struct the_nilfs *nilfs)
280 return cno; 280 return cno;
281} 281}
282 282
283static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
284{
285 return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
286}
287
283#endif /* _THE_NILFS_H */ 288#endif /* _THE_NILFS_H */