#include "super.h"
#include "mds_client.h"
+#include "mon_client.h"
+#include "auth.h"
#ifdef CONFIG_DEBUG_FS
char name[80];
snprintf(name, sizeof(name), FSID_FORMAT ".client%lld",
- PR_FSID(&client->monc.monmap->fsid), client->whoami);
+ PR_FSID(&client->fsid), client->monc.auth->global_id);
client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
if (!client->debugfs_dir)
ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad);
ceph_decode_copy(&p, &fsid, sizeof(fsid));
- if (mdsc->client->monc.have_fsid) {
- if (ceph_fsid_compare(&fsid,
- &mdsc->client->monc.monmap->fsid)) {
- pr_err("got mdsmap with wrong fsid\n");
- return;
- }
- } else {
- ceph_fsid_set(&mdsc->client->monc.monmap->fsid, &fsid);
- mdsc->client->monc.have_fsid = true;
- }
+ if (ceph_check_fsid(mdsc->client, &fsid) < 0)
+ return;
epoch = ceph_decode_32(&p);
maplen = ceph_decode_32(&p);
dout("handle_map epoch %u len %d\n", epoch, (int)maplen);
return 0;
}
-#if 0
-
-/*
- * The monitor responds with mount ack indicate mount success. The
- * included client ticket allows the client to talk to MDSs and OSDs.
- */
-static void handle_mount_ack(struct ceph_mon_client *monc, struct ceph_msg *msg)
-{
- struct ceph_client *client = monc->client;
- struct ceph_monmap *monmap = NULL, *old = monc->monmap;
- void *p, *end;
- s32 result;
- u32 len;
- s64 cnum;
- int err = -EINVAL;
-
- if (client->whoami >= 0) {
- dout("handle_mount_ack - already mounted\n");
- return;
- }
-
- mutex_lock(&monc->mutex);
-
- dout("handle_mount_ack\n");
- p = msg->front.iov_base;
- end = p + msg->front.iov_len;
-
- ceph_decode_64_safe(&p, end, cnum, bad);
- ceph_decode_32_safe(&p, end, result, bad);
- ceph_decode_32_safe(&p, end, len, bad);
- if (result) {
- pr_err("mount denied: %.*s (%d)\n", len, (char *)p,
- result);
- err = result;
- goto out;
- }
- p += len;
-
- ceph_decode_32_safe(&p, end, len, bad);
- ceph_decode_need(&p, end, len, bad);
- monmap = ceph_monmap_decode(p, p + len);
- if (IS_ERR(monmap)) {
- pr_err("problem decoding monmap, %d\n",
- (int)PTR_ERR(monmap));
- err = -EINVAL;
- goto out;
- }
- p += len;
-
- client->monc.monmap = monmap;
- kfree(old);
-
- client->signed_ticket = NULL;
- client->signed_ticket_len = 0;
-
- monc->want_mount = false;
-
- client->whoami = cnum;
- client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
- client->msgr->inst.name.num = cpu_to_le64(cnum);
- pr_info("client%lld fsid " FSID_FORMAT "\n",
- client->whoami, PR_FSID(&client->monc.monmap->fsid));
-
- ceph_debugfs_client_init(client);
- __send_subscribe(monc);
-
- err = 0;
- goto out;
-
-bad:
- pr_err("error decoding mount_ack message\n");
-out:
- client->mount_err = err;
- mutex_unlock(&monc->mutex);
- wake_up(&client->mount_wq);
-}
-#endif
-
/*
* The monitor responds with mount ack indicate mount success. The
* included client ticket allows the client to talk to MDSs and OSDs.
*/
-static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_msg *msg)
+static void ceph_monc_handle_map(struct ceph_mon_client *monc,
+ struct ceph_msg *msg)
{
struct ceph_client *client = monc->client;
struct ceph_monmap *monmap = NULL, *old = monc->monmap;
(int)PTR_ERR(monmap));
return;
}
- if (monc->have_fsid &&
- ceph_fsid_compare(&monmap->fsid, &monc->monmap->fsid)) {
- print_hex_dump(KERN_ERR, "monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1,
- (void *)&monmap->fsid, 16, 0);
- print_hex_dump(KERN_ERR, "monc->monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1,
- (void *)&monc->monmap->fsid, 16, 0);
-
- pr_err("fsid mismatch, got a previous map with different fsid");
+
+ if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) {
kfree(monmap);
return;
}
client->monc.monmap = monmap;
- client->monc.have_fsid = true;
kfree(old);
mutex_unlock(&monc->mutex);
wake_up(&client->mount_wq);
}
-
-/*
- * init client info after authentication
- */
-static void __init_authenticated_client(struct ceph_mon_client *monc)
-{
- struct ceph_client *client = monc->client;
-
- client->signed_ticket = NULL;
- client->signed_ticket_len = 0;
- client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
- client->msgr->inst.name.num = monc->auth->global_id;
-
- ceph_debugfs_client_init(client);
-}
-
/*
* statfs
*/
ceph_con_send(monc->con, monc->m_auth);
} else if (monc->auth->ops->is_authenticated(monc->auth)) {
dout("authenticated, starting session\n");
- __init_authenticated_client(monc);
+
+ monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
+ monc->client->msgr->inst.name.num = monc->auth->global_id;
+
__send_subscribe(monc);
__resend_statfs(monc);
}
/* verify fsid */
ceph_decode_need(&p, end, sizeof(fsid), bad);
ceph_decode_copy(&p, &fsid, sizeof(fsid));
- if (osdc->client->monc.have_fsid) {
- if (ceph_fsid_compare(&fsid,
- &osdc->client->monc.monmap->fsid)) {
- pr_err("got osdmap with wrong fsid, ignoring\n");
- return;
- }
- } else {
- ceph_fsid_set(&osdc->client->monc.monmap->fsid, &fsid);
- osdc->client->monc.have_fsid = true;
- }
+ if (ceph_check_fsid(osdc->client, &fsid) < 0)
+ return;
down_write(&osdc->map_sem);
#include "decode.h"
#include "super.h"
#include "mon_client.h"
+#include "auth.h"
/*
* Ceph superblock operations
client->sb = NULL;
client->mount_state = CEPH_MOUNT_MOUNTING;
- client->whoami = -1;
client->mount_args = args;
client->msgr = NULL;
client->mount_err = 0;
- client->signed_ticket = NULL;
- client->signed_ticket_len = 0;
err = bdi_init(&client->backing_dev_info);
if (err < 0)
ceph_monc_stop(&client->monc);
ceph_osdc_stop(&client->osdc);
- kfree(client->signed_ticket);
-
ceph_debugfs_client_cleanup(client);
destroy_workqueue(client->wb_wq);
destroy_workqueue(client->pg_inv_wq);
dout("destroy_client %p done\n", client);
}
+/*
+ * 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)) {
+ print_hex_dump(KERN_ERR, "this fsid: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ (void *)fsid, 16, 0);
+ print_hex_dump(KERN_ERR, " old fsid: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ (void *)&client->fsid, 16, 0);
+ pr_err("fsid mismatch\n");
+ return -1;
+ }
+ } else {
+ pr_info("client%lld fsid " FSID_FORMAT "\n",
+ client->monc.auth->global_id, PR_FSID(fsid));
+ memcpy(&client->fsid, fsid, sizeof(*fsid));
+ ceph_debugfs_client_init(client);
+ client->have_fsid = true;
+ }
+ return 0;
+}
+
/*
* true if we have the mon map (and have thus joined the cluster)
*/
* mounting the same ceph filesystem/cluster.
*/
struct ceph_client {
- __s64 whoami; /* my client number */
-#ifdef CONFIG_DEBUG_FS
- struct dentry *debugfs_monmap;
- struct dentry *debugfs_mdsmap, *debugfs_osdmap;
- struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
-#endif
+ struct ceph_fsid fsid;
+ bool have_fsid;
struct mutex mount_mutex; /* serialize mount attempts */
struct ceph_mount_args *mount_args;
- struct ceph_fsid fsid;
struct super_block *sb;
wait_queue_head_t mount_wq;
int mount_err;
- void *signed_ticket; /* our keys to the kingdom */
- int signed_ticket_len;
struct ceph_messenger *msgr; /* messenger instance */
struct ceph_mon_client monc;
struct workqueue_struct *trunc_wq;
struct backing_dev_info backing_dev_info;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_monmap;
+ struct dentry *debugfs_mdsmap, *debugfs_osdmap;
+ struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
+#endif
};
static inline struct ceph_client *ceph_client(struct super_block *sb)
extern struct kmem_cache *ceph_file_cachep;
extern const char *ceph_msg_type_name(int type);
+extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
#define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
"%02x%02x%02x%02x%02x%02x"