diff options
author | Steven Whitehouse | 2006-04-07 22:28:07 +0200 |
---|---|---|
committer | Steven Whitehouse | 2006-04-07 22:28:07 +0200 |
commit | ed3865079b573ef55dc13ab0bfb242ed5ebab4c1 (patch) | |
tree | 805051b854553a04cc6bb5082a74e3030216372b | |
parent | [GFS2] Fix a ref count bug and other clean ups (diff) | |
download | kernel-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.c | 17 | ||||
-rw-r--r-- | fs/gfs2/log.c | 2 |
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) |