Signed-off-by: Bob Peterson <[email protected]>
---
fs/gfs2/inode.c | 114 ++++++++++++++++++++++++--------------------------------
1 file changed, 49 insertions(+), 65 deletions(-)
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 2e2a8a2fb51d..d7a80b35910f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -912,13 +912,9 @@ static int gfs2_link(struct dentry *old_dentry, struct
inode *dir,
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
- error = gfs2_glock_nq(ghs); /* parent */
+ error = gfs2_glock_nq_m(2, ghs); /* inodes */
if (error)
- goto out_parent;
-
- error = gfs2_glock_nq(ghs + 1); /* child */
- if (error)
- goto out_child;
+ goto out_uninit;
error = -ENOENT;
if (inode->i_nlink == 0)
@@ -1004,10 +1000,8 @@ static int gfs2_link(struct dentry *old_dentry, struct
inode *dir,
gfs2_quota_unlock(dip);
out_gunlock:
gfs2_dir_no_add(&da);
- gfs2_glock_dq(ghs + 1);
-out_child:
- gfs2_glock_dq(ghs);
-out_parent:
+ gfs2_glock_dq_m(2, ghs);
+out_uninit:
gfs2_holder_uninit(ghs);
gfs2_holder_uninit(ghs + 1);
return error;
@@ -1100,7 +1094,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry
*dentry)
struct gfs2_sbd *sdp = GFS2_SB(dir);
struct inode *inode = d_inode(dentry);
struct gfs2_inode *ip = GFS2_I(inode);
- struct gfs2_holder ghs[3];
+ struct gfs2_holder ghs[2], rd_gh;
struct gfs2_rgrpd *rgd;
int error;
@@ -1108,60 +1102,48 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
if (error)
return error;
- error = -EROFS;
-
- gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
- gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
-
rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1);
if (!rgd)
- goto out_inodes;
-
- gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
+ return -EROFS;
+ gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
- error = gfs2_glock_nq(ghs); /* parent */
+ error = gfs2_glock_nq_m(2, ghs); /* inodes */
if (error)
- goto out_parent;
+ goto out_uninit;
- error = gfs2_glock_nq(ghs + 1); /* child */
+ error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rd_gh);
if (error)
- goto out_child;
+ goto out_gunlock;
- error = -ENOENT;
- if (inode->i_nlink == 0)
- goto out_rgrp;
+ if (inode->i_nlink == 0) {
+ error = -ENOENT;
+ goto out_rgunlock;
+ }
- if (S_ISDIR(inode->i_mode)) {
+ if (S_ISDIR(inode->i_mode) &&
+ (ip->i_entries > 2 || inode->i_nlink > 2)) {
error = -ENOTEMPTY;
- if (ip->i_entries > 2 || inode->i_nlink > 2)
- goto out_rgrp;
+ goto out_rgunlock;
}
- error = gfs2_glock_nq(ghs + 2); /* rgrp */
- if (error)
- goto out_rgrp;
-
error = gfs2_unlink_ok(dip, &dentry->d_name, ip);
if (error)
- goto out_gunlock;
+ goto out_rgunlock;
error = gfs2_trans_begin(sdp, 2*RES_DINODE + 3*RES_LEAF + RES_RG_BIT, 0);
if (error)
- goto out_gunlock;
+ goto out_rgunlock;
error = gfs2_unlink_inode(dip, dentry);
gfs2_trans_end(sdp);
+out_rgunlock:
+ gfs2_glock_dq_uninit(&rd_gh);
out_gunlock:
- gfs2_glock_dq(ghs + 2);
-out_rgrp:
- gfs2_glock_dq(ghs + 1);
-out_child:
- gfs2_glock_dq(ghs);
-out_parent:
- gfs2_holder_uninit(ghs + 2);
-out_inodes:
+ gfs2_glock_dq_m(2, ghs);
+out_uninit:
gfs2_holder_uninit(ghs + 1);
gfs2_holder_uninit(ghs);
return error;
@@ -1348,15 +1330,15 @@ static int gfs2_rename(struct inode *odir, struct
dentry *odentry,
struct gfs2_inode *ip = GFS2_I(d_inode(odentry));
struct gfs2_inode *nip = NULL;
struct gfs2_sbd *sdp = GFS2_SB(odir);
- struct gfs2_holder ghs[5], r_gh;
- struct gfs2_rgrpd *nrgd;
+ struct gfs2_holder ghs[4], r_gh, rd_gh;
+ struct gfs2_rgrpd *nrgd = NULL;
unsigned int num_gh;
int dir_rename = 0;
struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, };
- unsigned int x;
int error;
gfs2_holder_mark_uninitialized(&r_gh);
+ gfs2_holder_mark_uninitialized(&rd_gh);
if (d_really_is_positive(ndentry)) {
nip = GFS2_I(d_inode(ndentry));
if (ip == nip)
@@ -1403,12 +1385,15 @@ static int gfs2_rename(struct inode *odir, struct
dentry *odentry,
* so we unlink before doing the rename
*/
nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr, 1);
- if (nrgd)
- gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs +
num_gh++);
}
- for (x = 0; x < num_gh; x++) {
- error = gfs2_glock_nq(ghs + x);
+ error = gfs2_glock_nq_m(num_gh, ghs);
+ if (error)
+ goto out_uninit;
+
+ if (nrgd) {
+ error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0,
+ &rd_gh);
if (error)
goto out_gunlock;
}
@@ -1541,10 +1526,12 @@ static int gfs2_rename(struct inode *odir, struct
dentry *odentry,
gfs2_quota_unlock(ndip);
out_gunlock:
gfs2_dir_no_add(&da);
- while (x--) {
- gfs2_glock_dq(ghs + x);
- gfs2_holder_uninit(ghs + x);
- }
+ if (gfs2_holder_initialized(&rd_gh))
+ gfs2_glock_dq_uninit(&rd_gh);
+ gfs2_glock_dq_m(num_gh, ghs);
+out_uninit:
+ while (num_gh--)
+ gfs2_holder_uninit(ghs + num_gh);
out_gunlock_r:
if (gfs2_holder_initialized(&r_gh))
gfs2_glock_dq_uninit(&r_gh);
@@ -1572,9 +1559,8 @@ static int gfs2_exchange(struct inode *odir, struct
dentry *odentry,
struct gfs2_inode *oip = GFS2_I(odentry->d_inode);
struct gfs2_inode *nip = GFS2_I(ndentry->d_inode);
struct gfs2_sbd *sdp = GFS2_SB(odir);
- struct gfs2_holder ghs[5], r_gh;
+ struct gfs2_holder ghs[4], r_gh;
unsigned int num_gh;
- unsigned int x;
umode_t old_mode = oip->i_inode.i_mode;
umode_t new_mode = nip->i_inode.i_mode;
int error;
@@ -1617,11 +1603,9 @@ static int gfs2_exchange(struct inode *odir, struct
dentry *odentry,
gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
num_gh++;
- for (x = 0; x < num_gh; x++) {
- error = gfs2_glock_nq(ghs + x);
- if (error)
- goto out_gunlock;
- }
+ error = gfs2_glock_nq_m(num_gh, ghs);
+ if (error)
+ goto out_guninit;
error = -ENOENT;
if (oip->i_inode.i_nlink == 0 || nip->i_inode.i_nlink == 0)
@@ -1682,10 +1666,10 @@ static int gfs2_exchange(struct inode *odir, struct
dentry *odentry,
out_end_trans:
gfs2_trans_end(sdp);
out_gunlock:
- while (x--) {
- gfs2_glock_dq(ghs + x);
- gfs2_holder_uninit(ghs + x);
- }
+ gfs2_glock_dq_m(num_gh, ghs);
+out_guninit:
+ while (num_gh--)
+ gfs2_holder_uninit(ghs + num_gh);
out_gunlock_r:
if (gfs2_holder_initialized(&r_gh))
gfs2_glock_dq_uninit(&r_gh);