Commit 85c2a74f authored by Ryusuke Konishi's avatar Ryusuke Konishi

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: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent 091bf762
...@@ -407,6 +407,7 @@ void nilfs_dispose_segment_list(struct list_head *head) ...@@ -407,6 +407,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
} }
static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi,
struct nilfs_recovery_info *ri) struct nilfs_recovery_info *ri)
{ {
struct list_head *head = &ri->ri_used_segments; struct list_head *head = &ri->ri_used_segments;
...@@ -421,6 +422,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, ...@@ -421,6 +422,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
segnum[2] = ri->ri_segnum; segnum[2] = ri->ri_segnum;
segnum[3] = ri->ri_nextnum; segnum[3] = ri->ri_nextnum;
nilfs_attach_writer(nilfs, sbi);
/* /*
* Releasing the next segment of the latest super root. * Releasing the next segment of the latest super root.
* The next segment is invalidated by this recovery. * The next segment is invalidated by this recovery.
...@@ -459,10 +461,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, ...@@ -459,10 +461,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
nilfs->ns_pseg_offset = 0; nilfs->ns_pseg_offset = 0;
nilfs->ns_seg_seq = ri->ri_seq + 2; nilfs->ns_seg_seq = ri->ri_seq + 2;
nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0]; nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0];
return 0;
failed: failed:
/* No need to recover sufile because it will be destroyed on error */ /* No need to recover sufile because it will be destroyed on error */
nilfs_detach_writer(nilfs, sbi);
return err; return err;
} }
...@@ -728,7 +730,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, ...@@ -728,7 +730,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
goto failed; goto failed;
if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) { if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
err = nilfs_prepare_segment_for_recovery(nilfs, ri); err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri);
if (unlikely(err)) { if (unlikely(err)) {
printk(KERN_ERR "NILFS: Error preparing segments for " printk(KERN_ERR "NILFS: Error preparing segments for "
"recovery.\n"); "recovery.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment