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>
This commit is contained in:
@@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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");
|
||||||
|
Reference in New Issue
Block a user