@@ -790,8 +790,18 @@ EXPORT_SYMBOL(ceph_reset_client_addr);
*/
static bool have_mon_and_osd_map(struct ceph_client *client)
{
- return client->monc.monmap && client->monc.monmap->epoch &&
- client->osdc.osdmap && client->osdc.osdmap->epoch;
+ bool have_mon_map = false;
+ bool have_osd_map = false;
+
+ mutex_lock(&client->monc.mutex);
+ have_mon_map = client->monc.monmap && client->monc.monmap->epoch;
+ mutex_unlock(&client->monc.mutex);
+
+ down_read(&client->osdc.lock);
+ have_osd_map = client->osdc.osdmap && client->osdc.osdmap->epoch;
+ up_read(&client->osdc.lock);
+
+ return have_mon_map && have_osd_map;
}
/*
@@ -813,9 +823,23 @@ int __ceph_open_session(struct ceph_client *client, unsigned long started)
/* 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));
+
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
+
+ add_wait_queue(&client->auth_wq, &wait);
+
+ while (!(have_mon_and_osd_map(client) ||
+ (client->auth_err < 0))) {
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ break;
+ }
+ wait_woken(&wait, TASK_INTERRUPTIBLE,
+ ceph_timeout_jiffies(timeout));
+ }
+
+ remove_wait_queue(&client->auth_wq, &wait);
+
if (err < 0)
return err;
if (client->auth_err < 0)
@@ -36,8 +36,10 @@ static int monmap_show(struct seq_file *s, void *p)
int i;
struct ceph_client *client = s->private;
+ mutex_lock(&client->monc.mutex);
+
if (client->monc.monmap == NULL)
- return 0;
+ goto out_unlock;
seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
for (i = 0; i < client->monc.monmap->num_mon; i++) {
@@ -48,6 +50,10 @@ static int monmap_show(struct seq_file *s, void *p)
ENTITY_NAME(inst->name),
ceph_pr_addr(&inst->addr));
}
+
+out_unlock:
+ mutex_unlock(&client->monc.mutex);
+
return 0;
}
@@ -56,13 +62,15 @@ static int osdmap_show(struct seq_file *s, void *p)
int i;
struct ceph_client *client = s->private;
struct ceph_osd_client *osdc = &client->osdc;
- struct ceph_osdmap *map = osdc->osdmap;
+ struct ceph_osdmap *map = NULL;
struct rb_node *n;
+ down_read(&osdc->lock);
+
+ map = osdc->osdmap;
if (map == NULL)
- return 0;
+ goto out_unlock;
- down_read(&osdc->lock);
seq_printf(s, "epoch %u barrier %u flags 0x%x\n", map->epoch,
osdc->epoch_barrier, map->flags);
@@ -131,6 +139,7 @@ static int osdmap_show(struct seq_file *s, void *p)
seq_printf(s, "]\n");
}
+out_unlock:
up_read(&osdc->lock);
return 0;
}
@@ -1232,6 +1232,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
ceph_auth_destroy(monc->auth);
out_monmap:
kfree(monc->monmap);
+ monc->monmap = NULL;
out:
return err;
}
@@ -1239,6 +1240,8 @@ EXPORT_SYMBOL(ceph_monc_init);
void ceph_monc_stop(struct ceph_mon_client *monc)
{
+ struct ceph_monmap *old_monmap;
+
dout("stop\n");
mutex_lock(&monc->mutex);
@@ -1266,7 +1269,11 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
ceph_msg_put(monc->m_subscribe);
ceph_msg_put(monc->m_subscribe_ack);
- kfree(monc->monmap);
+ mutex_lock(&monc->mutex);
+ old_monmap = monc->monmap;
+ monc->monmap = NULL;
+ mutex_unlock(&monc->mutex);
+ kfree(old_monmap);
}
EXPORT_SYMBOL(ceph_monc_stop);
@@ -5255,6 +5255,7 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
mempool_destroy(osdc->req_mempool);
out_map:
ceph_osdmap_destroy(osdc->osdmap);
+ osdc->osdmap = NULL;
out:
return err;
}
@@ -5283,10 +5284,13 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc)
WARN_ON(atomic_read(&osdc->num_requests));
WARN_ON(atomic_read(&osdc->num_homeless));
+ down_write(&osdc->lock);
ceph_osdmap_destroy(osdc->osdmap);
+ osdc->osdmap = NULL;
mempool_destroy(osdc->req_mempool);
ceph_msgpool_destroy(&osdc->msgpool_op);
ceph_msgpool_destroy(&osdc->msgpool_op_reply);
+ up_write(&osdc->lock);
}
int osd_req_op_copy_from_init(struct ceph_osd_request *req,