|
@@ -264,13 +264,23 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
|
struct gfs2_inode *dip = GFS2_I(dir);
|
|
struct gfs2_inode *dip = GFS2_I(dir);
|
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
|
- struct gfs2_holder ghs[2];
|
|
|
|
|
|
+ struct gfs2_holder ghs[3];
|
|
|
|
+ struct gfs2_rgrpd *rgd;
|
|
|
|
+ struct gfs2_holder ri_gh;
|
|
int error;
|
|
int error;
|
|
|
|
|
|
|
|
+ error = gfs2_rindex_hold(sdp, &ri_gh);
|
|
|
|
+ if (error)
|
|
|
|
+ return error;
|
|
|
|
+
|
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
|
- gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
|
|
|
|
|
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
|
|
|
|
|
- error = gfs2_glock_nq_m(2, ghs);
|
|
|
|
|
|
+ rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
|
|
|
|
+ gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ error = gfs2_glock_nq_m(3, ghs);
|
|
if (error)
|
|
if (error)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
@@ -291,10 +301,12 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
|
out_end_trans:
|
|
out_end_trans:
|
|
gfs2_trans_end(sdp);
|
|
gfs2_trans_end(sdp);
|
|
out_gunlock:
|
|
out_gunlock:
|
|
- gfs2_glock_dq_m(2, ghs);
|
|
|
|
|
|
+ gfs2_glock_dq_m(3, ghs);
|
|
out:
|
|
out:
|
|
gfs2_holder_uninit(ghs);
|
|
gfs2_holder_uninit(ghs);
|
|
gfs2_holder_uninit(ghs + 1);
|
|
gfs2_holder_uninit(ghs + 1);
|
|
|
|
+ gfs2_holder_uninit(ghs + 2);
|
|
|
|
+ gfs2_glock_dq_uninit(&ri_gh);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -449,13 +461,22 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
|
struct gfs2_inode *dip = GFS2_I(dir);
|
|
struct gfs2_inode *dip = GFS2_I(dir);
|
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
|
struct gfs2_sbd *sdp = GFS2_SB(dir);
|
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
|
- struct gfs2_holder ghs[2];
|
|
|
|
|
|
+ struct gfs2_holder ghs[3];
|
|
|
|
+ struct gfs2_rgrpd *rgd;
|
|
|
|
+ struct gfs2_holder ri_gh;
|
|
int error;
|
|
int error;
|
|
|
|
|
|
|
|
+
|
|
|
|
+ error = gfs2_rindex_hold(sdp, &ri_gh);
|
|
|
|
+ if (error)
|
|
|
|
+ return error;
|
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
|
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
|
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
|
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
|
|
|
|
|
- error = gfs2_glock_nq_m(2, ghs);
|
|
|
|
|
|
+ rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
|
|
|
|
+ gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
|
|
|
|
+
|
|
|
|
+ error = gfs2_glock_nq_m(3, ghs);
|
|
if (error)
|
|
if (error)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
@@ -483,10 +504,12 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
|
|
gfs2_trans_end(sdp);
|
|
gfs2_trans_end(sdp);
|
|
|
|
|
|
out_gunlock:
|
|
out_gunlock:
|
|
- gfs2_glock_dq_m(2, ghs);
|
|
|
|
|
|
+ gfs2_glock_dq_m(3, ghs);
|
|
out:
|
|
out:
|
|
gfs2_holder_uninit(ghs);
|
|
gfs2_holder_uninit(ghs);
|
|
gfs2_holder_uninit(ghs + 1);
|
|
gfs2_holder_uninit(ghs + 1);
|
|
|
|
+ gfs2_holder_uninit(ghs + 2);
|
|
|
|
+ gfs2_glock_dq_uninit(&ri_gh);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -547,7 +570,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
|
struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
|
|
struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
|
|
struct gfs2_inode *nip = NULL;
|
|
struct gfs2_inode *nip = NULL;
|
|
struct gfs2_sbd *sdp = GFS2_SB(odir);
|
|
struct gfs2_sbd *sdp = GFS2_SB(odir);
|
|
- struct gfs2_holder ghs[4], r_gh;
|
|
|
|
|
|
+ struct gfs2_holder ghs[5], r_gh;
|
|
|
|
+ struct gfs2_rgrpd *nrgd;
|
|
unsigned int num_gh;
|
|
unsigned int num_gh;
|
|
int dir_rename = 0;
|
|
int dir_rename = 0;
|
|
int alloc_required;
|
|
int alloc_required;
|
|
@@ -587,6 +611,13 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
|
if (nip) {
|
|
if (nip) {
|
|
gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
|
|
gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
|
|
num_gh++;
|
|
num_gh++;
|
|
|
|
+ /* grab the resource lock for unlink flag twiddling
|
|
|
|
+ * this is the case of the target file already existing
|
|
|
|
+ * so we unlink before doing the rename
|
|
|
|
+ */
|
|
|
|
+ nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr);
|
|
|
|
+ if (nrgd)
|
|
|
|
+ gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
|
|
}
|
|
}
|
|
|
|
|
|
error = gfs2_glock_nq_m(num_gh, ghs);
|
|
error = gfs2_glock_nq_m(num_gh, ghs);
|