diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-04-28 10:38:46 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-05-09 00:36:56 -0400 |
commit | 85c2a74fabadfc561b75fbd7decc6bcbfe873d57 (patch) | |
tree | ad0adcd8377412184a9a5bac9fea3191cbea29ca /fs/nilfs2/recovery.c | |
parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) |
nilfs2: fix possible recovery failure due to block creation without writer
Some function calls in nilfs_prepare_segment_for_recovery() may fail
because they can create blocks on meta data files without configuring
a writable FS-instance. Concretely, nilfs_mdt_create_block() routine
of meta data files will fail in that case.
This fixes the problem by temporarily attaching a writable FS-instace
during the function is called.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/recovery.c')
-rw-r--r-- | fs/nilfs2/recovery.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index 4fc081e47d70..57afa9d24061 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -407,6 +407,7 @@ void nilfs_dispose_segment_list(struct list_head *head) | |||
407 | } | 407 | } |
408 | 408 | ||
409 | static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | 409 | static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, |
410 | struct nilfs_sb_info *sbi, | ||
410 | struct nilfs_recovery_info *ri) | 411 | struct nilfs_recovery_info *ri) |
411 | { | 412 | { |
412 | struct list_head *head = &ri->ri_used_segments; | 413 | struct list_head *head = &ri->ri_used_segments; |
@@ -421,6 +422,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
421 | segnum[2] = ri->ri_segnum; | 422 | segnum[2] = ri->ri_segnum; |
422 | segnum[3] = ri->ri_nextnum; | 423 | segnum[3] = ri->ri_nextnum; |
423 | 424 | ||
425 | nilfs_attach_writer(nilfs, sbi); | ||
424 | /* | 426 | /* |
425 | * Releasing the next segment of the latest super root. | 427 | * Releasing the next segment of the latest super root. |
426 | * The next segment is invalidated by this recovery. | 428 | * The next segment is invalidated by this recovery. |
@@ -459,10 +461,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, | |||
459 | nilfs->ns_pseg_offset = 0; | 461 | nilfs->ns_pseg_offset = 0; |
460 | nilfs->ns_seg_seq = ri->ri_seq + 2; | 462 | nilfs->ns_seg_seq = ri->ri_seq + 2; |
461 | nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; | 463 | nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; |
462 | return 0; | ||
463 | 464 | ||
464 | failed: | 465 | failed: |
465 | /* No need to recover sufile because it will be destroyed on error */ | 466 | /* No need to recover sufile because it will be destroyed on error */ |
467 | nilfs_detach_writer(nilfs, sbi); | ||
466 | return err; | 468 | return err; |
467 | } | 469 | } |
468 | 470 | ||
@@ -728,7 +730,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, | |||
728 | goto failed; | 730 | goto failed; |
729 | 731 | ||
730 | if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { | 732 | if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { |
731 | err = nilfs_prepare_segment_for_recovery(nilfs, ri); | 733 | err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri); |
732 | if (unlikely(err)) { | 734 | if (unlikely(err)) { |
733 | printk(KERN_ERR "NILFS: Error preparing segments for " | 735 | printk(KERN_ERR "NILFS: Error preparing segments for " |
734 | "recovery.\n"); | 736 | "recovery.\n"); |