Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs updates from Al Viro:
 "Assorted stuff; the biggest pile here is Christoph's ACL series.  Plus
  assorted cleanups and fixes all over the place...

  There will be another pile later this week"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (43 commits)
  __dentry_path() fixes
  vfs: Remove second variable named error in __dentry_path
  vfs: Is mounted should be testing mnt_ns for NULL or error.
  Fix race when checking i_size on direct i/o read
  hfsplus: remove can_set_xattr
  nfsd: use get_acl and ->set_acl
  fs: remove generic_acl
  nfs: use generic posix ACL infrastructure for v3 Posix ACLs
  gfs2: use generic posix ACL infrastructure
  jfs: use generic posix ACL infrastructure
  xfs: use generic posix ACL infrastructure
  reiserfs: use generic posix ACL infrastructure
  ocfs2: use generic posix ACL infrastructure
  jffs2: use generic posix ACL infrastructure
  hfsplus: use generic posix ACL infrastructure
  f2fs: use generic posix ACL infrastructure
  ext2/3/4: use generic posix ACL infrastructure
  btrfs: use generic posix ACL infrastructure
  fs: make posix_acl_create more useful
  fs: make posix_acl_chmod more useful
  ...
This commit is contained in:
Linus Torvalds
2014-01-28 08:38:04 -08:00
bovenliggende 54c0a4b461 f650080152
commit bf3d846b78
179 gewijzigde bestanden met toevoegingen van 1554 en 3862 verwijderingen

Bestand weergeven

@@ -124,16 +124,12 @@ struct posix_acl *
xfs_get_acl(struct inode *inode, int type)
{
struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl;
struct posix_acl *acl = NULL;
struct xfs_acl *xfs_acl;
unsigned char *ea_name;
int error;
int len;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
trace_xfs_get_acl(ip);
switch (type) {
@@ -164,10 +160,8 @@ xfs_get_acl(struct inode *inode, int type)
* cache entry, for any other error assume it is transient and
* leave the cache entry as ACL_NOT_CACHED.
*/
if (error == -ENOATTR) {
acl = NULL;
if (error == -ENOATTR)
goto out_update_cache;
}
goto out;
}
@@ -183,15 +177,12 @@ out:
}
STATIC int
xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
__xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{
struct xfs_inode *ip = XFS_I(inode);
unsigned char *ea_name;
int error;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
switch (type) {
case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE;
@@ -282,131 +273,23 @@ posix_acl_default_exists(struct inode *inode)
return xfs_acl_exists(inode, SGI_ACL_DEFAULT);
}
/*
* 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 *acl)
xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
umode_t mode = inode->i_mode;
int error = 0, inherit = 0;
if (S_ISDIR(inode->i_mode)) {
error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
if (error)
goto out;
}
error = posix_acl_create(&acl, GFP_KERNEL, &mode);
if (error < 0)
return error;
/*
* 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.
*/
if (error > 0)
inherit = 1;
error = xfs_set_mode(inode, mode);
if (error)
goto out;
if (inherit)
error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
out:
posix_acl_release(acl);
return error;
}
int
xfs_acl_chmod(struct inode *inode)
{
struct posix_acl *acl;
int error;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl) || !acl)
return PTR_ERR(acl);
error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
if (error)
return error;
error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
posix_acl_release(acl);
return error;
}
static int
xfs_xattr_acl_get(struct dentry *dentry, const char *name,
void *value, size_t size, int type)
{
struct posix_acl *acl;
int error;
acl = xfs_get_acl(dentry->d_inode, type);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl == NULL)
return -ENODATA;
error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
posix_acl_release(acl);
return error;
}
static int
xfs_xattr_acl_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
struct inode *inode = dentry->d_inode;
struct posix_acl *acl = NULL;
int error = 0;
if (flags & XATTR_CREATE)
return -EINVAL;
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
return value ? -EACCES : 0;
if (!inode_owner_or_capable(inode))
return -EPERM;
if (!value)
if (!acl)
goto set_acl;
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (!acl) {
/*
* acl_set_file(3) may request that we set default ACLs with
* zero length -- defend (gracefully) against that here.
*/
goto out;
}
if (IS_ERR(acl)) {
error = PTR_ERR(acl);
goto out;
}
error = posix_acl_valid(acl);
if (error)
goto out_release;
error = -EINVAL;
if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
goto out_release;
return error;
if (type == ACL_TYPE_ACCESS) {
umode_t mode = inode->i_mode;
error = posix_acl_equiv_mode(acl, &mode);
if (error <= 0) {
posix_acl_release(acl);
acl = NULL;
if (error < 0)
@@ -415,27 +298,9 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
error = xfs_set_mode(inode, mode);
if (error)
goto out_release;
return error;
}
set_acl:
error = xfs_set_acl(inode, type, acl);
out_release:
posix_acl_release(acl);
out:
return error;
return __xfs_set_acl(inode, type, acl);
}
const struct xattr_handler xfs_xattr_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS,
.flags = ACL_TYPE_ACCESS,
.get = xfs_xattr_acl_get,
.set = xfs_xattr_acl_set,
};
const struct xattr_handler xfs_xattr_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.get = xfs_xattr_acl_get,
.set = xfs_xattr_acl_set,
};

Bestand weergeven

@@ -60,20 +60,15 @@ struct xfs_acl {
#ifdef CONFIG_XFS_POSIX_ACL
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);
extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
extern int posix_acl_access_exists(struct inode *inode);
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
static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
{
return NULL;
}
# define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 0
# define xfs_set_acl NULL
# define posix_acl_access_exists(inode) 0
# define posix_acl_default_exists(inode) 0
#endif /* CONFIG_XFS_POSIX_ACL */

Bestand weergeven

@@ -123,7 +123,7 @@ xfs_vn_mknod(
{
struct inode *inode;
struct xfs_inode *ip = NULL;
struct posix_acl *default_acl = NULL;
struct posix_acl *default_acl, *acl;
struct xfs_name name;
int error;
@@ -139,14 +139,9 @@ xfs_vn_mknod(
rdev = 0;
}
if (IS_POSIXACL(dir)) {
default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(default_acl))
return PTR_ERR(default_acl);
if (!default_acl)
mode &= ~current_umask();
}
error = posix_acl_create(dir, &mode, &default_acl, &acl);
if (error)
return error;
xfs_dentry_to_name(&name, dentry, mode);
error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
@@ -159,22 +154,30 @@ xfs_vn_mknod(
if (unlikely(error))
goto out_cleanup_inode;
#ifdef CONFIG_XFS_POSIX_ACL
if (default_acl) {
error = -xfs_inherit_acl(inode, default_acl);
default_acl = NULL;
if (unlikely(error))
error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
if (error)
goto out_cleanup_inode;
}
if (acl) {
error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
if (error)
goto out_cleanup_inode;
}
#endif
d_instantiate(dentry, inode);
out_free_acl:
if (default_acl)
posix_acl_release(default_acl);
if (acl)
posix_acl_release(acl);
return -error;
out_cleanup_inode:
xfs_cleanup_inode(dir, inode, dentry);
out_free_acl:
posix_acl_release(default_acl);
return -error;
goto out_free_acl;
}
STATIC int
@@ -391,18 +394,6 @@ xfs_vn_follow_link(
return NULL;
}
STATIC void
xfs_vn_put_link(
struct dentry *dentry,
struct nameidata *nd,
void *p)
{
char *s = nd_get_link(nd);
if (!IS_ERR(s))
kfree(s);
}
STATIC int
xfs_vn_getattr(
struct vfsmount *mnt,
@@ -688,7 +679,7 @@ xfs_setattr_nonsize(
* Posix ACL code seems to care about this issue either.
*/
if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
error = -xfs_acl_chmod(inode);
error = -posix_acl_chmod(inode, inode->i_mode);
if (error)
return XFS_ERROR(error);
}
@@ -1045,6 +1036,7 @@ xfs_vn_fiemap(
static const struct inode_operations xfs_inode_operations = {
.get_acl = xfs_get_acl,
.set_acl = xfs_set_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1072,6 +1064,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
.get_acl = xfs_get_acl,
.set_acl = xfs_set_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1098,6 +1091,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
.mknod = xfs_vn_mknod,
.rename = xfs_vn_rename,
.get_acl = xfs_get_acl,
.set_acl = xfs_set_acl,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
@@ -1110,8 +1104,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
static const struct inode_operations xfs_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = xfs_vn_follow_link,
.put_link = xfs_vn_put_link,
.get_acl = xfs_get_acl,
.put_link = kfree_put_link,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,

Bestand weergeven

@@ -30,7 +30,7 @@ extern void xfs_setup_inode(struct xfs_inode *);
/*
* Internal setattr interfaces.
*/
#define XFS_ATTR_NOACL 0x01 /* Don't call xfs_acl_chmod */
#define XFS_ATTR_NOACL 0x01 /* Don't call posix_acl_chmod */
extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap,
int flags);

Bestand weergeven

@@ -102,8 +102,8 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
&xfs_xattr_trusted_handler,
&xfs_xattr_security_handler,
#ifdef CONFIG_XFS_POSIX_ACL
&xfs_xattr_acl_access_handler,
&xfs_xattr_acl_default_handler,
&posix_acl_access_xattr_handler,
&posix_acl_default_xattr_handler,
#endif
NULL
};