Browse Source

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>
Ryusuke Konishi 16 years ago
parent
commit
85c2a74fab
1 changed files with 4 additions and 2 deletions
  1. 4 2
      fs/nilfs2/recovery.c

+ 4 - 2
fs/nilfs2/recovery.c

@@ -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");