aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-06 22:01:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:20 -0400
commitcece552074c591970353ad48308d65f110aeaf28 (patch)
tree2dcca7913d38df89711504f5daeecccfedb5a3eb
parentc96fa464a567a2a8796009af0e79bc68af73f485 (diff)
nilfs2: simplify handling of active state of segments
will reduce some lines of segment constructor. Previously, the state was complexly controlled through a list of segments in order to keep consistency in meta data of usage state of segments. Instead, this presents ``calculated'' active flags to userland cleaner program and stop maintaining its real flag on disk. Only by this fake flag, the cleaner cannot exactly know if each segment is reclaimable or not. However, the recent extension of nilfs_sustat ioctl struct (nilfs2-extend-nilfs_sustat-ioctl-struct.patch) can prevent the cleaner from reclaiming in-use segment wrongly. So, now I can apply this for simplification. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-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 */