diff options
-rw-r--r-- | fs/nilfs2/recovery.c | 12 | ||||
-rw-r--r-- | fs/nilfs2/segbuf.c | 24 | ||||
-rw-r--r-- | fs/nilfs2/segbuf.h | 6 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 173 | ||||
-rw-r--r-- | fs/nilfs2/segment.h | 5 | ||||
-rw-r--r-- | fs/nilfs2/sufile.c | 8 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.h | 5 |
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 | ||
71 | void nilfs_segbuf_free(struct nilfs_segment_buffer *segbuf) | 70 | void 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 | ||
83 | int nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum, | 75 | void 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 | ||
109 | void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf, | 87 | void 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 { | |||
83 | struct nilfs_segment_buffer { | 82 | struct 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); | |||
125 | void nilfs_destroy_segbuf_cache(void); | 123 | void nilfs_destroy_segbuf_cache(void); |
126 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); | 124 | struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); |
127 | void nilfs_segbuf_free(struct nilfs_segment_buffer *); | 125 | void nilfs_segbuf_free(struct nilfs_segment_buffer *); |
128 | int nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, | 126 | void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, |
129 | struct the_nilfs *); | 127 | struct the_nilfs *); |
130 | void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, | 128 | void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, |
131 | struct the_nilfs *); | 129 | struct the_nilfs *); |
132 | int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t); | 130 | int 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 | ||
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); |
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); |
233 | extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *); | 231 | extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *); |
234 | 232 | ||
235 | extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *, | 233 | extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); |
236 | struct nilfs_recovery_info *); | ||
237 | extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); | 234 | extern 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 | ||
283 | static 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 */ |