ceph: check the cephx mds auth access for setattr
If we hit any failre just try to force it to do the sync setattr. Link: https://tracker.ceph.com/issues/61333 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Milind Changire <mchangir@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
596afb0b89
commit
ded6783040
@ -2480,6 +2480,34 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
|
|||||||
bool lock_snap_rwsem = false;
|
bool lock_snap_rwsem = false;
|
||||||
bool fill_fscrypt;
|
bool fill_fscrypt;
|
||||||
int truncate_retry = 20; /* The RMW will take around 50ms */
|
int truncate_retry = 20; /* The RMW will take around 50ms */
|
||||||
|
struct dentry *dentry;
|
||||||
|
char *path;
|
||||||
|
int pathlen;
|
||||||
|
u64 pathbase;
|
||||||
|
bool do_sync = false;
|
||||||
|
|
||||||
|
dentry = d_find_alias(inode);
|
||||||
|
if (!dentry) {
|
||||||
|
do_sync = true;
|
||||||
|
} else {
|
||||||
|
path = ceph_mdsc_build_path(mdsc, dentry, &pathlen, &pathbase, 0);
|
||||||
|
if (IS_ERR(path)) {
|
||||||
|
do_sync = true;
|
||||||
|
err = 0;
|
||||||
|
} else {
|
||||||
|
err = ceph_mds_check_access(mdsc, path, MAY_WRITE);
|
||||||
|
}
|
||||||
|
ceph_mdsc_free_path(path, pathlen);
|
||||||
|
dput(dentry);
|
||||||
|
|
||||||
|
/* For none EACCES cases will let the MDS do the mds auth check */
|
||||||
|
if (err == -EACCES) {
|
||||||
|
return err;
|
||||||
|
} else if (err < 0) {
|
||||||
|
do_sync = true;
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
prealloc_cf = ceph_alloc_cap_flush();
|
prealloc_cf = ceph_alloc_cap_flush();
|
||||||
@ -2526,7 +2554,7 @@ retry:
|
|||||||
/* It should never be re-set once set */
|
/* It should never be re-set once set */
|
||||||
WARN_ON_ONCE(ci->fscrypt_auth);
|
WARN_ON_ONCE(ci->fscrypt_auth);
|
||||||
|
|
||||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
|
||||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||||
kfree(ci->fscrypt_auth);
|
kfree(ci->fscrypt_auth);
|
||||||
ci->fscrypt_auth = (u8 *)cia->fscrypt_auth;
|
ci->fscrypt_auth = (u8 *)cia->fscrypt_auth;
|
||||||
@ -2555,7 +2583,7 @@ retry:
|
|||||||
ceph_vinop(inode),
|
ceph_vinop(inode),
|
||||||
from_kuid(&init_user_ns, inode->i_uid),
|
from_kuid(&init_user_ns, inode->i_uid),
|
||||||
from_kuid(&init_user_ns, attr->ia_uid));
|
from_kuid(&init_user_ns, attr->ia_uid));
|
||||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
|
||||||
inode->i_uid = fsuid;
|
inode->i_uid = fsuid;
|
||||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||||
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
||||||
@ -2573,7 +2601,7 @@ retry:
|
|||||||
ceph_vinop(inode),
|
ceph_vinop(inode),
|
||||||
from_kgid(&init_user_ns, inode->i_gid),
|
from_kgid(&init_user_ns, inode->i_gid),
|
||||||
from_kgid(&init_user_ns, attr->ia_gid));
|
from_kgid(&init_user_ns, attr->ia_gid));
|
||||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
|
||||||
inode->i_gid = fsgid;
|
inode->i_gid = fsgid;
|
||||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||||
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
||||||
@ -2587,7 +2615,7 @@ retry:
|
|||||||
if (ia_valid & ATTR_MODE) {
|
if (ia_valid & ATTR_MODE) {
|
||||||
doutc(cl, "%p %llx.%llx mode 0%o -> 0%o\n", inode,
|
doutc(cl, "%p %llx.%llx mode 0%o -> 0%o\n", inode,
|
||||||
ceph_vinop(inode), inode->i_mode, attr->ia_mode);
|
ceph_vinop(inode), inode->i_mode, attr->ia_mode);
|
||||||
if (issued & CEPH_CAP_AUTH_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
|
||||||
inode->i_mode = attr->ia_mode;
|
inode->i_mode = attr->ia_mode;
|
||||||
dirtied |= CEPH_CAP_AUTH_EXCL;
|
dirtied |= CEPH_CAP_AUTH_EXCL;
|
||||||
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
|
||||||
@ -2606,11 +2634,11 @@ retry:
|
|||||||
inode, ceph_vinop(inode),
|
inode, ceph_vinop(inode),
|
||||||
atime.tv_sec, atime.tv_nsec,
|
atime.tv_sec, atime.tv_nsec,
|
||||||
attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
|
attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
|
||||||
if (issued & CEPH_CAP_FILE_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_FILE_EXCL)) {
|
||||||
ci->i_time_warp_seq++;
|
ci->i_time_warp_seq++;
|
||||||
inode_set_atime_to_ts(inode, attr->ia_atime);
|
inode_set_atime_to_ts(inode, attr->ia_atime);
|
||||||
dirtied |= CEPH_CAP_FILE_EXCL;
|
dirtied |= CEPH_CAP_FILE_EXCL;
|
||||||
} else if ((issued & CEPH_CAP_FILE_WR) &&
|
} else if (!do_sync && (issued & CEPH_CAP_FILE_WR) &&
|
||||||
timespec64_compare(&atime,
|
timespec64_compare(&atime,
|
||||||
&attr->ia_atime) < 0) {
|
&attr->ia_atime) < 0) {
|
||||||
inode_set_atime_to_ts(inode, attr->ia_atime);
|
inode_set_atime_to_ts(inode, attr->ia_atime);
|
||||||
@ -2646,7 +2674,7 @@ retry:
|
|||||||
CEPH_FSCRYPT_BLOCK_SIZE));
|
CEPH_FSCRYPT_BLOCK_SIZE));
|
||||||
req->r_fscrypt_file = attr->ia_size;
|
req->r_fscrypt_file = attr->ia_size;
|
||||||
fill_fscrypt = true;
|
fill_fscrypt = true;
|
||||||
} else if ((issued & CEPH_CAP_FILE_EXCL) && attr->ia_size >= isize) {
|
} else if (!do_sync && (issued & CEPH_CAP_FILE_EXCL) && attr->ia_size >= isize) {
|
||||||
if (attr->ia_size > isize) {
|
if (attr->ia_size > isize) {
|
||||||
i_size_write(inode, attr->ia_size);
|
i_size_write(inode, attr->ia_size);
|
||||||
inode->i_blocks = calc_inode_blocks(attr->ia_size);
|
inode->i_blocks = calc_inode_blocks(attr->ia_size);
|
||||||
@ -2683,11 +2711,11 @@ retry:
|
|||||||
inode, ceph_vinop(inode),
|
inode, ceph_vinop(inode),
|
||||||
mtime.tv_sec, mtime.tv_nsec,
|
mtime.tv_sec, mtime.tv_nsec,
|
||||||
attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
|
attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
|
||||||
if (issued & CEPH_CAP_FILE_EXCL) {
|
if (!do_sync && (issued & CEPH_CAP_FILE_EXCL)) {
|
||||||
ci->i_time_warp_seq++;
|
ci->i_time_warp_seq++;
|
||||||
inode_set_mtime_to_ts(inode, attr->ia_mtime);
|
inode_set_mtime_to_ts(inode, attr->ia_mtime);
|
||||||
dirtied |= CEPH_CAP_FILE_EXCL;
|
dirtied |= CEPH_CAP_FILE_EXCL;
|
||||||
} else if ((issued & CEPH_CAP_FILE_WR) &&
|
} else if (!do_sync && (issued & CEPH_CAP_FILE_WR) &&
|
||||||
timespec64_compare(&mtime, &attr->ia_mtime) < 0) {
|
timespec64_compare(&mtime, &attr->ia_mtime) < 0) {
|
||||||
inode_set_mtime_to_ts(inode, attr->ia_mtime);
|
inode_set_mtime_to_ts(inode, attr->ia_mtime);
|
||||||
dirtied |= CEPH_CAP_FILE_WR;
|
dirtied |= CEPH_CAP_FILE_WR;
|
||||||
|
Loading…
Reference in New Issue
Block a user