Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 376712
b: refs/heads/master
c: 0a8aa19
h: refs/heads/master
v: v3
  • Loading branch information
Dave Chinner authored and Ben Myers committed Jun 6, 2013
1 parent b2745a5 commit 159db42
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f763fd440e094be37b38596ee14f1d64caa9bf9c
refs/heads/master: 0a8aa1939777dd114479677f0044652c1fd72398
31 changes: 18 additions & 13 deletions trunk/fs/xfs/xfs_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
#include "xfs_vnodeops.h"
#include "xfs_sb.h"
#include "xfs_mount.h"
#include "xfs_trace.h"
#include <linux/slab.h>
#include <linux/xattr.h>
Expand All @@ -34,15 +36,17 @@
*/

STATIC struct posix_acl *
xfs_acl_from_disk(struct xfs_acl *aclp)
xfs_acl_from_disk(
struct xfs_acl *aclp,
int max_entries)
{
struct posix_acl_entry *acl_e;
struct posix_acl *acl;
struct xfs_acl_entry *ace;
unsigned int count, i;

count = be32_to_cpu(aclp->acl_cnt);
if (count > XFS_ACL_MAX_ENTRIES)
if (count > max_entries)
return ERR_PTR(-EFSCORRUPTED);

acl = posix_acl_alloc(count, GFP_KERNEL);
Expand Down Expand Up @@ -108,9 +112,9 @@ xfs_get_acl(struct inode *inode, int type)
struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl;
struct xfs_acl *xfs_acl;
int len = sizeof(struct xfs_acl);
unsigned char *ea_name;
int error;
int len;

acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
Expand All @@ -133,8 +137,8 @@ xfs_get_acl(struct inode *inode, int type)
* If we have a cached ACLs value just return it, not need to
* go out to the disk.
*/

xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
len = XFS_ACL_MAX_SIZE(ip->i_mount);
xfs_acl = kzalloc(len, GFP_KERNEL);
if (!xfs_acl)
return ERR_PTR(-ENOMEM);

Expand All @@ -153,7 +157,7 @@ xfs_get_acl(struct inode *inode, int type)
goto out;
}

acl = xfs_acl_from_disk(xfs_acl);
acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount));
if (IS_ERR(acl))
goto out;

Expand Down Expand Up @@ -189,16 +193,17 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)

if (acl) {
struct xfs_acl *xfs_acl;
int len;
int len = XFS_ACL_MAX_SIZE(ip->i_mount);

xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
xfs_acl = kzalloc(len, GFP_KERNEL);
if (!xfs_acl)
return -ENOMEM;

xfs_acl_to_disk(xfs_acl, acl);
len = sizeof(struct xfs_acl) -
(sizeof(struct xfs_acl_entry) *
(XFS_ACL_MAX_ENTRIES - acl->a_count));

/* subtract away the unused acl entries */
len -= sizeof(struct xfs_acl_entry) *
(XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);

error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
len, ATTR_ROOT);
Expand Down Expand Up @@ -243,7 +248,7 @@ xfs_set_mode(struct inode *inode, umode_t mode)
static int
xfs_acl_exists(struct inode *inode, unsigned char *name)
{
int len = sizeof(struct xfs_acl);
int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb));

return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
ATTR_ROOT|ATTR_KERNOVAL) == 0);
Expand Down Expand Up @@ -379,7 +384,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
goto out_release;

error = -EINVAL;
if (acl->a_count > XFS_ACL_MAX_ENTRIES)
if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
goto out_release;

if (type == ACL_TYPE_ACCESS) {
Expand Down
31 changes: 24 additions & 7 deletions trunk/fs/xfs/xfs_acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,36 @@ struct inode;
struct posix_acl;
struct xfs_inode;

#define XFS_ACL_MAX_ENTRIES 25
#define XFS_ACL_NOT_PRESENT (-1)

/* On-disk XFS access control list structure */
struct xfs_acl_entry {
__be32 ae_tag;
__be32 ae_id;
__be16 ae_perm;
__be16 ae_pad; /* fill the implicit hole in the structure */
};

struct xfs_acl {
__be32 acl_cnt;
struct xfs_acl_entry {
__be32 ae_tag;
__be32 ae_id;
__be16 ae_perm;
} acl_entry[XFS_ACL_MAX_ENTRIES];
__be32 acl_cnt;
struct xfs_acl_entry acl_entry[0];
};

/*
* The number of ACL entries allowed is defined by the on-disk format.
* For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is
* limited only by the maximum size of the xattr that stores the information.
*/
#define XFS_ACL_MAX_ENTRIES(mp) \
(xfs_sb_version_hascrc(&mp->m_sb) \
? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
sizeof(struct xfs_acl_entry) \
: 25)

#define XFS_ACL_MAX_SIZE(mp) \
(sizeof(struct xfs_acl) + \
sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))

/* On-disk XFS extended attribute names */
#define SGI_ACL_FILE (unsigned char *)"SGI_ACL_FILE"
#define SGI_ACL_DEFAULT (unsigned char *)"SGI_ACL_DEFAULT"
Expand Down

0 comments on commit 159db42

Please sign in to comment.