/* * Module compatibility interface. For now it doesn't do anything, * but its existence signals a certain level of functionality. * * The data buffer is used to pass information both to and from * libceph. The return value indicates whether libceph determines * it is compatible with the caller (from another kernel module), * given the provided data. * * The data pointer can be null.
*/ bool libceph_compatible(void *data)
{ returntrue;
}
EXPORT_SYMBOL(libceph_compatible);
constchar *ceph_msg_type_name(int type)
{ switch (type) { case CEPH_MSG_SHUTDOWN: return"shutdown"; case CEPH_MSG_PING: return"ping"; case CEPH_MSG_AUTH: return"auth"; case CEPH_MSG_AUTH_REPLY: return"auth_reply"; case CEPH_MSG_MON_MAP: return"mon_map"; case CEPH_MSG_MON_GET_MAP: return"mon_get_map"; case CEPH_MSG_MON_SUBSCRIBE: return"mon_subscribe"; case CEPH_MSG_MON_SUBSCRIBE_ACK: return"mon_subscribe_ack"; case CEPH_MSG_STATFS: return"statfs"; case CEPH_MSG_STATFS_REPLY: return"statfs_reply"; case CEPH_MSG_MON_GET_VERSION: return"mon_get_version"; case CEPH_MSG_MON_GET_VERSION_REPLY: return"mon_get_version_reply"; case CEPH_MSG_MDS_MAP: return"mds_map"; case CEPH_MSG_FS_MAP_USER: return"fs_map_user"; case CEPH_MSG_CLIENT_SESSION: return"client_session"; case CEPH_MSG_CLIENT_RECONNECT: return"client_reconnect"; case CEPH_MSG_CLIENT_REQUEST: return"client_request"; case CEPH_MSG_CLIENT_REQUEST_FORWARD: return"client_request_forward"; case CEPH_MSG_CLIENT_REPLY: return"client_reply"; case CEPH_MSG_CLIENT_CAPS: return"client_caps"; case CEPH_MSG_CLIENT_CAPRELEASE: return"client_cap_release"; case CEPH_MSG_CLIENT_QUOTA: return"client_quota"; case CEPH_MSG_CLIENT_SNAP: return"client_snap"; case CEPH_MSG_CLIENT_LEASE: return"client_lease"; case CEPH_MSG_POOLOP_REPLY: return"poolop_reply"; case CEPH_MSG_POOLOP: return"poolop"; case CEPH_MSG_MON_COMMAND: return"mon_command"; case CEPH_MSG_MON_COMMAND_ACK: return"mon_command_ack"; case CEPH_MSG_OSD_MAP: return"osd_map"; case CEPH_MSG_OSD_OP: return"osd_op"; case CEPH_MSG_OSD_OPREPLY: return"osd_opreply"; case CEPH_MSG_WATCH_NOTIFY: return"watch_notify"; case CEPH_MSG_OSD_BACKOFF: return"osd_backoff"; default: return"unknown";
}
}
EXPORT_SYMBOL(ceph_msg_type_name);
/* * Initially learn our fsid, or verify an fsid matches.
*/ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
{ if (client->have_fsid) { if (ceph_fsid_compare(&client->fsid, fsid)) {
pr_err("bad fsid, had %pU got %pU",
&client->fsid, fsid); return -1;
}
} else {
memcpy(&client->fsid, fsid, sizeof(*fsid));
} return 0;
}
EXPORT_SYMBOL(ceph_check_fsid);
staticint strcmp_null(constchar *s1, constchar *s2)
{ if (!s1 && !s2) return 0; if (s1 && !s2) return -1; if (!s1 && s2) return 1; return strcmp(s1, s2);
}
int ceph_compare_options(struct ceph_options *new_opt, struct ceph_client *client)
{ struct ceph_options *opt1 = new_opt; struct ceph_options *opt2 = client->options; int ofs = offsetof(struct ceph_options, mon_addr); int i; int ret;
/* * Don't bother comparing options if network namespaces don't * match.
*/ if (!net_eq(current->nsproxy->net_ns, read_pnet(&client->msgr.net))) return -1;
ret = memcmp(opt1, opt2, ofs); if (ret) return ret;
ret = strcmp_null(opt1->name, opt2->name); if (ret) return ret;
if (opt1->key && !opt2->key) return -1; if (!opt1->key && opt2->key) return 1; if (opt1->key && opt2->key) { if (opt1->key->type != opt2->key->type) return -1; if (opt1->key->created.tv_sec != opt2->key->created.tv_sec) return -1; if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec) return -1; if (opt1->key->len != opt2->key->len) return -1; if (opt1->key->key && !opt2->key->key) return -1; if (!opt1->key->key && opt2->key->key) return 1; if (opt1->key->key && opt2->key->key) {
ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len); if (ret) return ret;
}
}
ret = ceph_compare_crush_locs(&opt1->crush_locs, &opt2->crush_locs); if (ret) return ret;
/* any matching mon ip implies a match */ for (i = 0; i < opt1->num_mon; i++) { if (ceph_monmap_contains(client->monc.monmap,
&opt1->mon_addr[i])) return 0;
} return -1;
}
EXPORT_SYMBOL(ceph_compare_options);
int ceph_parse_fsid(constchar *str, struct ceph_fsid *fsid)
{ int i = 0; char tmp[3]; int err = -EINVAL; int d;
dout("%s '%s'\n", __func__, str);
tmp[2] = 0; while (*str && i < 16) { if (ispunct(*str)) {
str++; continue;
} if (!isxdigit(str[0]) || !isxdigit(str[1])) break;
tmp[0] = str[0];
tmp[1] = str[1]; if (sscanf(tmp, "%x", &d) < 1) break;
fsid->fsid[i] = d & 0xff;
i++;
str += 2;
}
if (i == 16)
err = 0;
dout("%s ret %d got fsid %pU\n", __func__, err, fsid); return err;
}
EXPORT_SYMBOL(ceph_parse_fsid);
/* get secret from key store */ staticint get_secret(struct ceph_crypto_key *dst, constchar *name, struct p_log *log)
{ struct key *ukey; int key_err; int err = 0; struct ceph_crypto_key *ckey;
ukey = request_key(&key_type_ceph, name, NULL); if (IS_ERR(ukey)) { /* request_key errors don't map nicely to mount(2)
errors; don't even try, but still printk */
key_err = PTR_ERR(ukey); switch (key_err) { case -ENOKEY:
error_plog(log, "Failed due to key not found: %s",
name); break; case -EKEYEXPIRED:
error_plog(log, "Failed due to expired key: %s",
name); break; case -EKEYREVOKED:
error_plog(log, "Failed due to revoked key: %s",
name); break; default:
error_plog(log, "Failed due to key error %d: %s",
key_err, name);
}
err = -EPERM; goto out;
}
ckey = ukey->payload.data[0];
err = ceph_crypto_key_clone(dst, ckey); if (err) goto out_key; /* pass through, err is 0 */
/* * true if we have the mon map (and have thus joined the cluster)
*/ staticbool have_mon_and_osd_map(struct ceph_client *client)
{ return client->monc.monmap && client->monc.monmap->epoch &&
client->osdc.osdmap && client->osdc.osdmap->epoch;
}
/* * mount: join the ceph cluster, and open root directory.
*/ int __ceph_open_session(struct ceph_client *client, unsignedlong started)
{ unsignedlong timeout = client->options->mount_timeout; long err;
/* open session, and wait for mon and osd maps */
err = ceph_monc_open_session(&client->monc); if (err < 0) return err;
while (!have_mon_and_osd_map(client)) { if (timeout && time_after_eq(jiffies, started + timeout)) return -ETIMEDOUT;
/* wait */
dout("mount waiting for mon_map\n");
err = wait_event_interruptible_timeout(client->auth_wq,
have_mon_and_osd_map(client) || (client->auth_err < 0),
ceph_timeout_jiffies(timeout)); if (err < 0) return err; if (client->auth_err < 0) return client->auth_err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.