summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 12:53:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 12:53:15 -0700
commit0003230e8200699860f0b10af524dc47bf8aecad (patch)
tree8addb0c889b32111d6973c46cd3d0a5b5c17606c /fs/xfs
parent4b478cedcdc1b2d131170f22bd3f916e53472f52 (diff)
parent4e34e719e457f2e031297175410fc0bd4016a085 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: fs: take the ACL checks to common code bury posix_acl_..._masq() variants kill boilerplates around posix_acl_create_masq() generic_acl: no need to clone acl just to push it to set_cached_acl() kill boilerplate around posix_acl_chmod_masq() reiserfs: cache negative ACLs for v1 stat format xfs: cache negative ACLs if there is no attribute fork 9p: do no return 0 from ->check_acl without actually checking vfs: move ACL cache lookup into generic code CIFS: Fix oops while mounting with prefixpath xfs: Fix wrong return value of xfs_file_aio_write fix devtmpfs race caam: don't pass bogus S_IFCHR to debugfs_create_...() get rid of create_proc_entry() abuses - proc_mkdir() is there for purpose asus-wmi: ->is_visible() can't return negative fix jffs2 ACLs on big-endian with 16bit mode_t 9p: close ACL leaks ocfs2_init_acl(): fix a leak VFS : mount lock scalability for internal mounts
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c80
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h2
-rw-r--r--fs/xfs/xfs_acl.h2
5 files changed, 33 insertions, 70 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index cac48fe22ad..44ce5165680 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -114,6 +114,8 @@ xfs_get_acl(struct inode *inode, int type)
if (acl != ACL_NOT_CACHED)
return acl;
+ trace_xfs_get_acl(ip);
+
switch (type) {
case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE;
@@ -218,40 +220,6 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
return error;
}
-int
-xfs_check_acl(struct inode *inode, int mask)
-{
- struct xfs_inode *ip;
- struct posix_acl *acl;
- int error = -EAGAIN;
-
- ip = XFS_I(inode);
- trace_xfs_check_acl(ip);
-
- /*
- * If there is no attribute fork no ACL exists on this inode and
- * we can skip the whole exercise.
- */
- if (!XFS_IFORK_Q(ip))
- return -EAGAIN;
-
- if (mask & MAY_NOT_BLOCK) {
- if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
- return -ECHILD;
- return -EAGAIN;
- }
-
- acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
- if (IS_ERR(acl))
- return PTR_ERR(acl);
- if (acl) {
- error = posix_acl_permission(inode, acl, mask);
- posix_acl_release(acl);
- }
-
- return error;
-}
-
static int
xfs_set_mode(struct inode *inode, mode_t mode)
{
@@ -297,29 +265,23 @@ posix_acl_default_exists(struct inode *inode)
* No need for i_mutex because the inode is not yet exposed to the VFS.
*/
int
-xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
+xfs_inherit_acl(struct inode *inode, struct posix_acl *acl)
{
- struct posix_acl *clone;
- mode_t mode;
+ mode_t mode = inode->i_mode;
int error = 0, inherit = 0;
if (S_ISDIR(inode->i_mode)) {
- error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl);
+ error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
if (error)
- return error;
+ goto out;
}
- clone = posix_acl_clone(default_acl, GFP_KERNEL);
- if (!clone)
- return -ENOMEM;
-
- mode = inode->i_mode;
- error = posix_acl_create_masq(clone, &mode);
+ error = posix_acl_create(&acl, GFP_KERNEL, &mode);
if (error < 0)
- goto out_release_clone;
+ return error;
/*
- * If posix_acl_create_masq returns a positive value we need to
+ * If posix_acl_create returns a positive value we need to
* inherit a permission that can't be represented using the Unix
* mode bits and we actually need to set an ACL.
*/
@@ -328,20 +290,20 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
error = xfs_set_mode(inode, mode);
if (error)
- goto out_release_clone;
+ goto out;
if (inherit)
- error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
+ error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
- out_release_clone:
- posix_acl_release(clone);
+out:
+ posix_acl_release(acl);
return error;
}
int
xfs_acl_chmod(struct inode *inode)
{
- struct posix_acl *acl, *clone;
+ struct posix_acl *acl;
int error;
if (S_ISLNK(inode->i_mode))
@@ -351,16 +313,12 @@ xfs_acl_chmod(struct inode *inode)
if (IS_ERR(acl) || !acl)
return PTR_ERR(acl);
- clone = posix_acl_clone(acl, GFP_KERNEL);
- posix_acl_release(acl);
- if (!clone)
- return -ENOMEM;
-
- error = posix_acl_chmod_masq(clone, inode->i_mode);
- if (!error)
- error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
+ error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
+ if (error)
+ return error;
- posix_acl_release(clone);
+ error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
+ posix_acl_release(acl);
return error;
}
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index cca00f49e09..825390e1c13 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -881,11 +881,14 @@ xfs_file_aio_write(
/* Handle various SYNC-type writes */
if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
loff_t end = pos + ret - 1;
+ int error;
xfs_rw_iunlock(ip, iolock);
- ret = -xfs_file_fsync(file, pos, end,
+ error = xfs_file_fsync(file, pos, end,
(file->f_flags & __O_SYNC) ? 0 : 1);
xfs_rw_ilock(ip, iolock);
+ if (error)
+ ret = error;
}
out_unlock:
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 501e4f63054..6544c3236bc 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -202,9 +202,9 @@ xfs_vn_mknod(
if (default_acl) {
error = -xfs_inherit_acl(inode, default_acl);
+ default_acl = NULL;
if (unlikely(error))
goto out_cleanup_inode;
- posix_acl_release(default_acl);
}
@@ -1022,7 +1022,7 @@ xfs_vn_fiemap(
}
static const struct inode_operations xfs_inode_operations = {
- .check_acl = xfs_check_acl,
+ .get_acl = xfs_get_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1048,7 +1048,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
.rmdir = xfs_vn_unlink,
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
- .check_acl = xfs_check_acl,
+ .get_acl = xfs_get_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1073,7 +1073,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
.rmdir = xfs_vn_unlink,
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
- .check_acl = xfs_check_acl,
+ .get_acl = xfs_get_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1086,7 +1086,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = xfs_vn_follow_link,
.put_link = xfs_vn_put_link,
- .check_acl = xfs_check_acl,
+ .get_acl = xfs_get_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1194,6 +1194,10 @@ xfs_setup_inode(
break;
}
+ /* if there is no attribute fork no ACL can exist on this inode */
+ if (!XFS_IFORK_Q(ip))
+ cache_no_acl(inode);
+
xfs_iflags_clear(ip, XFS_INEW);
barrier();
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index fda0708ef2e..690fc7a7bd7 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -571,7 +571,7 @@ DEFINE_INODE_EVENT(xfs_alloc_file_space);
DEFINE_INODE_EVENT(xfs_free_file_space);
DEFINE_INODE_EVENT(xfs_readdir);
#ifdef CONFIG_XFS_POSIX_ACL
-DEFINE_INODE_EVENT(xfs_check_acl);
+DEFINE_INODE_EVENT(xfs_get_acl);
#endif
DEFINE_INODE_EVENT(xfs_vm_bmap);
DEFINE_INODE_EVENT(xfs_file_ioctl);
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 0135e2a669d..2c656ef4947 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -42,7 +42,6 @@ struct xfs_acl {
#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
#ifdef CONFIG_XFS_POSIX_ACL
-extern int xfs_check_acl(struct inode *inode, int mask);
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode);
@@ -52,7 +51,6 @@ extern int posix_acl_default_exists(struct inode *inode);
extern const struct xattr_handler xfs_xattr_acl_access_handler;
extern const struct xattr_handler xfs_xattr_acl_default_handler;
#else
-# define xfs_check_acl NULL
# define xfs_get_acl(inode, type) NULL
# define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 0