aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/segment.c
diff options
context:
space:
mode:
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);