1

ceph: check the cephx mds auth access for open

Before opening the file 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 10:54:35 +08:00 committed by Ilya Dryomov
parent ded6783040
commit 845ae9d492

View File

@ -366,6 +366,12 @@ int ceph_open(struct inode *inode, struct file *file)
struct ceph_file_info *fi = file->private_data; struct ceph_file_info *fi = file->private_data;
int err; int err;
int flags, fmode, wanted; int flags, fmode, wanted;
struct dentry *dentry;
char *path;
int pathlen;
u64 pathbase;
bool do_sync = false;
int mask = MAY_READ;
if (fi) { if (fi) {
doutc(cl, "file %p is already opened\n", file); doutc(cl, "file %p is already opened\n", file);
@ -387,6 +393,31 @@ int ceph_open(struct inode *inode, struct file *file)
fmode = ceph_flags_to_mode(flags); fmode = ceph_flags_to_mode(flags);
wanted = ceph_caps_for_mode(fmode); wanted = ceph_caps_for_mode(fmode);
if (fmode & CEPH_FILE_MODE_WR)
mask |= MAY_WRITE;
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, mask);
}
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;
}
}
/* snapped files are read-only */ /* snapped files are read-only */
if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE)) if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
return -EROFS; return -EROFS;
@ -402,7 +433,7 @@ int ceph_open(struct inode *inode, struct file *file)
* asynchronously. * asynchronously.
*/ */
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
if (__ceph_is_any_real_caps(ci) && if (!do_sync && __ceph_is_any_real_caps(ci) &&
(((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) { (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) {
int mds_wanted = __ceph_caps_mds_wanted(ci, true); int mds_wanted = __ceph_caps_mds_wanted(ci, true);
int issued = __ceph_caps_issued(ci, NULL); int issued = __ceph_caps_issued(ci, NULL);
@ -420,7 +451,7 @@ int ceph_open(struct inode *inode, struct file *file)
ceph_check_caps(ci, 0); ceph_check_caps(ci, 0);
return ceph_init_file(inode, file, fmode); return ceph_init_file(inode, file, fmode);
} else if (ceph_snap(inode) != CEPH_NOSNAP && } else if (!do_sync && ceph_snap(inode) != CEPH_NOSNAP &&
(ci->i_snap_caps & wanted) == wanted) { (ci->i_snap_caps & wanted) == wanted) {
__ceph_touch_fmode(ci, mdsc, fmode); __ceph_touch_fmode(ci, mdsc, fmode);
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);