^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/ceph/ceph_debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/backing-dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <keys/ceph-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/nsproxy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/statfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/ceph/ceph_features.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/ceph/libceph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/ceph/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/ceph/decode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/ceph/mon_client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/ceph/auth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "crypto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Module compatibility interface. For now it doesn't do anything,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * but its existence signals a certain level of functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * The data buffer is used to pass information both to and from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * libceph. The return value indicates whether libceph determines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * it is compatible with the caller (from another kernel module),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * given the provided data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * The data pointer can be null.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) bool libceph_compatible(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) EXPORT_SYMBOL(libceph_compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int param_get_supported_features(char *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) const struct kernel_param *kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return sprintf(buffer, "0x%llx", CEPH_FEATURES_SUPPORTED_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct kernel_param_ops param_ops_supported_features = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .get = param_get_supported_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) module_param_cb(supported_features, ¶m_ops_supported_features, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const char *ceph_msg_type_name(int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case CEPH_MSG_SHUTDOWN: return "shutdown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case CEPH_MSG_PING: return "ping";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case CEPH_MSG_AUTH: return "auth";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case CEPH_MSG_AUTH_REPLY: return "auth_reply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case CEPH_MSG_MON_MAP: return "mon_map";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case CEPH_MSG_MON_GET_MAP: return "mon_get_map";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case CEPH_MSG_STATFS: return "statfs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case CEPH_MSG_STATFS_REPLY: return "statfs_reply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) case CEPH_MSG_MON_GET_VERSION: return "mon_get_version";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case CEPH_MSG_MON_GET_VERSION_REPLY: return "mon_get_version_reply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case CEPH_MSG_MDS_MAP: return "mds_map";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) case CEPH_MSG_FS_MAP_USER: return "fs_map_user";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case CEPH_MSG_CLIENT_SESSION: return "client_session";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case CEPH_MSG_CLIENT_REQUEST: return "client_request";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case CEPH_MSG_CLIENT_REPLY: return "client_reply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case CEPH_MSG_CLIENT_CAPS: return "client_caps";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case CEPH_MSG_CLIENT_QUOTA: return "client_quota";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) case CEPH_MSG_CLIENT_SNAP: return "client_snap";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case CEPH_MSG_CLIENT_LEASE: return "client_lease";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) case CEPH_MSG_POOLOP_REPLY: return "poolop_reply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case CEPH_MSG_POOLOP: return "poolop";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case CEPH_MSG_MON_COMMAND: return "mon_command";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case CEPH_MSG_MON_COMMAND_ACK: return "mon_command_ack";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case CEPH_MSG_OSD_MAP: return "osd_map";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case CEPH_MSG_OSD_OP: return "osd_op";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case CEPH_MSG_WATCH_NOTIFY: return "watch_notify";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case CEPH_MSG_OSD_BACKOFF: return "osd_backoff";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) default: return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXPORT_SYMBOL(ceph_msg_type_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * Initially learn our fsid, or verify an fsid matches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (client->have_fsid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ceph_fsid_compare(&client->fsid, fsid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pr_err("bad fsid, had %pU got %pU",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) &client->fsid, fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) memcpy(&client->fsid, fsid, sizeof(*fsid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) EXPORT_SYMBOL(ceph_check_fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int strcmp_null(const char *s1, const char *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!s1 && !s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (s1 && !s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!s1 && s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return strcmp(s1, s2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int ceph_compare_options(struct ceph_options *new_opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct ceph_options *opt1 = new_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct ceph_options *opt2 = client->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int ofs = offsetof(struct ceph_options, mon_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Don't bother comparing options if network namespaces don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!net_eq(current->nsproxy->net_ns, read_pnet(&client->msgr.net)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = memcmp(opt1, opt2, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ret = strcmp_null(opt1->name, opt2->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (opt1->key && !opt2->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!opt1->key && opt2->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (opt1->key && opt2->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (opt1->key->type != opt2->key->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (opt1->key->len != opt2->key->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (opt1->key->key && !opt2->key->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!opt1->key->key && opt2->key->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (opt1->key->key && opt2->key->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = ceph_compare_crush_locs(&opt1->crush_locs, &opt2->crush_locs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* any matching mon ip implies a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) for (i = 0; i < opt1->num_mon; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (ceph_monmap_contains(client->monc.monmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) &opt1->mon_addr[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL(ceph_compare_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * kvmalloc() doesn't fall back to the vmalloc allocator unless flags are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * compatible with (a superset of) GFP_KERNEL. This is because while the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * actual pages are allocated with the specified flags, the page table pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * are always allocated with GFP_KERNEL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * ceph_kvmalloc() may be called with GFP_KERNEL, GFP_NOFS or GFP_NOIO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void *ceph_kvmalloc(size_t size, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if ((flags & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) p = kvmalloc(size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) } else if ((flags & (__GFP_IO | __GFP_FS)) == __GFP_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned int nofs_flag = memalloc_nofs_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) p = kvmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) memalloc_nofs_restore(nofs_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned int noio_flag = memalloc_noio_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) p = kvmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) memalloc_noio_restore(noio_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int parse_fsid(const char *str, struct ceph_fsid *fsid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) char tmp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dout("parse_fsid '%s'\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) tmp[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) while (*str && i < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ispunct(*str)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (!isxdigit(str[0]) || !isxdigit(str[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) tmp[0] = str[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) tmp[1] = str[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (sscanf(tmp, "%x", &d) < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) fsid->fsid[i] = d & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) str += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (i == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dout("parse_fsid ret %d got fsid %pU\n", err, fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * ceph options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) Opt_osdtimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) Opt_osdkeepalivetimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) Opt_mount_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) Opt_osd_idle_ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) Opt_osd_request_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* int args above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) Opt_fsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) Opt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) Opt_secret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) Opt_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) Opt_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) Opt_crush_location,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) Opt_read_from_replica,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* string args above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) Opt_share,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) Opt_crc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) Opt_cephx_require_signatures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) Opt_cephx_sign_messages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) Opt_tcp_nodelay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) Opt_abort_on_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) Opt_read_from_replica_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) Opt_read_from_replica_balance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) Opt_read_from_replica_localize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static const struct constant_table ceph_param_read_from_replica[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {"no", Opt_read_from_replica_no},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {"balance", Opt_read_from_replica_balance},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {"localize", Opt_read_from_replica_localize},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static const struct fs_parameter_spec ceph_parameters[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) fsparam_flag ("abort_on_full", Opt_abort_on_full),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) fsparam_flag_no ("cephx_require_signatures", Opt_cephx_require_signatures),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fsparam_flag_no ("cephx_sign_messages", Opt_cephx_sign_messages),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) fsparam_flag_no ("crc", Opt_crc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) fsparam_string ("crush_location", Opt_crush_location),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) fsparam_string ("fsid", Opt_fsid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) fsparam_string ("ip", Opt_ip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) fsparam_string ("key", Opt_key),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fsparam_u32 ("mount_timeout", Opt_mount_timeout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) fsparam_string ("name", Opt_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) fsparam_u32 ("osd_idle_ttl", Opt_osd_idle_ttl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) fsparam_u32 ("osd_request_timeout", Opt_osd_request_timeout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) fsparam_u32 ("osdkeepalive", Opt_osdkeepalivetimeout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) __fsparam (fs_param_is_s32, "osdtimeout", Opt_osdtimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) fs_param_deprecated, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) fsparam_enum ("read_from_replica", Opt_read_from_replica,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ceph_param_read_from_replica),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fsparam_string ("secret", Opt_secret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) fsparam_flag_no ("share", Opt_share),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) fsparam_flag_no ("tcp_nodelay", Opt_tcp_nodelay),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct ceph_options *ceph_alloc_options(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct ceph_options *opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) opt = kzalloc(sizeof(*opt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) opt->crush_locs = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!opt->mon_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) kfree(opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) opt->flags = CEPH_OPT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) opt->osd_request_timeout = CEPH_OSD_REQUEST_TIMEOUT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) opt->read_from_replica = CEPH_READ_FROM_REPLICA_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) EXPORT_SYMBOL(ceph_alloc_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) void ceph_destroy_options(struct ceph_options *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dout("destroy_options %p\n", opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ceph_clear_crush_locs(&opt->crush_locs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) kfree(opt->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (opt->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ceph_crypto_key_destroy(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) kfree(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) kfree(opt->mon_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) kfree(opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) EXPORT_SYMBOL(ceph_destroy_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* get secret from key store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int get_secret(struct ceph_crypto_key *dst, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct p_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct key *ukey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int key_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct ceph_crypto_key *ckey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ukey = request_key(&key_type_ceph, name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (IS_ERR(ukey)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* request_key errors don't map nicely to mount(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) errors; don't even try, but still printk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) key_err = PTR_ERR(ukey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) switch (key_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case -ENOKEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) error_plog(log, "Failed due to key not found: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case -EKEYEXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) error_plog(log, "Failed due to expired key: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case -EKEYREVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) error_plog(log, "Failed due to revoked key: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) error_plog(log, "Failed due to key error %d: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) key_err, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ckey = ukey->payload.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) err = ceph_crypto_key_clone(dst, ckey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto out_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* pass through, err is 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) out_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) key_put(ukey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct fc_log *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct p_log log = {.prefix = "libceph", .log = l};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* ip1[:port1][,ip2[:port2]...] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) &opt->num_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) error_plog(&log, "Failed to parse monitor IPs: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) EXPORT_SYMBOL(ceph_parse_mon_ips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct fc_log *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct fs_parse_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int token, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct p_log log = {.prefix = "libceph", .log = l};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) token = __fs_parse(&log, ceph_parameters, param, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (token < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) case Opt_ip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) err = ceph_parse_ips(param->string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) param->string + param->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) &opt->my_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) error_plog(&log, "Failed to parse ip: %d", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) opt->flags |= CEPH_OPT_MYIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case Opt_fsid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) err = parse_fsid(param->string, &opt->fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) error_plog(&log, "Failed to parse fsid: %d", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) opt->flags |= CEPH_OPT_FSID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case Opt_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) kfree(opt->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) opt->name = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case Opt_secret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ceph_crypto_key_destroy(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) kfree(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!opt->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) err = ceph_crypto_key_unarmor(opt->key, param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) error_plog(&log, "Failed to parse secret: %d", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) case Opt_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ceph_crypto_key_destroy(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) kfree(opt->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!opt->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return get_secret(opt->key, param->string, &log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case Opt_crush_location:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ceph_clear_crush_locs(&opt->crush_locs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) err = ceph_parse_crush_location(param->string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) &opt->crush_locs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) error_plog(&log, "Failed to parse CRUSH location: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case Opt_read_from_replica:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) switch (result.uint_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case Opt_read_from_replica_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) opt->read_from_replica = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case Opt_read_from_replica_balance:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) opt->read_from_replica = CEPH_OSD_FLAG_BALANCE_READS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case Opt_read_from_replica_localize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) opt->read_from_replica = CEPH_OSD_FLAG_LOCALIZE_READS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case Opt_osdtimeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) warn_plog(&log, "Ignoring osdtimeout");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case Opt_osdkeepalivetimeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* 0 isn't well defined right now, reject it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto out_of_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) opt->osd_keepalive_timeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) msecs_to_jiffies(result.uint_32 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) case Opt_osd_idle_ttl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* 0 isn't well defined right now, reject it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (result.uint_32 < 1 || result.uint_32 > INT_MAX / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) goto out_of_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) opt->osd_idle_ttl = msecs_to_jiffies(result.uint_32 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case Opt_mount_timeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* 0 is "wait forever" (i.e. infinite timeout) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (result.uint_32 > INT_MAX / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto out_of_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) opt->mount_timeout = msecs_to_jiffies(result.uint_32 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case Opt_osd_request_timeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* 0 is "wait forever" (i.e. infinite timeout) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (result.uint_32 > INT_MAX / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) goto out_of_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) opt->osd_request_timeout =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) msecs_to_jiffies(result.uint_32 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case Opt_share:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) opt->flags &= ~CEPH_OPT_NOSHARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) opt->flags |= CEPH_OPT_NOSHARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case Opt_crc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) opt->flags &= ~CEPH_OPT_NOCRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) opt->flags |= CEPH_OPT_NOCRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case Opt_cephx_require_signatures:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) opt->flags &= ~CEPH_OPT_NOMSGAUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) opt->flags |= CEPH_OPT_NOMSGAUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) case Opt_cephx_sign_messages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) opt->flags &= ~CEPH_OPT_NOMSGSIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) opt->flags |= CEPH_OPT_NOMSGSIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case Opt_tcp_nodelay:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) opt->flags |= CEPH_OPT_TCP_NODELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) opt->flags &= ~CEPH_OPT_TCP_NODELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case Opt_abort_on_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) opt->flags |= CEPH_OPT_ABORT_ON_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) out_of_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return inval_plog(&log, "%s out of range", param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) EXPORT_SYMBOL(ceph_parse_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) bool show_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct ceph_options *opt = client->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) size_t pos = m->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (opt->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) seq_puts(m, "name=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) seq_escape(m, opt->name, ", \t\n\\");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) seq_putc(m, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (opt->key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) seq_puts(m, "secret=<hidden>,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!RB_EMPTY_ROOT(&opt->crush_locs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) seq_puts(m, "crush_location=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) for (n = rb_first(&opt->crush_locs); ; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct crush_loc_node *loc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) rb_entry(n, struct crush_loc_node, cl_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) seq_printf(m, "%s:%s", loc->cl_loc.cl_type_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) loc->cl_loc.cl_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) n = rb_next(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) seq_putc(m, '|');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) seq_putc(m, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (opt->read_from_replica == CEPH_OSD_FLAG_BALANCE_READS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) seq_puts(m, "read_from_replica=balance,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) } else if (opt->read_from_replica == CEPH_OSD_FLAG_LOCALIZE_READS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) seq_puts(m, "read_from_replica=localize,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (opt->flags & CEPH_OPT_FSID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) seq_printf(m, "fsid=%pU,", &opt->fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (opt->flags & CEPH_OPT_NOSHARE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) seq_puts(m, "noshare,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (opt->flags & CEPH_OPT_NOCRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) seq_puts(m, "nocrc,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (opt->flags & CEPH_OPT_NOMSGAUTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) seq_puts(m, "nocephx_require_signatures,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (opt->flags & CEPH_OPT_NOMSGSIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) seq_puts(m, "nocephx_sign_messages,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if ((opt->flags & CEPH_OPT_TCP_NODELAY) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) seq_puts(m, "notcp_nodelay,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (show_all && (opt->flags & CEPH_OPT_ABORT_ON_FULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) seq_puts(m, "abort_on_full,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) seq_printf(m, "mount_timeout=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) jiffies_to_msecs(opt->mount_timeout) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) seq_printf(m, "osd_idle_ttl=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) jiffies_to_msecs(opt->osd_idle_ttl) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) seq_printf(m, "osdkeepalivetimeout=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) jiffies_to_msecs(opt->osd_keepalive_timeout) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (opt->osd_request_timeout != CEPH_OSD_REQUEST_TIMEOUT_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) seq_printf(m, "osd_request_timeout=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) jiffies_to_msecs(opt->osd_request_timeout) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* drop redundant comma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (m->count != pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) m->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) EXPORT_SYMBOL(ceph_print_client_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return &client->msgr.inst.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) EXPORT_SYMBOL(ceph_client_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) u64 ceph_client_gid(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return client->monc.auth->global_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) EXPORT_SYMBOL(ceph_client_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * create a fresh client instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct ceph_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct ceph_entity_addr *myaddr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err = wait_for_random_bytes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) client = kzalloc(sizeof(*client), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (client == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) client->private = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) client->options = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) mutex_init(&client->mount_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) init_waitqueue_head(&client->auth_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) client->auth_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) client->extra_mon_dispatch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) client->supported_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) client->required_features = CEPH_FEATURES_REQUIRED_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (!ceph_test_opt(client, NOMSGAUTH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) client->required_features |= CEPH_FEATURE_MSG_AUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* msgr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ceph_test_opt(client, MYIP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) myaddr = &client->options->my_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ceph_messenger_init(&client->msgr, myaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* subsystems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) err = ceph_monc_init(&client->monc, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) err = ceph_osdc_init(&client->osdc, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto fail_monc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) fail_monc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ceph_monc_stop(&client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ceph_messenger_fini(&client->msgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) EXPORT_SYMBOL(ceph_create_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) void ceph_destroy_client(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dout("destroy_client %p\n", client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) atomic_set(&client->msgr.stopping, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* unmount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ceph_osdc_stop(&client->osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ceph_monc_stop(&client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ceph_messenger_fini(&client->msgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ceph_debugfs_client_cleanup(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ceph_destroy_options(client->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) dout("destroy_client %p done\n", client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) EXPORT_SYMBOL(ceph_destroy_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) void ceph_reset_client_addr(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ceph_messenger_reset_nonce(&client->msgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ceph_monc_reopen_session(&client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ceph_osdc_reopen_osds(&client->osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) EXPORT_SYMBOL(ceph_reset_client_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * true if we have the mon map (and have thus joined the cluster)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static bool have_mon_and_osd_map(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return client->monc.monmap && client->monc.monmap->epoch &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) client->osdc.osdmap && client->osdc.osdmap->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * mount: join the ceph cluster, and open root directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int __ceph_open_session(struct ceph_client *client, unsigned long started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) unsigned long timeout = client->options->mount_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) long err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* open session, and wait for mon and osd maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) err = ceph_monc_open_session(&client->monc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) while (!have_mon_and_osd_map(client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (timeout && time_after_eq(jiffies, started + timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dout("mount waiting for mon_map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) err = wait_event_interruptible_timeout(client->auth_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) have_mon_and_osd_map(client) || (client->auth_err < 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ceph_timeout_jiffies(timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (client->auth_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return client->auth_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pr_info("client%llu fsid %pU\n", ceph_client_gid(client),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) &client->fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ceph_debugfs_client_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) EXPORT_SYMBOL(__ceph_open_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int ceph_open_session(struct ceph_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) unsigned long started = jiffies; /* note the start time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dout("open_session start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mutex_lock(&client->mount_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret = __ceph_open_session(client, started);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) mutex_unlock(&client->mount_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) EXPORT_SYMBOL(ceph_open_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int ceph_wait_for_latest_osdmap(struct ceph_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) u64 newest_epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (client->osdc.osdmap->epoch >= newest_epoch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ceph_osdc_maybe_request_map(&client->osdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return ceph_monc_wait_osdmap(&client->monc, newest_epoch, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) EXPORT_SYMBOL(ceph_wait_for_latest_osdmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static int __init init_ceph_lib(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ceph_debugfs_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = ceph_crypto_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) goto out_debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ret = ceph_msgr_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) goto out_crypto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ret = ceph_osdc_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto out_msgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) pr_info("loaded (mon/osd proto %d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) out_msgr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ceph_msgr_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) out_crypto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) ceph_crypto_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) out_debugfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ceph_debugfs_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static void __exit exit_ceph_lib(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dout("exit_ceph_lib\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) WARN_ON(!ceph_strings_empty());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ceph_osdc_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ceph_msgr_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ceph_crypto_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) ceph_debugfs_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) module_init(init_ceph_lib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) module_exit(exit_ceph_lib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) MODULE_DESCRIPTION("Ceph core library");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) MODULE_LICENSE("GPL");