ceph: add retry logic for error -ERANGE in ceph_get_acl()
When the size of acl extended attribution is larger than pre-allocated value buffer size, we will hit error '-ERANGE' and it's probabaly caused by concurrent get/set acl from different clients. In this case, current logic just sets acl to NULL so that we cannot get proper information but the operation looks successful. This patch adds retry logic for error -ERANGE and return -EIO if fail from the retry. Additionally, print real errno when failing from __ceph_getxattr(). Signed-off-by: Chengguang Xu <cgxu519@gmx.com> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Родитель
acb1872577
Коммит
f017754d69
|
@ -45,6 +45,7 @@ static inline void ceph_set_cached_acl(struct inode *inode,
|
|||
struct posix_acl *ceph_get_acl(struct inode *inode, int type)
|
||||
{
|
||||
int size;
|
||||
unsigned int retry_cnt = 0;
|
||||
const char *name;
|
||||
char *value = NULL;
|
||||
struct posix_acl *acl;
|
||||
|
@ -60,6 +61,7 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
|
|||
BUG();
|
||||
}
|
||||
|
||||
retry:
|
||||
size = __ceph_getxattr(inode, name, "", 0);
|
||||
if (size > 0) {
|
||||
value = kzalloc(size, GFP_NOFS);
|
||||
|
@ -68,12 +70,22 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
|
|||
size = __ceph_getxattr(inode, name, value, size);
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
if (size == -ERANGE && retry_cnt < 10) {
|
||||
retry_cnt++;
|
||||
kfree(value);
|
||||
value = NULL;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
acl = posix_acl_from_xattr(&init_user_ns, value, size);
|
||||
else if (size == -ERANGE || size == -ENODATA || size == 0)
|
||||
} else if (size == -ENODATA || size == 0) {
|
||||
acl = NULL;
|
||||
else
|
||||
} else {
|
||||
pr_err_ratelimited("get acl %llx.%llx failed, err=%d\n",
|
||||
ceph_vinop(inode), size);
|
||||
acl = ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
kfree(value);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче