ceph: check the cephx mds auth access for async dirop

Before doing the op locally we need to check the cephx access.

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:
Xiubo Li 2023-11-08 11:06:05 +08:00 committed by Ilya Dryomov
parent 845ae9d492
commit 2827badaf8
2 changed files with 59 additions and 0 deletions

View file

@ -1336,8 +1336,12 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
struct inode *inode = d_inode(dentry);
struct ceph_mds_request *req;
bool try_async = ceph_test_mount_opt(fsc, ASYNC_DIROPS);
struct dentry *dn;
int err = -EROFS;
int op;
char *path;
int pathlen;
u64 pathbase;
if (ceph_snap(dir) == CEPH_SNAPDIR) {
/* rmdir .snap/foo is RMSNAP */
@ -1351,6 +1355,30 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK;
} else
goto out;
dn = d_find_alias(dir);
if (!dn) {
try_async = false;
} else {
path = ceph_mdsc_build_path(mdsc, dn, &pathlen, &pathbase, 0);
if (IS_ERR(path)) {
try_async = false;
err = 0;
} else {
err = ceph_mds_check_access(mdsc, path, MAY_WRITE);
}
ceph_mdsc_free_path(path, pathlen);
dput(dn);
/* For none EACCES cases will let the MDS do the mds auth check */
if (err == -EACCES) {
return err;
} else if (err < 0) {
try_async = false;
err = 0;
}
}
retry:
req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
if (IS_ERR(req)) {

View file

@ -790,6 +790,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
bool try_async = ceph_test_mount_opt(fsc, ASYNC_DIROPS);
int mask;
int err;
char *path;
int pathlen;
u64 pathbase;
doutc(cl, "%p %llx.%llx dentry %p '%pd' %s flags %d mode 0%o\n",
dir, ceph_vinop(dir), dentry, dentry,
@ -807,6 +810,34 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
*/
flags &= ~O_TRUNC;
dn = d_find_alias(dir);
if (!dn) {
try_async = false;
} else {
path = ceph_mdsc_build_path(mdsc, dn, &pathlen, &pathbase, 0);
if (IS_ERR(path)) {
try_async = false;
err = 0;
} else {
int fmode = ceph_flags_to_mode(flags);
mask = MAY_READ;
if (fmode & CEPH_FILE_MODE_WR)
mask |= MAY_WRITE;
err = ceph_mds_check_access(mdsc, path, mask);
}
ceph_mdsc_free_path(path, pathlen);
dput(dn);
/* For none EACCES cases will let the MDS do the mds auth check */
if (err == -EACCES) {
return err;
} else if (err < 0) {
try_async = false;
err = 0;
}
}
retry:
if (flags & O_CREAT) {
if (ceph_quota_is_max_files_exceeded(dir))