nilfs2: fix bh leak in nilfs_cpfile_delete_checkpoints function
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Sat, 30 May 2009 12:50:58 +0000 (21:50 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Sat, 30 May 2009 13:07:50 +0000 (22:07 +0900)
The nilfs_cpfile_delete_checkpoints() wrongly skips brelse() for the
header block of checkpoint file in case of errors.  This fixes the
leak bug.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
fs/nilfs2/cpfile.c

index e90b60dfced9c40f728546400940f6ff12afb5a9..300f1cdfa8620ab27cbc247d42f0850b011b4ce8 100644 (file)
@@ -311,7 +311,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
                ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
                if (ret < 0) {
                        if (ret != -ENOENT)
                ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
                if (ret < 0) {
                        if (ret != -ENOENT)
-                               goto out_sem;
+                               goto out_header;
                        /* skip hole */
                        ret = 0;
                        continue;
                        /* skip hole */
                        ret = 0;
                        continue;
@@ -344,7 +344,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
                                        continue;
                                printk(KERN_ERR "%s: cannot delete block\n",
                                       __func__);
                                        continue;
                                printk(KERN_ERR "%s: cannot delete block\n",
                                       __func__);
-                               goto out_sem;
+                               goto out_header;
                        }
                }
 
                        }
                }
 
@@ -361,6 +361,8 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
                nilfs_mdt_mark_dirty(cpfile);
                kunmap_atomic(kaddr, KM_USER0);
        }
                nilfs_mdt_mark_dirty(cpfile);
                kunmap_atomic(kaddr, KM_USER0);
        }
+
+ out_header:
        brelse(header_bh);
 
  out_sem:
        brelse(header_bh);
 
  out_sem: