aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/sufile.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-05 05:30:58 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-12 20:53:52 -0400
commitc85399c2da8b86de8f6877980294fa1a4a88a5a4 (patch)
tree0319b8ab4d8b7da4d614e46949755b8a9ba4eab0 /fs/nilfs2/sufile.c
parenta703018f7bbec8109419318f5d51f235fdce5155 (diff)
nilfs2: fix possible mismatch of sufile counters on recovery
On-disk counters ndirtysegs and ncleansegs of sufile, can go wrong after roll-forward recovery because nilfs_prepare_segment_for_recovery() function marks segments dirty without adjusting value of these counters. This fixes the problem by adding a function to sufile which does the operation adjusting the counters, and by letting the recovery function use it. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/sufile.c')
-rw-r--r--fs/nilfs2/sufile.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 07013f58dfe9..98e68677f045 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -258,6 +258,35 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
258 nilfs_mdt_mark_dirty(sufile); 258 nilfs_mdt_mark_dirty(sufile);
259} 259}
260 260
261void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
262 struct buffer_head *header_bh,
263 struct buffer_head *su_bh)
264{
265 struct nilfs_segment_usage *su;
266 void *kaddr;
267 int clean, dirty;
268
269 kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
270 su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
271 if (su->su_flags == cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY) &&
272 su->su_nblocks == cpu_to_le32(0)) {
273 kunmap_atomic(kaddr, KM_USER0);
274 return;
275 }
276 clean = nilfs_segment_usage_clean(su);
277 dirty = nilfs_segment_usage_dirty(su);
278
279 /* make the segment garbage */
280 su->su_lastmod = cpu_to_le64(0);
281 su->su_nblocks = cpu_to_le32(0);
282 su->su_flags = cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY);
283 kunmap_atomic(kaddr, KM_USER0);
284
285 nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
286 nilfs_mdt_mark_buffer_dirty(su_bh);
287 nilfs_mdt_mark_dirty(sufile);
288}
289
261void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum, 290void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
262 struct buffer_head *header_bh, 291 struct buffer_head *header_bh,
263 struct buffer_head *su_bh) 292 struct buffer_head *su_bh)