Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit ded6783

Browse files
lxbszidryomov
authored andcommitted
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>
1 parent 596afb0 commit ded6783

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

fs/ceph/inode.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,34 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
24802480
bool lock_snap_rwsem = false;
24812481
bool fill_fscrypt;
24822482
int truncate_retry = 20; /* The RMW will take around 50ms */
2483+
struct dentry *dentry;
2484+
char *path;
2485+
int pathlen;
2486+
u64 pathbase;
2487+
bool do_sync = false;
2488+
2489+
dentry = d_find_alias(inode);
2490+
if (!dentry) {
2491+
do_sync = true;
2492+
} else {
2493+
path = ceph_mdsc_build_path(mdsc, dentry, &pathlen, &pathbase, 0);
2494+
if (IS_ERR(path)) {
2495+
do_sync = true;
2496+
err = 0;
2497+
} else {
2498+
err = ceph_mds_check_access(mdsc, path, MAY_WRITE);
2499+
}
2500+
ceph_mdsc_free_path(path, pathlen);
2501+
dput(dentry);
2502+
2503+
/* For none EACCES cases will let the MDS do the mds auth check */
2504+
if (err == -EACCES) {
2505+
return err;
2506+
} else if (err < 0) {
2507+
do_sync = true;
2508+
err = 0;
2509+
}
2510+
}
24832511

24842512
retry:
24852513
prealloc_cf = ceph_alloc_cap_flush();
@@ -2526,7 +2554,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
25262554
/* It should never be re-set once set */
25272555
WARN_ON_ONCE(ci->fscrypt_auth);
25282556

2529-
if (issued & CEPH_CAP_AUTH_EXCL) {
2557+
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
25302558
dirtied |= CEPH_CAP_AUTH_EXCL;
25312559
kfree(ci->fscrypt_auth);
25322560
ci->fscrypt_auth = (u8 *)cia->fscrypt_auth;
@@ -2555,7 +2583,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
25552583
ceph_vinop(inode),
25562584
from_kuid(&init_user_ns, inode->i_uid),
25572585
from_kuid(&init_user_ns, attr->ia_uid));
2558-
if (issued & CEPH_CAP_AUTH_EXCL) {
2586+
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
25592587
inode->i_uid = fsuid;
25602588
dirtied |= CEPH_CAP_AUTH_EXCL;
25612589
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
@@ -2573,7 +2601,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
25732601
ceph_vinop(inode),
25742602
from_kgid(&init_user_ns, inode->i_gid),
25752603
from_kgid(&init_user_ns, attr->ia_gid));
2576-
if (issued & CEPH_CAP_AUTH_EXCL) {
2604+
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
25772605
inode->i_gid = fsgid;
25782606
dirtied |= CEPH_CAP_AUTH_EXCL;
25792607
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
@@ -2587,7 +2615,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
25872615
if (ia_valid & ATTR_MODE) {
25882616
doutc(cl, "%p %llx.%llx mode 0%o -> 0%o\n", inode,
25892617
ceph_vinop(inode), inode->i_mode, attr->ia_mode);
2590-
if (issued & CEPH_CAP_AUTH_EXCL) {
2618+
if (!do_sync && (issued & CEPH_CAP_AUTH_EXCL)) {
25912619
inode->i_mode = attr->ia_mode;
25922620
dirtied |= CEPH_CAP_AUTH_EXCL;
25932621
} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
@@ -2606,11 +2634,11 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
26062634
inode, ceph_vinop(inode),
26072635
atime.tv_sec, atime.tv_nsec,
26082636
attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
2609-
if (issued & CEPH_CAP_FILE_EXCL) {
2637+
if (!do_sync && (issued & CEPH_CAP_FILE_EXCL)) {
26102638
ci->i_time_warp_seq++;
26112639
inode_set_atime_to_ts(inode, attr->ia_atime);
26122640
dirtied |= CEPH_CAP_FILE_EXCL;
2613-
} else if ((issued & CEPH_CAP_FILE_WR) &&
2641+
} else if (!do_sync && (issued & CEPH_CAP_FILE_WR) &&
26142642
timespec64_compare(&atime,
26152643
&attr->ia_atime) < 0) {
26162644
inode_set_atime_to_ts(inode, attr->ia_atime);
@@ -2646,7 +2674,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
26462674
CEPH_FSCRYPT_BLOCK_SIZE));
26472675
req->r_fscrypt_file = attr->ia_size;
26482676
fill_fscrypt = true;
2649-
} else if ((issued & CEPH_CAP_FILE_EXCL) && attr->ia_size >= isize) {
2677+
} else if (!do_sync && (issued & CEPH_CAP_FILE_EXCL) && attr->ia_size >= isize) {
26502678
if (attr->ia_size > isize) {
26512679
i_size_write(inode, attr->ia_size);
26522680
inode->i_blocks = calc_inode_blocks(attr->ia_size);
@@ -2683,11 +2711,11 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode,
26832711
inode, ceph_vinop(inode),
26842712
mtime.tv_sec, mtime.tv_nsec,
26852713
attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
2686-
if (issued & CEPH_CAP_FILE_EXCL) {
2714+
if (!do_sync && (issued & CEPH_CAP_FILE_EXCL)) {
26872715
ci->i_time_warp_seq++;
26882716
inode_set_mtime_to_ts(inode, attr->ia_mtime);
26892717
dirtied |= CEPH_CAP_FILE_EXCL;
2690-
} else if ((issued & CEPH_CAP_FILE_WR) &&
2718+
} else if (!do_sync && (issued & CEPH_CAP_FILE_WR) &&
26912719
timespec64_compare(&mtime, &attr->ia_mtime) < 0) {
26922720
inode_set_mtime_to_ts(inode, attr->ia_mtime);
26932721
dirtied |= CEPH_CAP_FILE_WR;

0 commit comments

Comments
 (0)