Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2...
[linux-2.6-microblaze.git] / fs / gfs2 / inode.c
index 1bae189..3e94400 100644 (file)
@@ -191,13 +191,13 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
 fail_refresh:
        ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
        ip->i_iopen_gh.gh_gl->gl_object = NULL;
-       gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+       gfs2_glock_dq_wait(&ip->i_iopen_gh);
+       gfs2_holder_uninit(&ip->i_iopen_gh);
 fail_iopen:
        if (io_gl)
                gfs2_glock_put(io_gl);
 fail_put:
        ip->i_gl->gl_object = NULL;
-       gfs2_glock_put(ip->i_gl);
 fail:
        iget_failed(inode);
        return ERR_PTR(error);
@@ -593,7 +593,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        struct gfs2_inode *dip = GFS2_I(dir), *ip;
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
        struct gfs2_glock *io_gl;
-       int error, free_vfs_inode = 0;
+       int error, free_vfs_inode = 1;
        u32 aflags = 0;
        unsigned blocks = 1;
        struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
@@ -601,7 +601,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        if (!name->len || name->len > GFS2_FNAMESIZE)
                return -ENAMETOOLONG;
 
-       error = gfs2_rs_alloc(dip);
+       error = gfs2_rsqa_alloc(dip);
        if (error)
                return error;
 
@@ -650,10 +650,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
 
        error = posix_acl_create(dir, &mode, &default_acl, &acl);
        if (error)
-               goto fail_free_vfs_inode;
+               goto fail_gunlock;
 
        ip = GFS2_I(inode);
-       error = gfs2_rs_alloc(ip);
+       error = gfs2_rsqa_alloc(ip);
        if (error)
                goto fail_free_acls;
 
@@ -685,6 +685,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
                ip->i_entries = 2;
                break;
        }
+
+       /* Force SYSTEM flag on all files and subdirs of a SYSTEM directory */
+       if (dip->i_diskflags & GFS2_DIF_SYSTEM)
+               ip->i_diskflags |= GFS2_DIF_SYSTEM;
+
        gfs2_set_inode_flags(inode);
 
        if ((GFS2_I(d_inode(sdp->sd_root_dir)) == dip) ||
@@ -733,6 +738,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        gfs2_set_iop(inode);
        insert_inode_hash(inode);
 
+       free_vfs_inode = 0; /* After this point, the inode is no longer
+                              considered free. Any failures need to undo
+                              the gfs2 structures. */
        if (default_acl) {
                error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
                posix_acl_release(default_acl);
@@ -766,24 +774,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
        return error;
 
 fail_gunlock3:
-       gfs2_glock_dq_uninit(ghs + 1);
-       if (ip->i_gl)
-               gfs2_glock_put(ip->i_gl);
-       goto fail_gunlock;
-
+       gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+       gfs2_glock_put(io_gl);
 fail_gunlock2:
        gfs2_glock_dq_uninit(ghs + 1);
 fail_free_inode:
        if (ip->i_gl)
                gfs2_glock_put(ip->i_gl);
-       gfs2_rs_delete(ip, NULL);
+       gfs2_rsqa_delete(ip, NULL);
 fail_free_acls:
        if (default_acl)
                posix_acl_release(default_acl);
        if (acl)
                posix_acl_release(acl);
-fail_free_vfs_inode:
-       free_vfs_inode = 1;
 fail_gunlock:
        gfs2_dir_no_add(&da);
        gfs2_glock_dq_uninit(ghs);
@@ -898,7 +901,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        if (S_ISDIR(inode->i_mode))
                return -EPERM;
 
-       error = gfs2_rs_alloc(dip);
+       error = gfs2_rsqa_alloc(dip);
        if (error)
                return error;
 
@@ -1371,7 +1374,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        if (error)
                return error;
 
-       error = gfs2_rs_alloc(ndip);
+       error = gfs2_rsqa_alloc(ndip);
        if (error)
                return error;
 
@@ -1860,11 +1863,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
        if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid))
                ogid = ngid = NO_GID_QUOTA_CHANGE;
 
-       error = get_write_access(inode);
-       if (error)
-               return error;
-
-       error = gfs2_rs_alloc(ip);
+       error = gfs2_rsqa_alloc(ip);
        if (error)
                goto out;
 
@@ -1904,7 +1903,6 @@ out_end_trans:
 out_gunlock_q:
        gfs2_quota_unlock(ip);
 out:
-       put_write_access(inode);
        return error;
 }
 
@@ -1926,7 +1924,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
        struct gfs2_holder i_gh;
        int error;
 
-       error = gfs2_rs_alloc(ip);
+       error = gfs2_rsqa_alloc(ip);
        if (error)
                return error;
 
@@ -2008,7 +2006,7 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret == 0) {
-               ret = gfs2_rs_alloc(ip);
+               ret = gfs2_rsqa_alloc(ip);
                if (ret == 0)
                        ret = generic_setxattr(dentry, name, data, size, flags);
                gfs2_glock_dq(&gh);
@@ -2049,7 +2047,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret == 0) {
-               ret = gfs2_rs_alloc(ip);
+               ret = gfs2_rsqa_alloc(ip);
                if (ret == 0)
                        ret = generic_removexattr(dentry, name);
                gfs2_glock_dq(&gh);