]> Pileus Git - ~andy/linux/blobdiff - fs/gfs2/ops_inode.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[~andy/linux] / fs / gfs2 / ops_inode.c
index 6cbbb5b46ce4b7a6712dcd04261fc52a0337823b..1e252dfc52940c745dea61137afc386dbe183cd7 100644 (file)
@@ -163,7 +163,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
        if (error)
                goto out;
 
-       error = permission(dir, MAY_WRITE | MAY_EXEC, NULL);
+       error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
        if (error)
                goto out_gunlock;
 
@@ -200,15 +200,15 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
 
        if (alloc_required) {
                struct gfs2_alloc *al = gfs2_alloc_get(dip);
+               if (!al) {
+                       error = -ENOMEM;
+                       goto out_gunlock;
+               }
 
-               error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+               error = gfs2_quota_lock_check(dip);
                if (error)
                        goto out_alloc;
 
-               error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid);
-               if (error)
-                       goto out_gunlock_q;
-
                al->al_requested = sdp->sd_max_dirres;
 
                error = gfs2_inplace_reserve(dip);
@@ -669,7 +669,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
                        }
                }
        } else {
-               error = permission(ndir, MAY_WRITE | MAY_EXEC, NULL);
+               error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC);
                if (error)
                        goto out_gunlock;
 
@@ -704,7 +704,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
        /* Check out the dir to be renamed */
 
        if (dir_rename) {
-               error = permission(odentry->d_inode, MAY_WRITE, NULL);
+               error = gfs2_permission(odentry->d_inode, MAY_WRITE);
                if (error)
                        goto out_gunlock;
        }
@@ -716,15 +716,15 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 
        if (alloc_required) {
                struct gfs2_alloc *al = gfs2_alloc_get(ndip);
+               if (!al) {
+                       error = -ENOMEM;
+                       goto out_gunlock;
+               }
 
-               error = gfs2_quota_lock(ndip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+               error = gfs2_quota_lock_check(ndip);
                if (error)
                        goto out_alloc;
 
-               error = gfs2_quota_check(ndip, ndip->i_inode.i_uid, ndip->i_inode.i_gid);
-               if (error)
-                       goto out_gunlock_q;
-
                al->al_requested = sdp->sd_max_dirres;
 
                error = gfs2_inplace_reserve(ndip);
@@ -891,7 +891,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
  * Returns: errno
  */
 
-static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+int gfs2_permission(struct inode *inode, int mask)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_holder i_gh;
@@ -905,13 +905,22 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
                unlock = 1;
        }
 
-       error = generic_permission(inode, mask, gfs2_check_acl);
+       if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
+               error = -EACCES;
+       else
+               error = generic_permission(inode, mask, gfs2_check_acl);
        if (unlock)
                gfs2_glock_dq_uninit(&i_gh);
 
        return error;
 }
 
+static int gfs2_iop_permission(struct inode *inode, int mask,
+                              struct nameidata *nd)
+{
+       return gfs2_permission(inode, mask);
+}
+
 static int setattr_size(struct inode *inode, struct iattr *attr)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
@@ -953,7 +962,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
        if (!(attr->ia_valid & ATTR_GID) || ogid == ngid)
                ogid = ngid = NO_QUOTA_CHANGE;
 
-       gfs2_alloc_get(ip);
+       if (!gfs2_alloc_get(ip))
+               return -ENOMEM;
 
        error = gfs2_quota_lock(ip, nuid, ngid);
        if (error)
@@ -1140,7 +1150,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
 }
 
 const struct inode_operations gfs2_file_iops = {
-       .permission = gfs2_permission,
+       .permission = gfs2_iop_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,
@@ -1159,7 +1169,7 @@ const struct inode_operations gfs2_dir_iops = {
        .rmdir = gfs2_rmdir,
        .mknod = gfs2_mknod,
        .rename = gfs2_rename,
-       .permission = gfs2_permission,
+       .permission = gfs2_iop_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,
@@ -1171,7 +1181,7 @@ const struct inode_operations gfs2_dir_iops = {
 const struct inode_operations gfs2_symlink_iops = {
        .readlink = gfs2_readlink,
        .follow_link = gfs2_follow_link,
-       .permission = gfs2_permission,
+       .permission = gfs2_iop_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,