summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse2006-04-07 22:28:07 +0200
committerSteven Whitehouse2006-04-07 22:28:07 +0200
commited3865079b573ef55dc13ab0bfb242ed5ebab4c1 (patch)
tree805051b854553a04cc6bb5082a74e3030216372b
parent[GFS2] Fix a ref count bug and other clean ups (diff)
downloadkernel-qcow2-linux-ed3865079b573ef55dc13ab0bfb242ed5ebab4c1.tar.gz
kernel-qcow2-linux-ed3865079b573ef55dc13ab0bfb242ed5ebab4c1.tar.xz
kernel-qcow2-linux-ed3865079b573ef55dc13ab0bfb242ed5ebab4c1.zip
[GFS2] Finally get ref counting correct
The last patch missed some other instances of incorrect ref counting, this fixes all of those too. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/dir.c17
-rw-r--r--fs/gfs2/log.c2
2 files changed, 13 insertions, 6 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 316eed688f8e..100672d2c6c5 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -776,9 +776,9 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
goto got_dent;
leaf = (struct gfs2_leaf *)bh->b_data;
ln = be64_to_cpu(leaf->lf_next);
- brelse(bh);
if (!ln)
break;
+ brelse(bh);
error = get_leaf(ip, ln, &bh);
} while(!error);
@@ -789,9 +789,11 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
if (error)
return ERR_PTR(error);
dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
- brelse(bh);
-
got_dent:
+ if (unlikely(IS_ERR(dent))) {
+ brelse(bh);
+ bh = NULL;
+ }
*pbh = bh;
return dent;
}
@@ -1475,6 +1477,7 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *name,
brelse(bh);
return 0;
}
+ brelse(bh);
return -ENOENT;
}
@@ -1616,6 +1619,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
previous entry otherwise */
dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh);
if (!dent) {
+ brelse(bh);
gfs2_consist_inode(dip);
return -EIO;
}
@@ -1636,8 +1640,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
if (!entries)
gfs2_consist_inode(dip);
leaf->lf_entries = cpu_to_be16(--entries);
- brelse(bh);
}
+ brelse(bh);
error = gfs2_meta_inode_buffer(dip, &bh);
if (error)
@@ -1676,6 +1680,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh);
if (!dent) {
+ brelse(bh);
gfs2_consist_inode(dip);
return -EIO;
}
@@ -1955,8 +1960,10 @@ int gfs2_diradd_alloc_required(struct inode *inode,
struct buffer_head *bh;
dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
- if (!dent)
+ if (!dent) {
+ brelse(bh);
return 1;
+ }
if (IS_ERR(dent))
return PTR_ERR(dent);
brelse(bh);
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index cadfef193e55..0b26d6a74118 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -196,7 +196,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
{
- up_read(&sdp->sd_log_flush_lock);
gfs2_log_lock(sdp);
sdp->sd_log_blks_free += blks;
@@ -204,6 +203,7 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
gfs2_assert_withdraw(sdp,
sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
gfs2_log_unlock(sdp);
+ up_read(&sdp->sd_log_flush_lock);
}
static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)