diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/recovery.c | 32 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 39 | ||||
-rw-r--r-- | fs/nilfs2/sufile.c | 8 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 18 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.h | 5 |
6 files changed, 37 insertions, 69 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index 877dc1ba23f3..a4253f34e138 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -416,6 +416,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
416 | struct nilfs_segment_entry *ent, *n; | 416 | struct nilfs_segment_entry *ent, *n; |
417 | struct inode *sufile = nilfs->ns_sufile; | 417 | struct inode *sufile = nilfs->ns_sufile; |
418 | __u64 segnum[4]; | 418 | __u64 segnum[4]; |
419 | time_t mtime; | ||
419 | int err; | 420 | int err; |
420 | int i; | 421 | int i; |
421 | 422 | ||
@@ -442,9 +443,9 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
442 | 443 | ||
443 | /* | 444 | /* |
444 | * Collecting segments written after the latest super root. | 445 | * Collecting segments written after the latest super root. |
445 | * These are marked volatile active, and won't be reallocated in | 446 | * These are marked dirty to avoid being reallocated in the next write. |
446 | * the next construction. | ||
447 | */ | 447 | */ |
448 | mtime = get_seconds(); | ||
448 | list_for_each_entry_safe(ent, n, head, list) { | 449 | list_for_each_entry_safe(ent, n, head, list) { |
449 | if (ent->segnum == segnum[0]) { | 450 | if (ent->segnum == segnum[0]) { |
450 | list_del(&ent->list); | 451 | list_del(&ent->list); |
@@ -454,17 +455,16 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
454 | err = nilfs_open_segment_entry(ent, sufile); | 455 | err = nilfs_open_segment_entry(ent, sufile); |
455 | if (unlikely(err)) | 456 | if (unlikely(err)) |
456 | goto failed; | 457 | goto failed; |
457 | if (nilfs_segment_usage_clean(ent->raw_su)) { | 458 | if (!nilfs_segment_usage_dirty(ent->raw_su)) { |
458 | nilfs_segment_usage_set_volatile_active(ent->raw_su); | 459 | /* make the segment garbage */ |
459 | /* Keep it open */ | 460 | ent->raw_su->su_nblocks = cpu_to_le32(0); |
460 | } else { | 461 | ent->raw_su->su_lastmod = cpu_to_le32(mtime); |
461 | /* Removing duplicated entries */ | 462 | nilfs_segment_usage_set_dirty(ent->raw_su); |
462 | list_del(&ent->list); | ||
463 | nilfs_close_segment_entry(ent, sufile); | ||
464 | nilfs_free_segment_entry(ent); | ||
465 | } | 463 | } |
464 | list_del(&ent->list); | ||
465 | nilfs_close_segment_entry(ent, sufile); | ||
466 | nilfs_free_segment_entry(ent); | ||
466 | } | 467 | } |
467 | list_splice_init(head, nilfs->ns_used_segments.prev); | ||
468 | 468 | ||
469 | /* | 469 | /* |
470 | * The segment having the latest super root is active, and | 470 | * The segment having the latest super root is active, and |
@@ -882,10 +882,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, | |||
882 | 882 | ||
883 | if (scan_newer) | 883 | if (scan_newer) |
884 | ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; | 884 | ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; |
885 | else if (nilfs->ns_mount_state & NILFS_VALID_FS) | 885 | else { |
886 | goto super_root_found; | 886 | nilfs->ns_prot_seq = ssi.seg_seq; |
887 | 887 | if (nilfs->ns_mount_state & NILFS_VALID_FS) | |
888 | scan_newer = 1; | 888 | goto super_root_found; |
889 | scan_newer = 1; | ||
890 | } | ||
889 | 891 | ||
890 | /* reset region for roll-forward */ | 892 | /* reset region for roll-forward */ |
891 | pseg_start += ssi.nblocks; | 893 | pseg_start += ssi.nblocks; |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 5db12d774a03..24d0fbd4271c 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2229,13 +2229,6 @@ static void nilfs_segctor_reactivate_segments(struct nilfs_sc_info *sci, | |||
2229 | nilfs_segment_usage_set_active(ent->raw_su); | 2229 | nilfs_segment_usage_set_active(ent->raw_su); |
2230 | nilfs_close_segment_entry(ent, sufile); | 2230 | nilfs_close_segment_entry(ent, sufile); |
2231 | } | 2231 | } |
2232 | |||
2233 | down_write(&nilfs->ns_sem); | ||
2234 | head = &nilfs->ns_used_segments; | ||
2235 | list_for_each_entry(ent, head, list) { | ||
2236 | nilfs_segment_usage_set_volatile_active(ent->raw_su); | ||
2237 | } | ||
2238 | up_write(&nilfs->ns_sem); | ||
2239 | } | 2232 | } |
2240 | 2233 | ||
2241 | static int nilfs_segctor_deactivate_segments(struct nilfs_sc_info *sci, | 2234 | static int nilfs_segctor_deactivate_segments(struct nilfs_sc_info *sci, |
@@ -2244,7 +2237,6 @@ static int nilfs_segctor_deactivate_segments(struct nilfs_sc_info *sci, | |||
2244 | struct nilfs_segment_buffer *segbuf, *last; | 2237 | struct nilfs_segment_buffer *segbuf, *last; |
2245 | struct nilfs_segment_entry *ent; | 2238 | struct nilfs_segment_entry *ent; |
2246 | struct inode *sufile = nilfs->ns_sufile; | 2239 | struct inode *sufile = nilfs->ns_sufile; |
2247 | struct list_head *head; | ||
2248 | int err; | 2240 | int err; |
2249 | 2241 | ||
2250 | last = NILFS_LAST_SEGBUF(&sci->sc_segbufs); | 2242 | last = NILFS_LAST_SEGBUF(&sci->sc_segbufs); |
@@ -2265,22 +2257,13 @@ static int nilfs_segctor_deactivate_segments(struct nilfs_sc_info *sci, | |||
2265 | BUG_ON(!buffer_dirty(ent->bh_su)); | 2257 | BUG_ON(!buffer_dirty(ent->bh_su)); |
2266 | } | 2258 | } |
2267 | 2259 | ||
2268 | head = &sci->sc_active_segments; | 2260 | list_for_each_entry(ent, &sci->sc_active_segments, list) { |
2269 | list_for_each_entry(ent, head, list) { | ||
2270 | err = nilfs_open_segment_entry(ent, sufile); | 2261 | err = nilfs_open_segment_entry(ent, sufile); |
2271 | if (unlikely(err)) | 2262 | if (unlikely(err)) |
2272 | goto failed; | 2263 | goto failed; |
2273 | nilfs_segment_usage_clear_active(ent->raw_su); | 2264 | nilfs_segment_usage_clear_active(ent->raw_su); |
2274 | BUG_ON(!buffer_dirty(ent->bh_su)); | 2265 | BUG_ON(!buffer_dirty(ent->bh_su)); |
2275 | } | 2266 | } |
2276 | |||
2277 | down_write(&nilfs->ns_sem); | ||
2278 | head = &nilfs->ns_used_segments; | ||
2279 | list_for_each_entry(ent, head, list) { | ||
2280 | /* clear volatile active for segments of older generations */ | ||
2281 | nilfs_segment_usage_clear_volatile_active(ent->raw_su); | ||
2282 | } | ||
2283 | up_write(&nilfs->ns_sem); | ||
2284 | return 0; | 2267 | return 0; |
2285 | 2268 | ||
2286 | failed: | 2269 | failed: |
@@ -2304,19 +2287,15 @@ static void nilfs_segctor_bead_completed_segments(struct nilfs_sc_info *sci) | |||
2304 | } | 2287 | } |
2305 | } | 2288 | } |
2306 | 2289 | ||
2307 | static void | 2290 | static void nilfs_segctor_commit_deactivate_segments(struct nilfs_sc_info *sci, |
2308 | __nilfs_segctor_commit_deactivate_segments(struct nilfs_sc_info *sci, | 2291 | struct the_nilfs *nilfs) |
2309 | struct the_nilfs *nilfs) | ||
2310 | |||
2311 | { | 2292 | { |
2312 | struct nilfs_segment_entry *ent; | 2293 | struct nilfs_segment_entry *ent, *n; |
2313 | |||
2314 | list_splice_init(&sci->sc_active_segments, | ||
2315 | nilfs->ns_used_segments.prev); | ||
2316 | 2294 | ||
2317 | list_for_each_entry(ent, &nilfs->ns_used_segments, list) { | 2295 | list_for_each_entry_safe(ent, n, &sci->sc_active_segments, list) { |
2318 | nilfs_segment_usage_set_volatile_active(ent->raw_su); | 2296 | list_del(&ent->list); |
2319 | /* These segments are kept open */ | 2297 | nilfs_close_segment_entry(ent, nilfs->ns_sufile); |
2298 | nilfs_free_segment_entry(ent); | ||
2320 | } | 2299 | } |
2321 | } | 2300 | } |
2322 | 2301 | ||
@@ -2405,8 +2384,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2405 | if (has_sr) { | 2384 | if (has_sr) { |
2406 | down_write(&nilfs->ns_sem); | 2385 | down_write(&nilfs->ns_sem); |
2407 | nilfs_update_last_segment(sbi, 1); | 2386 | nilfs_update_last_segment(sbi, 1); |
2408 | __nilfs_segctor_commit_deactivate_segments(sci, nilfs); | ||
2409 | up_write(&nilfs->ns_sem); | 2387 | up_write(&nilfs->ns_sem); |
2388 | nilfs_segctor_commit_deactivate_segments(sci, nilfs); | ||
2410 | nilfs_segctor_commit_free_segments(sci); | 2389 | nilfs_segctor_commit_free_segments(sci); |
2411 | nilfs_segctor_clear_metadata_dirty(sci); | 2390 | nilfs_segctor_clear_metadata_dirty(sci); |
2412 | } | 2391 | } |
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index b3674a8162a1..cc714c72b138 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -446,6 +446,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat) | |||
446 | { | 446 | { |
447 | struct buffer_head *header_bh; | 447 | struct buffer_head *header_bh; |
448 | struct nilfs_sufile_header *header; | 448 | struct nilfs_sufile_header *header; |
449 | struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs; | ||
449 | void *kaddr; | 450 | void *kaddr; |
450 | int ret; | 451 | int ret; |
451 | 452 | ||
@@ -460,8 +461,11 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat) | |||
460 | sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile); | 461 | sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile); |
461 | sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs); | 462 | sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs); |
462 | sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs); | 463 | sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs); |
463 | sustat->ss_ctime = NILFS_MDT(sufile)->mi_nilfs->ns_ctime; | 464 | sustat->ss_ctime = nilfs->ns_ctime; |
464 | sustat->ss_nongc_ctime = NILFS_MDT(sufile)->mi_nilfs->ns_nongc_ctime; | 465 | sustat->ss_nongc_ctime = nilfs->ns_nongc_ctime; |
466 | spin_lock(&nilfs->ns_last_segment_lock); | ||
467 | sustat->ss_prot_seq = nilfs->ns_prot_seq; | ||
468 | spin_unlock(&nilfs->ns_last_segment_lock); | ||
465 | kunmap_atomic(kaddr, KM_USER0); | 469 | kunmap_atomic(kaddr, KM_USER0); |
466 | brelse(header_bh); | 470 | brelse(header_bh); |
467 | 471 | ||
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 268b563d215a..2f0e9f7bf152 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -262,8 +262,10 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi) | |||
262 | printk(KERN_ERR | 262 | printk(KERN_ERR |
263 | "NILFS: unable to write superblock (err=%d)\n", err); | 263 | "NILFS: unable to write superblock (err=%d)\n", err); |
264 | else { | 264 | else { |
265 | nilfs_dispose_used_segments(nilfs); | ||
266 | clear_nilfs_discontinued(nilfs); | 265 | clear_nilfs_discontinued(nilfs); |
266 | spin_lock(&nilfs->ns_last_segment_lock); | ||
267 | nilfs->ns_prot_seq = le64_to_cpu(nilfs->ns_sbp->s_last_seq); | ||
268 | spin_unlock(&nilfs->ns_last_segment_lock); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | return err; | 271 | return err; |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 69b625586226..661ab762d765 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -71,7 +71,6 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev) | |||
71 | INIT_LIST_HEAD(&nilfs->ns_supers); | 71 | INIT_LIST_HEAD(&nilfs->ns_supers); |
72 | spin_lock_init(&nilfs->ns_last_segment_lock); | 72 | spin_lock_init(&nilfs->ns_last_segment_lock); |
73 | nilfs->ns_gc_inodes_h = NULL; | 73 | nilfs->ns_gc_inodes_h = NULL; |
74 | INIT_LIST_HEAD(&nilfs->ns_used_segments); | ||
75 | init_rwsem(&nilfs->ns_segctor_sem); | 74 | init_rwsem(&nilfs->ns_segctor_sem); |
76 | 75 | ||
77 | return nilfs; | 76 | return nilfs; |
@@ -95,7 +94,6 @@ void put_nilfs(struct the_nilfs *nilfs) | |||
95 | */ | 94 | */ |
96 | might_sleep(); | 95 | might_sleep(); |
97 | if (nilfs_loaded(nilfs)) { | 96 | if (nilfs_loaded(nilfs)) { |
98 | nilfs_dispose_used_segments(nilfs); | ||
99 | nilfs_mdt_clear(nilfs->ns_sufile); | 97 | nilfs_mdt_clear(nilfs->ns_sufile); |
100 | nilfs_mdt_destroy(nilfs->ns_sufile); | 98 | nilfs_mdt_destroy(nilfs->ns_sufile); |
101 | nilfs_mdt_clear(nilfs->ns_cpfile); | 99 | nilfs_mdt_clear(nilfs->ns_cpfile); |
@@ -463,22 +461,6 @@ int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks) | |||
463 | return err; | 461 | return err; |
464 | } | 462 | } |
465 | 463 | ||
466 | void nilfs_dispose_used_segments(struct the_nilfs *nilfs) | ||
467 | { | ||
468 | struct nilfs_segment_entry *ent, *n; | ||
469 | |||
470 | /* nilfs->sem must be locked by the caller. */ | ||
471 | if (!nilfs_loaded(nilfs)) | ||
472 | return; | ||
473 | |||
474 | list_for_each_entry_safe(ent, n, &nilfs->ns_used_segments, list) { | ||
475 | list_del_init(&ent->list); | ||
476 | nilfs_segment_usage_clear_volatile_active(ent->raw_su); | ||
477 | nilfs_close_segment_entry(ent, nilfs->ns_sufile); | ||
478 | nilfs_free_segment_entry(ent); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | int nilfs_near_disk_full(struct the_nilfs *nilfs) | 464 | int nilfs_near_disk_full(struct the_nilfs *nilfs) |
483 | { | 465 | { |
484 | struct inode *sufile = nilfs->ns_sufile; | 466 | struct inode *sufile = nilfs->ns_sufile; |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 75da37306964..af566e78f7af 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -51,7 +51,6 @@ enum { | |||
51 | * @ns_writer_refcount: number of referrers on ns_writer | 51 | * @ns_writer_refcount: number of referrers on ns_writer |
52 | * @ns_sbh: buffer head of the on-disk super block | 52 | * @ns_sbh: buffer head of the on-disk super block |
53 | * @ns_sbp: pointer to the super block data | 53 | * @ns_sbp: pointer to the super block data |
54 | * @ns_used_segments: list of full segments in volatile active state | ||
55 | * @ns_supers: list of nilfs super block structs | 54 | * @ns_supers: list of nilfs super block structs |
56 | * @ns_seg_seq: segment sequence counter | 55 | * @ns_seg_seq: segment sequence counter |
57 | * @ns_segnum: index number of the latest full segment. | 56 | * @ns_segnum: index number of the latest full segment. |
@@ -65,6 +64,7 @@ enum { | |||
65 | * @ns_last_pseg: start block number of the latest segment | 64 | * @ns_last_pseg: start block number of the latest segment |
66 | * @ns_last_seq: sequence value of the latest segment | 65 | * @ns_last_seq: sequence value of the latest segment |
67 | * @ns_last_cno: checkpoint number of the latest segment | 66 | * @ns_last_cno: checkpoint number of the latest segment |
67 | * @ns_prot_seq: least sequence number of segments which must not be reclaimed | ||
68 | * @ns_free_segments_count: counter of free segments | 68 | * @ns_free_segments_count: counter of free segments |
69 | * @ns_segctor_sem: segment constructor semaphore | 69 | * @ns_segctor_sem: segment constructor semaphore |
70 | * @ns_dat: DAT file inode | 70 | * @ns_dat: DAT file inode |
@@ -103,7 +103,6 @@ struct the_nilfs { | |||
103 | */ | 103 | */ |
104 | struct buffer_head *ns_sbh; | 104 | struct buffer_head *ns_sbh; |
105 | struct nilfs_super_block *ns_sbp; | 105 | struct nilfs_super_block *ns_sbp; |
106 | struct list_head ns_used_segments; | ||
107 | unsigned ns_mount_state; | 106 | unsigned ns_mount_state; |
108 | struct list_head ns_supers; | 107 | struct list_head ns_supers; |
109 | 108 | ||
@@ -132,6 +131,7 @@ struct the_nilfs { | |||
132 | sector_t ns_last_pseg; | 131 | sector_t ns_last_pseg; |
133 | u64 ns_last_seq; | 132 | u64 ns_last_seq; |
134 | __u64 ns_last_cno; | 133 | __u64 ns_last_cno; |
134 | u64 ns_prot_seq; | ||
135 | unsigned long ns_free_segments_count; | 135 | unsigned long ns_free_segments_count; |
136 | 136 | ||
137 | struct rw_semaphore ns_segctor_sem; | 137 | struct rw_semaphore ns_segctor_sem; |
@@ -188,7 +188,6 @@ void put_nilfs(struct the_nilfs *); | |||
188 | int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *); | 188 | int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *); |
189 | int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *); | 189 | int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *); |
190 | int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); | 190 | int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); |
191 | void nilfs_dispose_used_segments(struct the_nilfs *); | ||
192 | int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); | 191 | int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); |
193 | int nilfs_near_disk_full(struct the_nilfs *); | 192 | int nilfs_near_disk_full(struct the_nilfs *); |
194 | 193 | ||