always require explicit disconnect(), pin connection until disconnect()
authorKay Sievers <kay@vrfy.org>
Thu, 15 May 2014 21:40:14 +0000 (23:40 +0200)
committerKay Sievers <kay@vrfy.org>
Thu, 15 May 2014 21:40:14 +0000 (23:40 +0200)
bus.c
connection.c
domain.c
endpoint.c

diff --git a/bus.c b/bus.c
index 7af1a4eebabbfb8293444d6980d99f6ae654de1a..d09e3c66283598bfc466a90fea3abdae8a1ec89f 100644 (file)
--- a/bus.c
+++ b/bus.c
@@ -69,11 +69,11 @@ static void __kdbus_bus_free(struct kref *kref)
 {
        struct kdbus_bus *bus = container_of(kref, struct kdbus_bus, kref);
 
+       BUG_ON(!bus->disconnected);
        BUG_ON(!list_empty(&bus->ep_list));
        BUG_ON(!list_empty(&bus->monitors_list));
        BUG_ON(!hash_empty(bus->conn_hash));
 
-       kdbus_bus_disconnect(bus);
        kdbus_notify_free(bus);
        atomic_dec(&bus->user->buses);
        kdbus_domain_user_unref(bus->user);
index 40cf13331ac41f7d1e5253cad079e55328cf16d1..32bb2e34d4f3c60179aef902683a9372734a152b 100644 (file)
@@ -715,11 +715,10 @@ static void kdbus_conn_work(struct work_struct *work)
        struct timespec ts;
        u64 now;
 
+       conn = container_of(work, struct kdbus_conn, work.work);
        ktime_get_ts(&ts);
        now = timespec_to_ns(&ts);
 
-       conn = container_of(work, struct kdbus_conn, work.work);
-
        mutex_lock(&conn->lock);
        if (!kdbus_conn_active(conn)) {
                mutex_unlock(&conn->lock);
@@ -1513,6 +1512,10 @@ int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty)
                               conn->flags);
 
        kdbus_notify_flush(conn->bus);
+
+       /* drop additional reference whe took at HELLO time */
+       kdbus_conn_unref(conn);
+
        return 0;
 }
 
@@ -1531,12 +1534,12 @@ static void __kdbus_conn_free(struct kref *kref)
 {
        struct kdbus_conn *conn = container_of(kref, struct kdbus_conn, kref);
 
+       BUG_ON(kdbus_conn_active(conn));
        BUG_ON(!list_empty(&conn->msg_list));
        BUG_ON(!list_empty(&conn->names_list));
        BUG_ON(!list_empty(&conn->names_queue_list));
        BUG_ON(!list_empty(&conn->reply_list));
 
-       kdbus_conn_disconnect(conn, false);
        atomic_dec(&conn->user->connections);
        kdbus_domain_user_unref(conn->user);
 
@@ -1831,15 +1834,13 @@ int kdbus_conn_new(struct kdbus_ep *ep,
        const char *seclabel = NULL;
        const char *name = NULL;
        struct kdbus_conn *conn;
-       struct kdbus_bus *bus;
+       struct kdbus_bus *bus = ep->bus;
        size_t seclabel_len = 0;
        bool is_policy_holder;
        bool is_activator;
        bool is_monitor;
        int ret;
 
-       bus = ep->bus;
-
        BUG_ON(*c);
 
        is_monitor = hello->conn_flags & KDBUS_HELLO_MONITOR;
@@ -2074,6 +2075,9 @@ int kdbus_conn_new(struct kdbus_ep *ep,
        list_add_tail(&conn->ep_entry, &ep->conn_list);
        hash_add(bus->conn_hash, &conn->hentry, conn->id);
 
+       /* take additional reference until we disconnect */
+       kdbus_conn_ref(conn);
+
        mutex_unlock(&ep->lock);
        mutex_unlock(&bus->lock);
 
index ee77f360dabbd01e30c652cdb94facc47472254f..4748a17562e389b96d22f33cd47502371005acc3 100644 (file)
--- a/domain.c
+++ b/domain.c
@@ -160,11 +160,11 @@ static void __kdbus_domain_free(struct kref *kref)
        struct kdbus_domain *domain =
                container_of(kref, struct kdbus_domain, kref);
 
+       BUG_ON(!domain->disconnected);
        BUG_ON(!list_empty(&domain->domain_list));
        BUG_ON(!list_empty(&domain->bus_list));
        BUG_ON(!hash_empty(domain->user_hash));
 
-       kdbus_domain_disconnect(domain);
        kdbus_domain_unref(domain->parent);
        kfree(domain->name);
        kfree(domain->devpath);
index 7267a566f1117f9c4179b1956410f3424c85e5a2..3cedfd74912fa03e5e1682ddbd90160ef9905e75 100644 (file)
@@ -115,9 +115,9 @@ static void __kdbus_ep_free(struct kref *kref)
 {
        struct kdbus_ep *ep = container_of(kref, struct kdbus_ep, kref);
 
+       BUG_ON(!ep->disconnected);
        BUG_ON(!list_empty(&ep->conn_list));
 
-       kdbus_ep_disconnect(ep);
        kdbus_policy_db_free(ep->policy_db);
        kdbus_bus_unref(ep->bus);
        kdbus_domain_user_unref(ep->user);