@@ -598,6 +598,9 @@ struct l2cap_chan {
void *data;
const struct l2cap_ops *ops;
struct mutex lock;
+
+ /* must be last */
+ u8 priv[0] __aligned(sizeof(void *));
};
struct l2cap_ops {
@@ -925,6 +928,7 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(void);
+struct l2cap_chan *l2cap_chan_create_priv(size_t priv_size);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type);
@@ -433,11 +433,11 @@ static void l2cap_chan_timeout(struct work_struct *work)
l2cap_chan_put(chan);
}
-struct l2cap_chan *l2cap_chan_create(void)
+static struct l2cap_chan *__l2cap_chan_create(size_t priv_size)
{
struct l2cap_chan *chan;
- chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
+ chan = kzalloc(sizeof(*chan) + priv_size, GFP_ATOMIC);
if (!chan)
return NULL;
@@ -463,8 +463,25 @@ struct l2cap_chan *l2cap_chan_create(void)
return chan;
}
+
+struct l2cap_chan *l2cap_chan_create(void)
+{
+ return __l2cap_chan_create(0);
+}
EXPORT_SYMBOL_GPL(l2cap_chan_create);
+struct l2cap_chan *l2cap_chan_create_priv(size_t priv_size)
+{
+ struct l2cap_chan *chan = __l2cap_chan_create(priv_size);
+
+ /* let's point data pointer to private space */
+ if (chan)
+ chan->data = chan->priv;
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(l2cap_chan_create_priv);
+
static void l2cap_chan_destroy(struct kref *kref)
{
struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
This patch adds possibility to add a private data room to the l2cap_chan structure. This private dataroom will be freed when the l2cap_chan reference count reach zero. This avoids dealing with separate allocated data pointer for l2cap_chan "data" attribute. Signed-off-by: Alexander Aring <aar@pengutronix.de> --- include/net/bluetooth/l2cap.h | 4 ++++ net/bluetooth/l2cap_core.c | 21 +++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-)