diff options
Diffstat (limited to 'fs/reiserfs/xattr_acl.c')
-rw-r--r-- | fs/reiserfs/xattr_acl.c | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 9128e4d5ba64..d63b2c5850c3 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -172,6 +172,29 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) | |||
172 | return ERR_PTR(-EINVAL); | 172 | return ERR_PTR(-EINVAL); |
173 | } | 173 | } |
174 | 174 | ||
175 | static inline void iset_acl(struct inode *inode, struct posix_acl **i_acl, | ||
176 | struct posix_acl *acl) | ||
177 | { | ||
178 | spin_lock(&inode->i_lock); | ||
179 | if (*i_acl != ERR_PTR(-ENODATA)) | ||
180 | posix_acl_release(*i_acl); | ||
181 | *i_acl = posix_acl_dup(acl); | ||
182 | spin_unlock(&inode->i_lock); | ||
183 | } | ||
184 | |||
185 | static inline struct posix_acl *iget_acl(struct inode *inode, | ||
186 | struct posix_acl **i_acl) | ||
187 | { | ||
188 | struct posix_acl *acl = ERR_PTR(-ENODATA); | ||
189 | |||
190 | spin_lock(&inode->i_lock); | ||
191 | if (*i_acl != ERR_PTR(-ENODATA)) | ||
192 | acl = posix_acl_dup(*i_acl); | ||
193 | spin_unlock(&inode->i_lock); | ||
194 | |||
195 | return acl; | ||
196 | } | ||
197 | |||
175 | /* | 198 | /* |
176 | * Inode operation get_posix_acl(). | 199 | * Inode operation get_posix_acl(). |
177 | * | 200 | * |
@@ -199,11 +222,11 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) | |||
199 | return ERR_PTR(-EINVAL); | 222 | return ERR_PTR(-EINVAL); |
200 | } | 223 | } |
201 | 224 | ||
202 | if (IS_ERR(*p_acl)) { | 225 | acl = iget_acl(inode, p_acl); |
203 | if (PTR_ERR(*p_acl) == -ENODATA) | 226 | if (acl && !IS_ERR(acl)) |
204 | return NULL; | 227 | return acl; |
205 | } else if (*p_acl != NULL) | 228 | else if (PTR_ERR(acl) == -ENODATA) |
206 | return posix_acl_dup(*p_acl); | 229 | return NULL; |
207 | 230 | ||
208 | size = reiserfs_xattr_get(inode, name, NULL, 0); | 231 | size = reiserfs_xattr_get(inode, name, NULL, 0); |
209 | if (size < 0) { | 232 | if (size < 0) { |
@@ -229,7 +252,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) | |||
229 | } else { | 252 | } else { |
230 | acl = posix_acl_from_disk(value, retval); | 253 | acl = posix_acl_from_disk(value, retval); |
231 | if (!IS_ERR(acl)) | 254 | if (!IS_ERR(acl)) |
232 | *p_acl = posix_acl_dup(acl); | 255 | iset_acl(inode, p_acl, acl); |
233 | } | 256 | } |
234 | 257 | ||
235 | kfree(value); | 258 | kfree(value); |
@@ -300,16 +323,8 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
300 | 323 | ||
301 | kfree(value); | 324 | kfree(value); |
302 | 325 | ||
303 | if (!error) { | 326 | if (!error) |
304 | /* Release the old one */ | 327 | iset_acl(inode, p_acl, acl); |
305 | if (!IS_ERR(*p_acl) && *p_acl) | ||
306 | posix_acl_release(*p_acl); | ||
307 | |||
308 | if (acl == NULL) | ||
309 | *p_acl = ERR_PTR(-ENODATA); | ||
310 | else | ||
311 | *p_acl = posix_acl_dup(acl); | ||
312 | } | ||
313 | 328 | ||
314 | return error; | 329 | return error; |
315 | } | 330 | } |
@@ -404,9 +419,7 @@ int reiserfs_cache_default_acl(struct inode *inode) | |||
404 | if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { | 419 | if (reiserfs_posixacl(inode->i_sb) && !IS_PRIVATE(inode)) { |
405 | struct posix_acl *acl; | 420 | struct posix_acl *acl; |
406 | reiserfs_read_lock_xattr_i(inode); | 421 | reiserfs_read_lock_xattr_i(inode); |
407 | reiserfs_read_lock_xattrs(inode->i_sb); | ||
408 | acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); | 422 | acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); |
409 | reiserfs_read_unlock_xattrs(inode->i_sb); | ||
410 | reiserfs_read_unlock_xattr_i(inode); | 423 | reiserfs_read_unlock_xattr_i(inode); |
411 | ret = (acl && !IS_ERR(acl)); | 424 | ret = (acl && !IS_ERR(acl)); |
412 | if (ret) | 425 | if (ret) |
@@ -429,9 +442,7 @@ int reiserfs_acl_chmod(struct inode *inode) | |||
429 | return 0; | 442 | return 0; |
430 | } | 443 | } |
431 | 444 | ||
432 | reiserfs_read_lock_xattrs(inode->i_sb); | ||
433 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | 445 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); |
434 | reiserfs_read_unlock_xattrs(inode->i_sb); | ||
435 | if (!acl) | 446 | if (!acl) |
436 | return 0; | 447 | return 0; |
437 | if (IS_ERR(acl)) | 448 | if (IS_ERR(acl)) |
@@ -442,17 +453,8 @@ int reiserfs_acl_chmod(struct inode *inode) | |||
442 | return -ENOMEM; | 453 | return -ENOMEM; |
443 | error = posix_acl_chmod_masq(clone, inode->i_mode); | 454 | error = posix_acl_chmod_masq(clone, inode->i_mode); |
444 | if (!error) { | 455 | if (!error) { |
445 | int lock = !has_xattr_dir(inode); | ||
446 | reiserfs_write_lock_xattr_i(inode); | 456 | reiserfs_write_lock_xattr_i(inode); |
447 | if (lock) | ||
448 | reiserfs_write_lock_xattrs(inode->i_sb); | ||
449 | else | ||
450 | reiserfs_read_lock_xattrs(inode->i_sb); | ||
451 | error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); | 457 | error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); |
452 | if (lock) | ||
453 | reiserfs_write_unlock_xattrs(inode->i_sb); | ||
454 | else | ||
455 | reiserfs_read_unlock_xattrs(inode->i_sb); | ||
456 | reiserfs_write_unlock_xattr_i(inode); | 458 | reiserfs_write_unlock_xattr_i(inode); |
457 | } | 459 | } |
458 | posix_acl_release(clone); | 460 | posix_acl_release(clone); |
@@ -480,14 +482,9 @@ posix_acl_access_set(struct inode *inode, const char *name, | |||
480 | static int posix_acl_access_del(struct inode *inode, const char *name) | 482 | static int posix_acl_access_del(struct inode *inode, const char *name) |
481 | { | 483 | { |
482 | struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); | 484 | struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); |
483 | struct posix_acl **acl = &reiserfs_i->i_acl_access; | ||
484 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) | 485 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) |
485 | return -EINVAL; | 486 | return -EINVAL; |
486 | if (!IS_ERR(*acl) && *acl) { | 487 | iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA)); |
487 | posix_acl_release(*acl); | ||
488 | *acl = ERR_PTR(-ENODATA); | ||
489 | } | ||
490 | |||
491 | return 0; | 488 | return 0; |
492 | } | 489 | } |
493 | 490 | ||
@@ -533,14 +530,9 @@ posix_acl_default_set(struct inode *inode, const char *name, | |||
533 | static int posix_acl_default_del(struct inode *inode, const char *name) | 530 | static int posix_acl_default_del(struct inode *inode, const char *name) |
534 | { | 531 | { |
535 | struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); | 532 | struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); |
536 | struct posix_acl **acl = &reiserfs_i->i_acl_default; | ||
537 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) | 533 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) |
538 | return -EINVAL; | 534 | return -EINVAL; |
539 | if (!IS_ERR(*acl) && *acl) { | 535 | iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA)); |
540 | posix_acl_release(*acl); | ||
541 | *acl = ERR_PTR(-ENODATA); | ||
542 | } | ||
543 | |||
544 | return 0; | 536 | return 0; |
545 | } | 537 | } |
546 | 538 | ||