|
@@ -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;
|
|
|
|
|
@@ -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;
|
|
|
}
|
|
@@ -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);
|
|
@@ -1141,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,
|
|
@@ -1160,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,
|
|
@@ -1172,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,
|