diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-08-02 21:32:13 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-08-03 00:58:42 -0400 |
commit | 3567866bf26190d1e734c975c907eb06e923ba23 (patch) | |
tree | 60d6b71d8ec821b121e6ab0756833d79c912908e /include/linux/posix_acl.h | |
parent | 951c0d660a7c35286e401ca6d6ef38c9d49643c7 (diff) | |
download | linux-stable-3567866bf26190d1e734c975c907eb06e923ba23.tar.gz linux-stable-3567866bf26190d1e734c975c907eb06e923ba23.tar.bz2 linux-stable-3567866bf26190d1e734c975c907eb06e923ba23.zip |
RCUify freeing acls, let check_acl() go ahead in RCU mode if acl is cached
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.h | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index a9c2fb29be96..b7681102a4b9 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -9,6 +9,7 @@ #define __LINUX_POSIX_ACL_H #include <linux/slab.h> +#include <linux/rcupdate.h> #define ACL_UNDEFINED_ID (-1) @@ -38,7 +39,10 @@ struct posix_acl_entry { }; struct posix_acl { - atomic_t a_refcount; + union { + atomic_t a_refcount; + struct rcu_head a_rcu; + }; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -65,7 +69,7 @@ static inline void posix_acl_release(struct posix_acl *acl) { if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + kfree_rcu(acl, a_rcu); } @@ -110,13 +114,9 @@ static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) return acl; } -static inline int negative_cached_acl(struct inode *inode, int type) +static inline struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *acl = ACCESS_ONCE(*p); - if (acl) - return 0; - return 1; + return rcu_dereference(*acl_by_type(inode, type)); } static inline void set_cached_acl(struct inode *inode, @@ -127,7 +127,7 @@ static inline void set_cached_acl(struct inode *inode, struct posix_acl *old; spin_lock(&inode->i_lock); old = *p; - *p = posix_dup_acl(acl); + rcu_assign_pointer(*p, posix_acl_dup(acl)); spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) posix_acl_release(old); |