diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
-rw-r--r-- | fs/nilfs2/segment.c | 173 |
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 | ||
1307 | static 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 | |||
1326 | static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum) | 1307 | static 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 | ||
1396 | static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, | 1370 | static 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 | */ | ||
2184 | static 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 | |||
2208 | static 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 | |||
2248 | static 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 | |||
2264 | static 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 | */ |
2279 | static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | 2154 | static 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 | ||
2945 | static int nilfs_segctor_init(struct nilfs_sc_info *sci, | 2811 | static 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 | */ |
3077 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, | 2927 | int 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); |