diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-09 13:29:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-24 08:17:07 -0400 |
commit | 1cbd20d820c36f52543e3e4cd0067ebf52aa388f (patch) | |
tree | 51d53ee4b6f79031eb493d7d2f2a57a7be3a3955 /fs/xfs | |
parent | 073aaa1b142461d91f83da66db1184d7c1b1edea (diff) |
switch xfs to generic acl caching helpers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_acl.c | 73 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_iget.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 5 |
4 files changed, 9 insertions, 75 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 1e9d1246eebc..b23a54506446 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c | |||
@@ -25,14 +25,10 @@ | |||
25 | #include <linux/posix_acl_xattr.h> | 25 | #include <linux/posix_acl_xattr.h> |
26 | 26 | ||
27 | 27 | ||
28 | #define XFS_ACL_NOT_CACHED ((void *)-1) | ||
29 | |||
30 | /* | 28 | /* |
31 | * Locking scheme: | 29 | * Locking scheme: |
32 | * - all ACL updates are protected by inode->i_mutex, which is taken before | 30 | * - all ACL updates are protected by inode->i_mutex, which is taken before |
33 | * calling into this file. | 31 | * calling into this file. |
34 | * - access and updates to the ip->i_acl and ip->i_default_acl pointers are | ||
35 | * protected by inode->i_lock. | ||
36 | */ | 32 | */ |
37 | 33 | ||
38 | STATIC struct posix_acl * | 34 | STATIC struct posix_acl * |
@@ -102,59 +98,35 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) | |||
102 | } | 98 | } |
103 | } | 99 | } |
104 | 100 | ||
105 | /* | ||
106 | * Update the cached ACL pointer in the inode. | ||
107 | * | ||
108 | * Because we don't hold any locks while reading/writing the attribute | ||
109 | * from/to disk another thread could have raced and updated the cached | ||
110 | * ACL value before us. In that case we release the previous cached value | ||
111 | * and update it with our new value. | ||
112 | */ | ||
113 | STATIC void | ||
114 | xfs_update_cached_acl(struct inode *inode, struct posix_acl **p_acl, | ||
115 | struct posix_acl *acl) | ||
116 | { | ||
117 | spin_lock(&inode->i_lock); | ||
118 | if (*p_acl && *p_acl != XFS_ACL_NOT_CACHED) | ||
119 | posix_acl_release(*p_acl); | ||
120 | *p_acl = posix_acl_dup(acl); | ||
121 | spin_unlock(&inode->i_lock); | ||
122 | } | ||
123 | |||
124 | struct posix_acl * | 101 | struct posix_acl * |
125 | xfs_get_acl(struct inode *inode, int type) | 102 | xfs_get_acl(struct inode *inode, int type) |
126 | { | 103 | { |
127 | struct xfs_inode *ip = XFS_I(inode); | 104 | struct xfs_inode *ip = XFS_I(inode); |
128 | struct posix_acl *acl = NULL, **p_acl; | 105 | struct posix_acl *acl; |
129 | struct xfs_acl *xfs_acl; | 106 | struct xfs_acl *xfs_acl; |
130 | int len = sizeof(struct xfs_acl); | 107 | int len = sizeof(struct xfs_acl); |
131 | char *ea_name; | 108 | char *ea_name; |
132 | int error; | 109 | int error; |
133 | 110 | ||
111 | acl = get_cached_acl(inode, type); | ||
112 | if (acl != ACL_NOT_CACHED) | ||
113 | return acl; | ||
114 | |||
134 | switch (type) { | 115 | switch (type) { |
135 | case ACL_TYPE_ACCESS: | 116 | case ACL_TYPE_ACCESS: |
136 | ea_name = SGI_ACL_FILE; | 117 | ea_name = SGI_ACL_FILE; |
137 | p_acl = &ip->i_acl; | ||
138 | break; | 118 | break; |
139 | case ACL_TYPE_DEFAULT: | 119 | case ACL_TYPE_DEFAULT: |
140 | ea_name = SGI_ACL_DEFAULT; | 120 | ea_name = SGI_ACL_DEFAULT; |
141 | p_acl = &ip->i_default_acl; | ||
142 | break; | 121 | break; |
143 | default: | 122 | default: |
144 | return ERR_PTR(-EINVAL); | 123 | BUG(); |
145 | } | 124 | } |
146 | 125 | ||
147 | spin_lock(&inode->i_lock); | ||
148 | if (*p_acl != XFS_ACL_NOT_CACHED) | ||
149 | acl = posix_acl_dup(*p_acl); | ||
150 | spin_unlock(&inode->i_lock); | ||
151 | |||
152 | /* | 126 | /* |
153 | * If we have a cached ACLs value just return it, not need to | 127 | * If we have a cached ACLs value just return it, not need to |
154 | * go out to the disk. | 128 | * go out to the disk. |
155 | */ | 129 | */ |
156 | if (acl) | ||
157 | return acl; | ||
158 | 130 | ||
159 | xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); | 131 | xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); |
160 | if (!xfs_acl) | 132 | if (!xfs_acl) |
@@ -165,7 +137,7 @@ xfs_get_acl(struct inode *inode, int type) | |||
165 | /* | 137 | /* |
166 | * If the attribute doesn't exist make sure we have a negative | 138 | * If the attribute doesn't exist make sure we have a negative |
167 | * cache entry, for any other error assume it is transient and | 139 | * cache entry, for any other error assume it is transient and |
168 | * leave the cache entry as XFS_ACL_NOT_CACHED. | 140 | * leave the cache entry as ACL_NOT_CACHED. |
169 | */ | 141 | */ |
170 | if (error == -ENOATTR) { | 142 | if (error == -ENOATTR) { |
171 | acl = NULL; | 143 | acl = NULL; |
@@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type) | |||
179 | goto out; | 151 | goto out; |
180 | 152 | ||
181 | out_update_cache: | 153 | out_update_cache: |
182 | xfs_update_cached_acl(inode, p_acl, acl); | 154 | set_cached_acl(inode, type, acl); |
183 | out: | 155 | out: |
184 | kfree(xfs_acl); | 156 | kfree(xfs_acl); |
185 | return acl; | 157 | return acl; |
@@ -189,7 +161,6 @@ STATIC int | |||
189 | xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 161 | xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) |
190 | { | 162 | { |
191 | struct xfs_inode *ip = XFS_I(inode); | 163 | struct xfs_inode *ip = XFS_I(inode); |
192 | struct posix_acl **p_acl; | ||
193 | char *ea_name; | 164 | char *ea_name; |
194 | int error; | 165 | int error; |
195 | 166 | ||
@@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
199 | switch (type) { | 170 | switch (type) { |
200 | case ACL_TYPE_ACCESS: | 171 | case ACL_TYPE_ACCESS: |
201 | ea_name = SGI_ACL_FILE; | 172 | ea_name = SGI_ACL_FILE; |
202 | p_acl = &ip->i_acl; | ||
203 | break; | 173 | break; |
204 | case ACL_TYPE_DEFAULT: | 174 | case ACL_TYPE_DEFAULT: |
205 | if (!S_ISDIR(inode->i_mode)) | 175 | if (!S_ISDIR(inode->i_mode)) |
206 | return acl ? -EACCES : 0; | 176 | return acl ? -EACCES : 0; |
207 | ea_name = SGI_ACL_DEFAULT; | 177 | ea_name = SGI_ACL_DEFAULT; |
208 | p_acl = &ip->i_default_acl; | ||
209 | break; | 178 | break; |
210 | default: | 179 | default: |
211 | return -EINVAL; | 180 | return -EINVAL; |
@@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
242 | } | 211 | } |
243 | 212 | ||
244 | if (!error) | 213 | if (!error) |
245 | xfs_update_cached_acl(inode, p_acl, acl); | 214 | set_cached_acl(inode, type, acl); |
246 | return error; | 215 | return error; |
247 | } | 216 | } |
248 | 217 | ||
@@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode) | |||
384 | return error; | 353 | return error; |
385 | } | 354 | } |
386 | 355 | ||
387 | void | ||
388 | xfs_inode_init_acls(struct xfs_inode *ip) | ||
389 | { | ||
390 | /* | ||
391 | * No need for locking, inode is not live yet. | ||
392 | */ | ||
393 | ip->i_acl = XFS_ACL_NOT_CACHED; | ||
394 | ip->i_default_acl = XFS_ACL_NOT_CACHED; | ||
395 | } | ||
396 | |||
397 | void | ||
398 | xfs_inode_clear_acls(struct xfs_inode *ip) | ||
399 | { | ||
400 | /* | ||
401 | * No need for locking here, the inode is not live anymore | ||
402 | * and just about to be freed. | ||
403 | */ | ||
404 | if (ip->i_acl != XFS_ACL_NOT_CACHED) | ||
405 | posix_acl_release(ip->i_acl); | ||
406 | if (ip->i_default_acl != XFS_ACL_NOT_CACHED) | ||
407 | posix_acl_release(ip->i_default_acl); | ||
408 | } | ||
409 | |||
410 | |||
411 | /* | 356 | /* |
412 | * System xattr handlers. | 357 | * System xattr handlers. |
413 | * | 358 | * |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 63dc1f2efad5..947b150df8ed 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -46,8 +46,6 @@ extern int xfs_check_acl(struct inode *inode, int mask); | |||
46 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); | 46 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); |
47 | extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); | 47 | extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); |
48 | extern int xfs_acl_chmod(struct inode *inode); | 48 | extern int xfs_acl_chmod(struct inode *inode); |
49 | extern void xfs_inode_init_acls(struct xfs_inode *ip); | ||
50 | extern void xfs_inode_clear_acls(struct xfs_inode *ip); | ||
51 | extern int posix_acl_access_exists(struct inode *inode); | 49 | extern int posix_acl_access_exists(struct inode *inode); |
52 | extern int posix_acl_default_exists(struct inode *inode); | 50 | extern int posix_acl_default_exists(struct inode *inode); |
53 | 51 | ||
@@ -57,8 +55,6 @@ extern struct xattr_handler xfs_xattr_system_handler; | |||
57 | # define xfs_get_acl(inode, type) NULL | 55 | # define xfs_get_acl(inode, type) NULL |
58 | # define xfs_inherit_acl(inode, default_acl) 0 | 56 | # define xfs_inherit_acl(inode, default_acl) 0 |
59 | # define xfs_acl_chmod(inode) 0 | 57 | # define xfs_acl_chmod(inode) 0 |
60 | # define xfs_inode_init_acls(ip) | ||
61 | # define xfs_inode_clear_acls(ip) | ||
62 | # define posix_acl_access_exists(inode) 0 | 58 | # define posix_acl_access_exists(inode) 0 |
63 | # define posix_acl_default_exists(inode) 0 | 59 | # define posix_acl_default_exists(inode) 0 |
64 | #endif /* CONFIG_XFS_POSIX_ACL */ | 60 | #endif /* CONFIG_XFS_POSIX_ACL */ |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 76c540f719e4..5fcec6f020a7 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -83,7 +83,6 @@ xfs_inode_alloc( | |||
83 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); | 83 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); |
84 | ip->i_size = 0; | 84 | ip->i_size = 0; |
85 | ip->i_new_size = 0; | 85 | ip->i_new_size = 0; |
86 | xfs_inode_init_acls(ip); | ||
87 | 86 | ||
88 | /* | 87 | /* |
89 | * Initialize inode's trace buffers. | 88 | * Initialize inode's trace buffers. |
@@ -560,7 +559,6 @@ xfs_ireclaim( | |||
560 | ASSERT(atomic_read(&ip->i_pincount) == 0); | 559 | ASSERT(atomic_read(&ip->i_pincount) == 0); |
561 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | 560 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); |
562 | ASSERT(completion_done(&ip->i_flush)); | 561 | ASSERT(completion_done(&ip->i_flush)); |
563 | xfs_inode_clear_acls(ip); | ||
564 | kmem_zone_free(xfs_inode_zone, ip); | 562 | kmem_zone_free(xfs_inode_zone, ip); |
565 | } | 563 | } |
566 | 564 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 77016702938b..1804f866a71d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -273,11 +273,6 @@ typedef struct xfs_inode { | |||
273 | /* VFS inode */ | 273 | /* VFS inode */ |
274 | struct inode i_vnode; /* embedded VFS inode */ | 274 | struct inode i_vnode; /* embedded VFS inode */ |
275 | 275 | ||
276 | #ifdef CONFIG_XFS_POSIX_ACL | ||
277 | struct posix_acl *i_acl; | ||
278 | struct posix_acl *i_default_acl; | ||
279 | #endif | ||
280 | |||
281 | /* Trace buffers per inode. */ | 276 | /* Trace buffers per inode. */ |
282 | #ifdef XFS_INODE_TRACE | 277 | #ifdef XFS_INODE_TRACE |
283 | struct ktrace *i_trace; /* general inode trace */ | 278 | struct ktrace *i_trace; /* general inode trace */ |