posix_acl.h 3.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
/*
  File: linux/posix_acl.h

  (C) 2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
*/


#ifndef __LINUX_POSIX_ACL_H
#define __LINUX_POSIX_ACL_H

#include <linux/slab.h>

#define ACL_UNDEFINED_ID	(-1)

/* a_type field in acl_user_posix_entry_t */
#define ACL_TYPE_ACCESS		(0x8000)
#define ACL_TYPE_DEFAULT	(0x4000)

/* e_tag entry in struct posix_acl_entry */
#define ACL_USER_OBJ		(0x01)
#define ACL_USER		(0x02)
#define ACL_GROUP_OBJ		(0x04)
#define ACL_GROUP		(0x08)
#define ACL_MASK		(0x10)
#define ACL_OTHER		(0x20)

/* permissions in the e_perm field */
#define ACL_READ		(0x04)
#define ACL_WRITE		(0x02)
#define ACL_EXECUTE		(0x01)
//#define ACL_ADD		(0x08)
//#define ACL_DELETE		(0x10)

struct posix_acl_entry {
	short			e_tag;
	unsigned short		e_perm;
	unsigned int		e_id;
};

struct posix_acl {
	atomic_t		a_refcount;
	unsigned int		a_count;
	struct posix_acl_entry	a_entries[0];
};

#define FOREACH_ACL_ENTRY(pa, acl, pe) \
	for(pa=(acl)->a_entries, pe=pa+(acl)->a_count; pa<pe; pa++)


/*
 * Duplicate an ACL handle.
 */
static inline struct posix_acl *
posix_acl_dup(struct posix_acl *acl)
{
	if (acl)
		atomic_inc(&acl->a_refcount);
	return acl;
}

/*
 * Free an ACL handle.
 */
static inline void
posix_acl_release(struct posix_acl *acl)
{
	if (acl && atomic_dec_and_test(&acl->a_refcount))
		kfree(acl);
}


/* posix_acl.c */

A
Al Viro 已提交
74 75
extern struct posix_acl *posix_acl_alloc(int, gfp_t);
extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t);
L
Linus Torvalds 已提交
76 77
extern int posix_acl_valid(const struct posix_acl *);
extern int posix_acl_permission(struct inode *, const struct posix_acl *, int);
A
Al Viro 已提交
78
extern struct posix_acl *posix_acl_from_mode(mode_t, gfp_t);
L
Linus Torvalds 已提交
79 80 81 82 83 84 85
extern int posix_acl_equiv_mode(const struct posix_acl *, mode_t *);
extern int posix_acl_create_masq(struct posix_acl *, mode_t *);
extern int posix_acl_chmod_masq(struct posix_acl *, mode_t);

extern struct posix_acl *get_posix_acl(struct inode *, int);
extern int set_posix_acl(struct inode *, int, struct posix_acl *);

86
#ifdef CONFIG_FS_POSIX_ACL
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
static inline struct posix_acl *get_cached_acl(struct inode *inode, int type)
{
	struct posix_acl **p, *acl;
	switch (type) {
	case ACL_TYPE_ACCESS:
		p = &inode->i_acl;
		break;
	case ACL_TYPE_DEFAULT:
		p = &inode->i_default_acl;
		break;
	default:
		return ERR_PTR(-EINVAL);
	}
	acl = ACCESS_ONCE(*p);
	if (acl) {
		spin_lock(&inode->i_lock);
		acl = *p;
		if (acl != ACL_NOT_CACHED)
			acl = posix_acl_dup(acl);
		spin_unlock(&inode->i_lock);
	}
	return acl;
}

static inline void set_cached_acl(struct inode *inode,
				  int type,
				  struct posix_acl *acl)
{
	struct posix_acl *old = NULL;
	spin_lock(&inode->i_lock);
	switch (type) {
	case ACL_TYPE_ACCESS:
		old = inode->i_acl;
		inode->i_acl = posix_acl_dup(acl);
		break;
	case ACL_TYPE_DEFAULT:
		old = inode->i_default_acl;
		inode->i_default_acl = posix_acl_dup(acl);
		break;
	}
	spin_unlock(&inode->i_lock);
	if (old != ACL_NOT_CACHED)
		posix_acl_release(old);
}

static inline void forget_cached_acl(struct inode *inode, int type)
{
	struct posix_acl *old = NULL;
	spin_lock(&inode->i_lock);
	switch (type) {
	case ACL_TYPE_ACCESS:
		old = inode->i_acl;
		inode->i_acl = ACL_NOT_CACHED;
		break;
	case ACL_TYPE_DEFAULT:
		old = inode->i_default_acl;
		inode->i_default_acl = ACL_NOT_CACHED;
		break;
	}
	spin_unlock(&inode->i_lock);
	if (old != ACL_NOT_CACHED)
		posix_acl_release(old);
}
150
#endif
L
Linus Torvalds 已提交
151
#endif  /* __LINUX_POSIX_ACL_H */