From 3485129b7798ef43d7b5831640784da82d5ccb66 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 14 Jan 2014 15:59:04 +0800 Subject: [PATCH] export namespace-global message sequence number (ABI break) --- bus.c | 3 +-- bus.h | 10 ++++------ connection.c | 13 ++++++++++--- endpoint.c | 2 +- handle.c | 2 +- kdbus.h | 2 ++ message.c | 5 +++++ message.h | 3 +++ metadata.c | 11 +++++++++-- metadata.h | 3 +++ names.c | 3 +-- names.h | 4 ++-- namespace.c | 5 +++-- namespace.h | 8 ++++++-- test/kdbus-util.c | 3 ++- 15 files changed, 53 insertions(+), 24 deletions(-) diff --git a/bus.c b/bus.c index 872ddbd..ef0c9a6 100644 --- a/bus.c +++ b/bus.c @@ -205,7 +205,6 @@ int kdbus_bus_new(struct kdbus_ns *ns, b->uid_owner = uid; b->bus_flags = make->flags; b->bloom_size = bloom_size; - b->conn_id_next = 1; /* connection 0 == kernel */ mutex_init(&b->lock); hash_init(b->conn_hash); INIT_LIST_HEAD(&b->ep_list); @@ -239,7 +238,7 @@ int kdbus_bus_new(struct kdbus_ns *ns, /* link into namespace */ mutex_lock(&ns->lock); - b->id = ns->bus_id_next++; + b->id = ++ns->bus_seq_last; list_add_tail(&b->ns_entry, &ns->bus_list); b->ns = kdbus_ns_ref(ns); mutex_unlock(&ns->lock); diff --git a/bus.h b/bus.h index 5af1712..87395c7 100644 --- a/bus.h +++ b/bus.h @@ -27,9 +27,8 @@ * @name: The bus name * @id: ID of this bus in the namespace * @lock: Bus data lock - * @ep_id_next: Next endpoint id sequence number - * @conn_id_next: Next connection id sequence number - * @msg_id_next: Next message id sequence number + * @ep_seq_last: Last used endpoint id sequence number + * @conn_seq_last: Last used connection id sequence number * @conn_idr: Map of connection device minor nummbers * @conn_hash: Map of connection IDs * @ep_list: Endpoints on this bus @@ -54,9 +53,8 @@ struct kdbus_bus { const char *name; u64 id; struct mutex lock; - u64 ep_id_next; - u64 conn_id_next; - u64 msg_id_next; + u64 ep_seq_last; + u64 conn_seq_last; struct idr conn_idr; DECLARE_HASHTABLE(conn_hash, 6); struct list_head ep_list; diff --git a/connection.c b/connection.c index c426fb3..c0d280b 100644 --- a/connection.c +++ b/connection.c @@ -669,8 +669,13 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep, struct kdbus_conn *c; int ret; + /* assign namespace-global message sequence number */ + BUG_ON(kmsg->seq > 0); + kmsg->seq = atomic_inc_return(&ep->bus->ns->msg_seq_last); + /* non-kernel senders append credentials/metadata */ if (conn_src) { + ret = kdbus_meta_new(&kmsg->meta); if (ret < 0) return ret; @@ -704,6 +709,7 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep, */ if (conn_src) kdbus_meta_append(kmsg->meta, conn_src, + kmsg->seq, conn_dst->attach_flags); kdbus_conn_queue_insert(conn_dst, kmsg); @@ -787,7 +793,7 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep, } if (conn_src) { - ret = kdbus_meta_append(kmsg->meta, conn_src, + ret = kdbus_meta_append(kmsg->meta, conn_src, kmsg->seq, conn_dst->attach_flags); if (ret < 0) goto exit_unref; @@ -1395,7 +1401,8 @@ int kdbus_cmd_conn_info(struct kdbus_conn *conn, if (ret < 0) goto exit; - ret = kdbus_meta_append(meta, owner_conn, KDBUS_ATTACH_NAMES); + ret = kdbus_meta_append(meta, owner_conn, 0, + KDBUS_ATTACH_NAMES); if (ret < 0) goto exit; @@ -1551,7 +1558,7 @@ int kdbus_conn_new(struct kdbus_ep *ep, /* link into bus; get new id for this connection */ mutex_lock(&bus->lock); - conn->id = bus->conn_id_next++; + conn->id = ++bus->conn_seq_last; hash_add(bus->conn_hash, &conn->hentry, conn->id); mutex_unlock(&bus->lock); diff --git a/endpoint.c b/endpoint.c index 75ccf3f..6bb6180 100644 --- a/endpoint.c +++ b/endpoint.c @@ -218,7 +218,7 @@ int kdbus_ep_new(struct kdbus_bus *bus, struct kdbus_ns *ns, const char *name, /* link into bus */ mutex_lock(&bus->lock); - e->id = bus->ep_id_next++; + e->id = ++bus->ep_seq_last; e->bus = kdbus_bus_ref(bus); list_add_tail(&e->bus_entry, &bus->ep_list); mutex_unlock(&bus->lock); diff --git a/handle.c b/handle.c index 3a03a0e..1bfec19 100644 --- a/handle.c +++ b/handle.c @@ -131,7 +131,7 @@ static int kdbus_handle_open(struct inode *inode, struct file *file) if (ret < 0) goto exit_unlock; - ret = kdbus_meta_append(handle->meta, NULL, + ret = kdbus_meta_append(handle->meta, NULL, 0, KDBUS_ATTACH_CREDS | KDBUS_ATTACH_COMM | KDBUS_ATTACH_EXE | diff --git a/kdbus.h b/kdbus.h index eb4525e..601d018 100644 --- a/kdbus.h +++ b/kdbus.h @@ -102,6 +102,7 @@ struct kdbus_audit { /** * struct kdbus_timestamp + * @seqnum: Global per-namespace message sequence number * @monotonic_ns: Monotonic timestamp, in nanoseconds * @realtime_ns: Realtime timestamp, in nanoseconds * @@ -109,6 +110,7 @@ struct kdbus_audit { * KDBUS_ITEM_TIMESTAMP */ struct kdbus_timestamp { + __u64 seqnum; __u64 monotonic_ns; __u64 realtime_ns; }; diff --git a/message.c b/message.c index 0340b55..e9b8f52 100644 --- a/message.c +++ b/message.c @@ -24,6 +24,7 @@ #include #include "bus.h" +#include "namespace.h" #include "connection.h" #include "endpoint.h" #include "match.h" @@ -287,6 +288,10 @@ int kdbus_kmsg_new_from_user(struct kdbus_conn *conn, goto exit_free; /* patch-in the source of this message */ + if (m->msg.src_id > 0 && m->msg.src_id != conn->id) { + ret = -EINVAL; + goto exit_free; + } m->msg.src_id = conn->id; *kmsg = m; diff --git a/message.h b/message.h index 55fa6cf..44ed106 100644 --- a/message.h +++ b/message.h @@ -14,10 +14,12 @@ #define __KDBUS_MESSAGE_H #include "util.h" +#include "namespace.h" #include "metadata.h" /** * struct kdbus_kmsg - internal message handling data + * @seq: Namespace-global message sequence number * @notify_type: Short-cut for faster lookup * @notify_old_id: Short-cut for faster lookup * @notify_new_id: Short-cut for faster lookup @@ -36,6 +38,7 @@ * @msg: Message from or to userspace */ struct kdbus_kmsg { + u64 seq; u64 notify_type; u64 notify_old_id; u64 notify_new_id; diff --git a/metadata.c b/metadata.c index 364d9cd..3fe639e 100644 --- a/metadata.c +++ b/metadata.c @@ -25,6 +25,7 @@ #include #include "connection.h" +#include "message.h" #include "metadata.h" #include "names.h" @@ -148,7 +149,8 @@ static int kdbus_meta_append_str(struct kdbus_meta *meta, u64 type, return kdbus_meta_append_data(meta, type, str, strlen(str) + 1); } -static int kdbus_meta_append_timestamp(struct kdbus_meta *meta) +static int kdbus_meta_append_timestamp(struct kdbus_meta *meta, + u64 seq) { struct kdbus_item *item; u64 size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_timestamp)); @@ -161,6 +163,9 @@ static int kdbus_meta_append_timestamp(struct kdbus_meta *meta) item->type = KDBUS_ITEM_TIMESTAMP; item->size = size; + if (seq > 0) + item->timestamp.seqnum = seq; + ktime_get_ts(&ts); item->timestamp.monotonic_ns = timespec_to_ns(&ts); @@ -381,6 +386,7 @@ static int kdbus_meta_append_seclabel(struct kdbus_meta *meta) * kdbus_meta_append() - collect metadata from current process * @meta: Metadata object * @conn: Current connection to read names from + * @seq: Message sequence number * @which: KDBUS_ATTACH_* flags which typ of data to attach * * Collect the data specified in flags and allocate or extend @@ -390,6 +396,7 @@ static int kdbus_meta_append_seclabel(struct kdbus_meta *meta) */ int kdbus_meta_append(struct kdbus_meta *meta, struct kdbus_conn *conn, + u64 seq, u64 which) { int ret = 0; @@ -400,7 +407,7 @@ int kdbus_meta_append(struct kdbus_meta *meta, if (which & KDBUS_ATTACH_TIMESTAMP && !(meta->attached & KDBUS_ATTACH_TIMESTAMP)) { - ret = kdbus_meta_append_timestamp(meta); + ret = kdbus_meta_append_timestamp(meta, seq); if (ret < 0) goto exit; } diff --git a/metadata.h b/metadata.h index f3fdc46..1ee510e 100644 --- a/metadata.h +++ b/metadata.h @@ -13,6 +13,8 @@ #ifndef __KDBUS_METADATA_H #define __KDBUS_METADATA_H +#include "message.h" + /** * struct kdbus_meta - metadata buffer * @attached: Flags for already attached data @@ -39,6 +41,7 @@ int kdbus_meta_append_data(struct kdbus_meta *meta, u64 type, const void *buf, size_t len); int kdbus_meta_append(struct kdbus_meta *meta, struct kdbus_conn *conn, + u64 seq, u64 which); void kdbus_meta_free(struct kdbus_meta *meta); #endif diff --git a/names.c b/names.c index 39327e2..7feabd5 100644 --- a/names.c +++ b/names.c @@ -88,7 +88,6 @@ int kdbus_name_registry_new(struct kdbus_name_registry **reg) hash_init(r->entries_hash); mutex_init(&r->entries_lock); - r->name_id_next = 1; *reg = r; @@ -478,7 +477,7 @@ int kdbus_name_acquire(struct kdbus_name_registry *reg, e->flags = *flags; INIT_LIST_HEAD(&e->queue_list); - e->name_id = reg->name_id_next++; + e->name_id = ++reg->name_seq_last; hash_add(reg->entries_hash, &e->hentry, hash); kdbus_name_entry_set_owner(e, conn); diff --git a/names.h b/names.h index 0dbb63d..447122a 100644 --- a/names.h +++ b/names.h @@ -19,12 +19,12 @@ * struct kdbus_name_registry - names registered for a bus * @entries_hash: Map of entries * @entries_lock: Registry data lock - * @name_id_next: Next sequence number to assign to a name entry + * @name_seq_last: Last used sequence number to assign to a name entry */ struct kdbus_name_registry { DECLARE_HASHTABLE(entries_hash, 6); struct mutex entries_lock; - u64 name_id_next; + u64 name_seq_last; }; /** diff --git a/namespace.c b/namespace.c index 684fe43..c19816e 100644 --- a/namespace.c +++ b/namespace.c @@ -30,7 +30,7 @@ static DEFINE_IDR(kdbus_ns_major_idr); /* next namespace id sequence number */ -static u64 kdbus_ns_id_next; +static u64 kdbus_ns_seq_last; /* kdbus initial namespace */ struct kdbus_ns *kdbus_ns_init; @@ -216,6 +216,7 @@ int kdbus_ns_new(struct kdbus_ns *parent, const char *name, umode_t mode, n->mode = mode; idr_init(&n->idr); mutex_init(&n->lock); + atomic_set(&n->msg_seq_last, 0); mutex_lock(&kdbus_subsys_lock); @@ -270,7 +271,7 @@ int kdbus_ns_new(struct kdbus_ns *parent, const char *name, umode_t mode, } /* get id for this namespace */ - n->id = kdbus_ns_id_next++; + n->id = ++kdbus_ns_seq_last; /* register control device for this namespace */ n->dev = kzalloc(sizeof(struct device), GFP_KERNEL); diff --git a/namespace.h b/namespace.h index 93ff21b..e0730d6 100644 --- a/namespace.h +++ b/namespace.h @@ -13,6 +13,8 @@ #ifndef __KDBUS_NS_H #define __KDBUS_NS_H +#include + /** * struct kdbus_namespace - namespace for buses * @kref: Reference counter @@ -27,7 +29,8 @@ * @idr: Map of endpoint minors to buses * @dev: Control device node, minor == 0 * @lock: Namespace data lock - * @bus_id_next: Next bus id sequence number + * @bus_seq_last: Last used bus id sequence number + * @msg_seq_last: Last used message id sequence number * @ns_entry: Entry in parent namespace * @bus_list: Buses in this namespace * @@ -54,7 +57,8 @@ struct kdbus_ns { struct idr idr; struct device *dev; struct mutex lock; - u64 bus_id_next; + u64 bus_seq_last; + atomic_t msg_seq_last; struct list_head ns_entry; struct list_head bus_list; }; diff --git a/test/kdbus-util.c b/test/kdbus-util.c index 359a038..a8e2b80 100644 --- a/test/kdbus-util.c +++ b/test/kdbus-util.c @@ -350,8 +350,9 @@ void msg_dump(const struct conn *conn, const struct kdbus_msg *msg) } case KDBUS_ITEM_TIMESTAMP: - printf(" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n", + printf(" +%s (%llu bytes) seq=%llu realtime=%lluns monotonic=%lluns\n", enum_MSG(item->type), item->size, + (unsigned long long)item->timestamp.seqnum, (unsigned long long)item->timestamp.realtime_ns, (unsigned long long)item->timestamp.monotonic_ns); break; -- 2.34.1