|
@@ -60,15 +60,20 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
|
|
return ERR_PTR(-EINVAL);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Handle the cached NULL acl case without locking */
|
|
|
|
+ acl = ACCESS_ONCE(*p_acl);
|
|
|
|
+ if (!acl)
|
|
|
|
+ return acl;
|
|
|
|
+
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
- if (*p_acl != BTRFS_ACL_NOT_CACHED)
|
|
|
|
- acl = posix_acl_dup(*p_acl);
|
|
|
|
|
|
+ acl = *p_acl;
|
|
|
|
+ if (acl != BTRFS_ACL_NOT_CACHED)
|
|
|
|
+ acl = posix_acl_dup(acl);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
|
|
|
|
- if (acl)
|
|
|
|
|
|
+ if (acl != BTRFS_ACL_NOT_CACHED)
|
|
return acl;
|
|
return acl;
|
|
|
|
|
|
-
|
|
|
|
size = __btrfs_getxattr(inode, name, "", 0);
|
|
size = __btrfs_getxattr(inode, name, "", 0);
|
|
if (size > 0) {
|
|
if (size > 0) {
|
|
value = kzalloc(size, GFP_NOFS);
|
|
value = kzalloc(size, GFP_NOFS);
|
|
@@ -80,9 +85,12 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
|
|
btrfs_update_cached_acl(inode, p_acl, acl);
|
|
btrfs_update_cached_acl(inode, p_acl, acl);
|
|
}
|
|
}
|
|
kfree(value);
|
|
kfree(value);
|
|
- } else if (size == -ENOENT) {
|
|
|
|
|
|
+ } else if (size == -ENOENT || size == -ENODATA || size == 0) {
|
|
|
|
+ /* FIXME, who returns -ENOENT? I think nobody */
|
|
acl = NULL;
|
|
acl = NULL;
|
|
btrfs_update_cached_acl(inode, p_acl, acl);
|
|
btrfs_update_cached_acl(inode, p_acl, acl);
|
|
|
|
+ } else {
|
|
|
|
+ acl = ERR_PTR(-EIO);
|
|
}
|
|
}
|
|
|
|
|
|
return acl;
|
|
return acl;
|