Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169180
b: refs/heads/master
c: 2646a1f
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Dec 3, 2009
1 parent 2d6c64a commit 6fe939b
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 93 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: f55073ff1eaf99f6b3bc62134a456638bca043a3
refs/heads/master: 2646a1f61a3b5525914757f10fa12b5b94713648
170 changes: 115 additions & 55 deletions trunk/fs/gfs2/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
#include <linux/gfs2_ondisk.h>
Expand All @@ -26,61 +27,6 @@
#include "trans.h"
#include "util.h"

#define ACL_ACCESS 1
#define ACL_DEFAULT 0

int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
struct gfs2_ea_request *er, int *remove, mode_t *mode)
{
struct posix_acl *acl;
int error;

error = gfs2_acl_validate_remove(ip, access);
if (error)
return error;

if (!er->er_data)
return -EINVAL;

acl = posix_acl_from_xattr(er->er_data, er->er_data_len);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (!acl) {
*remove = 1;
return 0;
}

error = posix_acl_valid(acl);
if (error)
goto out;

if (access) {
error = posix_acl_equiv_mode(acl, mode);
if (!error)
*remove = 1;
else if (error > 0)
error = 0;
}

out:
posix_acl_release(acl);
return error;
}

int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
{
if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
return -EOPNOTSUPP;
if (!is_owner_or_cap(&ip->i_inode))
return -EPERM;
if (S_ISLNK(ip->i_inode.i_mode))
return -EOPNOTSUPP;
if (!access && !S_ISDIR(ip->i_inode.i_mode))
return -EACCES;

return 0;
}

static int acl_get(struct gfs2_inode *ip, const char *name,
struct posix_acl **acl, struct gfs2_ea_location *el,
char **datap, unsigned int *lenp)
Expand Down Expand Up @@ -277,3 +223,117 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
return error;
}

static int gfs2_acl_type(const char *name)
{
if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
return ACL_TYPE_ACCESS;
if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
return ACL_TYPE_DEFAULT;
return -EINVAL;
}

static int gfs2_xattr_system_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
int type;

type = gfs2_acl_type(name);
if (type < 0)
return type;

return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
}

static int gfs2_set_mode(struct inode *inode, mode_t mode)
{
int error = 0;

if (mode != inode->i_mode) {
struct iattr iattr;

iattr.ia_valid = ATTR_MODE;
iattr.ia_mode = mode;

error = gfs2_setattr_simple(GFS2_I(inode), &iattr);
}

return error;
}

static int gfs2_xattr_system_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct posix_acl *acl = NULL;
int error = 0, type;

if (!sdp->sd_args.ar_posix_acl)
return -EOPNOTSUPP;

type = gfs2_acl_type(name);
if (type < 0)
return type;
if (flags & XATTR_CREATE)
return -EINVAL;
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
return value ? -EACCES : 0;
if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
return -EPERM;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;

if (!value)
goto set_acl;

acl = posix_acl_from_xattr(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 > GFS2_ACL_MAX_ENTRIES)
goto out_release;

if (type == ACL_TYPE_ACCESS) {
mode_t mode = inode->i_mode;
error = posix_acl_equiv_mode(acl, &mode);

if (error <= 0) {
posix_acl_release(acl);
acl = NULL;

if (error < 0)
return error;
}

error = gfs2_set_mode(inode, mode);
if (error)
goto out_release;
}

set_acl:
error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, 0);
out_release:
posix_acl_release(acl);
out:
return error;
}

struct xattr_handler gfs2_xattr_system_handler = {
.prefix = XATTR_SYSTEM_PREFIX,
.get = gfs2_xattr_system_get,
.set = gfs2_xattr_system_set,
};

24 changes: 5 additions & 19 deletions trunk/fs/gfs2/acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,12 @@
#include "incore.h"

#define GFS2_POSIX_ACL_ACCESS "posix_acl_access"
#define GFS2_POSIX_ACL_ACCESS_LEN 16
#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default"
#define GFS2_POSIX_ACL_DEFAULT_LEN 17
#define GFS2_ACL_MAX_ENTRIES 25

#define GFS2_ACL_IS_ACCESS(name, len) \
((len) == GFS2_POSIX_ACL_ACCESS_LEN && \
!memcmp(GFS2_POSIX_ACL_ACCESS, (name), (len)))

#define GFS2_ACL_IS_DEFAULT(name, len) \
((len) == GFS2_POSIX_ACL_DEFAULT_LEN && \
!memcmp(GFS2_POSIX_ACL_DEFAULT, (name), (len)))

struct gfs2_ea_request;

int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
struct gfs2_ea_request *er,
int *remove, mode_t *mode);
int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access);
int gfs2_check_acl(struct inode *inode, int mask);
int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
extern int gfs2_check_acl(struct inode *inode, int mask);
extern int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
extern struct xattr_handler gfs2_xattr_system_handler;

#endif /* __ACL_DOT_H__ */
18 changes: 0 additions & 18 deletions trunk/fs/gfs2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1507,18 +1507,6 @@ static int gfs2_xattr_user_set(struct inode *inode, const char *name,
return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
}

static int gfs2_xattr_system_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
}

static int gfs2_xattr_system_set(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
}

static int gfs2_xattr_security_get(struct inode *inode, const char *name,
void *buffer, size_t size)
{
Expand All @@ -1543,12 +1531,6 @@ static struct xattr_handler gfs2_xattr_security_handler = {
.set = gfs2_xattr_security_set,
};

static struct xattr_handler gfs2_xattr_system_handler = {
.prefix = XATTR_SYSTEM_PREFIX,
.get = gfs2_xattr_system_get,
.set = gfs2_xattr_system_set,
};

struct xattr_handler *gfs2_xattr_handlers[] = {
&gfs2_xattr_user_handler,
&gfs2_xattr_security_handler,
Expand Down

0 comments on commit 6fe939b

Please sign in to comment.