]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/gfs2/inode.c
docs: driver-api: pti_intel_mid: Enable syntax highlighting for C code block
[linux.git] / fs / gfs2 / inode.c
index 2e2a8a2fb51dd6b95e478ad711ace6ac940d9852..e1e18fb587eba4541909953e58bcd64f528168ae 100644 (file)
@@ -1348,7 +1348,7 @@ 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_holder ghs[4], r_gh, rd_gh;
        struct gfs2_rgrpd *nrgd;
        unsigned int num_gh;
        int dir_rename = 0;
@@ -1357,6 +1357,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        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)
@@ -1387,24 +1388,19 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        }
 
        num_gh = 1;
-       gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
+       gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs);
        if (odip != ndip) {
-               gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+               gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE,GL_ASYNC,
+                                ghs + num_gh);
                num_gh++;
        }
-       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
        num_gh++;
 
        if (nip) {
-               gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+               gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC,
+                                ghs + 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_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++) {
@@ -1412,6 +1408,25 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                if (error)
                        goto out_gunlock;
        }
+       error = gfs2_glock_async_wait(num_gh, ghs);
+       if (error)
+               goto out_gunlock;
+
+       if (nip) {
+               /* Grab the resource group glock for unlink flag twiddling.
+                * This is the case where the target dinode already exists
+                * so we unlink before doing the rename.
+                */
+               nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr, 1);
+               if (!nrgd) {
+                       error = -ENOENT;
+                       goto out_gunlock;
+               }
+               error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0,
+                                          &rd_gh);
+               if (error)
+                       goto out_gunlock;
+       }
 
        error = -ENOENT;
        if (ip->i_inode.i_nlink == 0)
@@ -1541,8 +1556,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                gfs2_quota_unlock(ndip);
 out_gunlock:
        gfs2_dir_no_add(&da);
+       if (gfs2_holder_initialized(&rd_gh))
+               gfs2_glock_dq_uninit(&rd_gh);
+
        while (x--) {
-               gfs2_glock_dq(ghs + x);
+               if (gfs2_holder_queued(ghs + x))
+                       gfs2_glock_dq(ghs + x);
                gfs2_holder_uninit(ghs + x);
        }
 out_gunlock_r:
@@ -1572,7 +1591,7 @@ 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;
@@ -1606,15 +1625,16 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
        }
 
        num_gh = 1;
-       gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
+       gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs);
        if (odip != ndip) {
-               gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+               gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC,
+                                ghs + num_gh);
                num_gh++;
        }
-       gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+       gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
        num_gh++;
 
-       gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
+       gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh);
        num_gh++;
 
        for (x = 0; x < num_gh; x++) {
@@ -1623,6 +1643,10 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
                        goto out_gunlock;
        }
 
+       error = gfs2_glock_async_wait(num_gh, ghs);
+       if (error)
+               goto out_gunlock;
+
        error = -ENOENT;
        if (oip->i_inode.i_nlink == 0 || nip->i_inode.i_nlink == 0)
                goto out_gunlock;
@@ -1683,7 +1707,8 @@ static int gfs2_exchange(struct inode *odir, struct dentry *odentry,
        gfs2_trans_end(sdp);
 out_gunlock:
        while (x--) {
-               gfs2_glock_dq(ghs + x);
+               if (gfs2_holder_queued(ghs + x))
+                       gfs2_glock_dq(ghs + x);
                gfs2_holder_uninit(ghs + x);
        }
 out_gunlock_r: