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

Commit 1d17de9

Browse files
lxbszidryomov
authored andcommitted
ceph: save cap_auths in MDS client when session is opened
Save the cap_auths, which have been parsed by the MDS, in the opened session. [ idryomov: use s64 and u32 instead of int64_t and uint32_t, switch to bool for root_squash, readable and writeable ] 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 a38297e commit 1d17de9

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

fs/ceph/mds_client.c

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4112,10 +4112,13 @@ static void handle_session(struct ceph_mds_session *session,
41124112
void *p = msg->front.iov_base;
41134113
void *end = p + msg->front.iov_len;
41144114
struct ceph_mds_session_head *h;
4115-
u32 op;
4115+
struct ceph_mds_cap_auth *cap_auths = NULL;
4116+
u32 op, cap_auths_num = 0;
41164117
u64 seq, features = 0;
41174118
int wake = 0;
41184119
bool blocklisted = false;
4120+
u32 i;
4121+
41194122

41204123
/* decode */
41214124
ceph_decode_need(&p, end, sizeof(*h), bad);
@@ -4160,7 +4163,101 @@ static void handle_session(struct ceph_mds_session *session,
41604163
}
41614164
}
41624165

4166+
if (msg_version >= 6) {
4167+
ceph_decode_32_safe(&p, end, cap_auths_num, bad);
4168+
doutc(cl, "cap_auths_num %d\n", cap_auths_num);
4169+
4170+
if (cap_auths_num && op != CEPH_SESSION_OPEN) {
4171+
WARN_ON_ONCE(op != CEPH_SESSION_OPEN);
4172+
goto skip_cap_auths;
4173+
}
4174+
4175+
cap_auths = kcalloc(cap_auths_num,
4176+
sizeof(struct ceph_mds_cap_auth),
4177+
GFP_KERNEL);
4178+
if (!cap_auths) {
4179+
pr_err_client(cl, "No memory for cap_auths\n");
4180+
return;
4181+
}
4182+
4183+
for (i = 0; i < cap_auths_num; i++) {
4184+
u32 _len, j;
4185+
4186+
/* struct_v, struct_compat, and struct_len in MDSCapAuth */
4187+
ceph_decode_skip_n(&p, end, 2 + sizeof(u32), bad);
4188+
4189+
/* struct_v, struct_compat, and struct_len in MDSCapMatch */
4190+
ceph_decode_skip_n(&p, end, 2 + sizeof(u32), bad);
4191+
ceph_decode_64_safe(&p, end, cap_auths[i].match.uid, bad);
4192+
ceph_decode_32_safe(&p, end, _len, bad);
4193+
if (_len) {
4194+
cap_auths[i].match.gids = kcalloc(_len, sizeof(u32),
4195+
GFP_KERNEL);
4196+
if (!cap_auths[i].match.gids) {
4197+
pr_err_client(cl, "No memory for gids\n");
4198+
goto fail;
4199+
}
4200+
4201+
cap_auths[i].match.num_gids = _len;
4202+
for (j = 0; j < _len; j++)
4203+
ceph_decode_32_safe(&p, end,
4204+
cap_auths[i].match.gids[j],
4205+
bad);
4206+
}
4207+
4208+
ceph_decode_32_safe(&p, end, _len, bad);
4209+
if (_len) {
4210+
cap_auths[i].match.path = kcalloc(_len + 1, sizeof(char),
4211+
GFP_KERNEL);
4212+
if (!cap_auths[i].match.path) {
4213+
pr_err_client(cl, "No memory for path\n");
4214+
goto fail;
4215+
}
4216+
ceph_decode_copy(&p, cap_auths[i].match.path, _len);
4217+
4218+
/* Remove the tailing '/' */
4219+
while (_len && cap_auths[i].match.path[_len - 1] == '/') {
4220+
cap_auths[i].match.path[_len - 1] = '\0';
4221+
_len -= 1;
4222+
}
4223+
}
4224+
4225+
ceph_decode_32_safe(&p, end, _len, bad);
4226+
if (_len) {
4227+
cap_auths[i].match.fs_name = kcalloc(_len + 1, sizeof(char),
4228+
GFP_KERNEL);
4229+
if (!cap_auths[i].match.fs_name) {
4230+
pr_err_client(cl, "No memory for fs_name\n");
4231+
goto fail;
4232+
}
4233+
ceph_decode_copy(&p, cap_auths[i].match.fs_name, _len);
4234+
}
4235+
4236+
ceph_decode_8_safe(&p, end, cap_auths[i].match.root_squash, bad);
4237+
ceph_decode_8_safe(&p, end, cap_auths[i].readable, bad);
4238+
ceph_decode_8_safe(&p, end, cap_auths[i].writeable, bad);
4239+
doutc(cl, "uid %lld, num_gids %u, path %s, fs_name %s, root_squash %d, readable %d, writeable %d\n",
4240+
cap_auths[i].match.uid, cap_auths[i].match.num_gids,
4241+
cap_auths[i].match.path, cap_auths[i].match.fs_name,
4242+
cap_auths[i].match.root_squash,
4243+
cap_auths[i].readable, cap_auths[i].writeable);
4244+
}
4245+
}
4246+
4247+
skip_cap_auths:
41634248
mutex_lock(&mdsc->mutex);
4249+
if (op == CEPH_SESSION_OPEN) {
4250+
if (mdsc->s_cap_auths) {
4251+
for (i = 0; i < mdsc->s_cap_auths_num; i++) {
4252+
kfree(mdsc->s_cap_auths[i].match.gids);
4253+
kfree(mdsc->s_cap_auths[i].match.path);
4254+
kfree(mdsc->s_cap_auths[i].match.fs_name);
4255+
}
4256+
kfree(mdsc->s_cap_auths);
4257+
}
4258+
mdsc->s_cap_auths_num = cap_auths_num;
4259+
mdsc->s_cap_auths = cap_auths;
4260+
}
41644261
if (op == CEPH_SESSION_CLOSE) {
41654262
ceph_get_mds_session(session);
41664263
__unregister_session(mdsc, session);
@@ -4290,6 +4387,13 @@ static void handle_session(struct ceph_mds_session *session,
42904387
pr_err_client(cl, "corrupt message mds%d len %d\n", mds,
42914388
(int)msg->front.iov_len);
42924389
ceph_msg_dump(msg);
4390+
fail:
4391+
for (i = 0; i < cap_auths_num; i++) {
4392+
kfree(cap_auths[i].match.gids);
4393+
kfree(cap_auths[i].match.path);
4394+
kfree(cap_auths[i].match.fs_name);
4395+
}
4396+
kfree(cap_auths);
42934397
return;
42944398
}
42954399

fs/ceph/mds_client.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,24 @@ enum ceph_feature_type {
7171
struct ceph_fs_client;
7272
struct ceph_cap;
7373

74+
#define MDS_AUTH_UID_ANY -1
75+
76+
struct ceph_mds_cap_match {
77+
s64 uid; /* default to MDS_AUTH_UID_ANY */
78+
u32 num_gids;
79+
u32 *gids; /* use these GIDs */
80+
char *path; /* require path to be child of this
81+
(may be "" or "/" for any) */
82+
char *fs_name;
83+
bool root_squash; /* default to false */
84+
};
85+
86+
struct ceph_mds_cap_auth {
87+
struct ceph_mds_cap_match match;
88+
bool readable;
89+
bool writeable;
90+
};
91+
7492
/*
7593
* parsed info about a single inode. pointers are into the encoded
7694
* on-wire structures within the mds reply message payload.
@@ -513,6 +531,9 @@ struct ceph_mds_client {
513531
struct rw_semaphore pool_perm_rwsem;
514532
struct rb_root pool_perm_tree;
515533

534+
u32 s_cap_auths_num;
535+
struct ceph_mds_cap_auth *s_cap_auths;
536+
516537
char nodename[__NEW_UTS_LEN + 1];
517538
};
518539

0 commit comments

Comments
 (0)