aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-04-24 04:53:19 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:49:06 -0500
commit0ace9dfabec3c1e96a1cd9fe0791ecbe6737c2f9 (patch)
treede80467afbc59c4d98cdf6a3defa55fee051ac98 /drivers/block/drbd/drbd_nl.c
parent9dc9fbb35733c8ea97fe9b1cfc5499c7a625805c (diff)
drbd: Take a reference on tconn when finding a tconn by name
Rule #3 of kref.txt Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
-rw-r--r--drivers/block/drbd/drbd_nl.c15
1 files changed, 11 insertions, 4 deletions
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,
195 195
196 adm_ctx.minor = d_in->minor; 196 adm_ctx.minor = d_in->minor;
197 adm_ctx.mdev = minor_to_mdev(d_in->minor); 197 adm_ctx.mdev = minor_to_mdev(d_in->minor);
198 adm_ctx.tconn = conn_by_name(adm_ctx.conn_name); 198 adm_ctx.tconn = conn_get_by_name(adm_ctx.conn_name);
199 199
200 if (!adm_ctx.mdev && (flags & DRBD_ADM_NEED_MINOR)) { 200 if (!adm_ctx.mdev && (flags & DRBD_ADM_NEED_MINOR)) {
201 drbd_msg_put_info("unknown minor"); 201 drbd_msg_put_info("unknown minor");
@@ -223,8 +223,7 @@ static int drbd_adm_prepare(struct sk_buff *skb, struct genl_info *info,
223 drbd_msg_put_info("minor exists as different volume"); 223 drbd_msg_put_info("minor exists as different volume");
224 return ERR_INVALID_REQUEST; 224 return ERR_INVALID_REQUEST;
225 } 225 }
226 if (adm_ctx.mdev && !adm_ctx.tconn) 226
227 adm_ctx.tconn = adm_ctx.mdev->tconn;
228 return NO_ERROR; 227 return NO_ERROR;
229 228
230fail: 229fail:
@@ -238,6 +237,11 @@ static int drbd_adm_finish(struct genl_info *info, int retcode)
238 struct nlattr *nla; 237 struct nlattr *nla;
239 const char *conn_name = NULL; 238 const char *conn_name = NULL;
240 239
240 if (adm_ctx.tconn) {
241 kref_put(&adm_ctx.tconn->kref, &conn_destroy);
242 adm_ctx.tconn = NULL;
243 }
244
241 if (!adm_ctx.reply_skb) 245 if (!adm_ctx.reply_skb)
242 return -ENOMEM; 246 return -ENOMEM;
243 247
@@ -2748,10 +2752,13 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
2748 if (!nla) 2752 if (!nla)
2749 return -EINVAL; 2753 return -EINVAL;
2750 conn_name = nla_data(nla); 2754 conn_name = nla_data(nla);
2751 tconn = conn_by_name(conn_name); 2755 tconn = conn_get_by_name(conn_name);
2756
2752 if (!tconn) 2757 if (!tconn)
2753 return -ENODEV; 2758 return -ENODEV;
2754 2759
2760 kref_put(&tconn->kref, &conn_destroy); /* get_one_status() (re)validates tconn by itself */
2761
2755 /* prime iterators, and set "filter" mode mark: 2762 /* prime iterators, and set "filter" mode mark:
2756 * only dump this tconn. */ 2763 * only dump this tconn. */
2757 cb->args[0] = (long)tconn; 2764 cb->args[0] = (long)tconn;