summaryrefslogtreecommitdiffstats
path: root/include/linux/posix_acl.h
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-06-09 12:11:54 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-24 08:17:07 -0400
commit073aaa1b142461d91f83da66db1184d7c1b1edea (patch)
tree2b54d185d78f1229418fca521a93e6b55c57248b /include/linux/posix_acl.h
parent06b16e9f68edaa1e71aee943d3c030bcf7380af1 (diff)
helpers for acl caching + switch to those
helpers: get_cached_acl(inode, type), set_cached_acl(inode, type, acl), forget_cached_acl(inode, type). ubifs/xattr.c needed includes reordered, the rest is a plain switchover. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/posix_acl.h')
-rw-r--r--include/linux/posix_acl.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 4bc241290c2..0cdba01b775 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -83,4 +83,68 @@ 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 *);
+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);
+}
+
#endif /* __LINUX_POSIX_ACL_H */