From 0ace9dfabec3c1e96a1cd9fe0791ecbe6737c2f9 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Sun, 24 Apr 2011 10:53:19 +0200 Subject: drbd: Take a reference on tconn when finding a tconn by name Rule #3 of kref.txt Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/block/drbd/drbd_nl.c') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 23c34baa75a4..272c4a08ee42 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -195,7 +195,7 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, adm_ctx.minor = d_in->minor; adm_ctx.mdev = minor_to_mdev(d_in->minor); - adm_ctx.tconn = conn_by_name(adm_ctx.conn_name); + adm_ctx.tconn = conn_get_by_name(adm_ctx.conn_name); if (!adm_ctx.mdev && (flags & DRBD_ADM_NEED_MINOR)) { drbd_msg_put_info("unknown minor"); @@ -223,8 +223,7 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info, drbd_msg_put_info("minor exists as different volume"); return ERR_INVALID_REQUEST; } - if (adm_ctx.mdev && !adm_ctx.tconn) - adm_ctx.tconn = adm_ctx.mdev->tconn; + return NO_ERROR; fail: @@ -238,6 +237,11 @@ static int drbd_adm_finish(struct genl_info *info, int retcode) struct nlattr *nla; const char *conn_name = NULL; + if (adm_ctx.tconn) { + kref_put(&adm_ctx.tconn->kref, &conn_destroy); + adm_ctx.tconn = NULL; + } + if (!adm_ctx.reply_skb) return -ENOMEM; @@ -2748,10 +2752,13 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb) if (!nla) return -EINVAL; conn_name = nla_data(nla); - tconn = conn_by_name(conn_name); + tconn = conn_get_by_name(conn_name); + if (!tconn) return -ENODEV; + kref_put(&tconn->kref, &conn_destroy); /* get_one_status() (re)validates tconn by itself */ + /* prime iterators, and set "filter" mode mark: * only dump this tconn. */ cb->args[0] = (long)tconn; -- cgit v1.2.2