aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/segment.c
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 /fs/nilfs2/segment.c
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>
Diffstat (limited to 'fs/nilfs2/segment.c')
-rw-r--r--fs/nilfs2/segment.c173
1 files changed, 11 insertions, 162 deletions
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);