summaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@oracle.com>2012-02-03 17:08:50 +0100
committerSantosh Shilimkar <ssantosh@kernel.org>2015-09-30 18:43:25 +0200
commit28126959882d3ec4745f2ec800f3a1d74368b2fe (patch)
tree54ac2d73bb2c97e5cb65afe2b2429bc0f1eeec52 /net/rds
parentRDS: make socket bind/release locking scheme simple and more efficient (diff)
downloadlinux-28126959882d3ec4745f2ec800f3a1d74368b2fe.tar.xz
linux-28126959882d3ec4745f2ec800f3a1d74368b2fe.zip
RDS: fix rds_sock reference bug while doing bind
One need to take rds socket reference while using it and release it once done with it. rds_add_bind() code path does not do that so lets fix it. Signed-off-by: Santosh Shilimkar <ssantosh@kernel.org> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/bind.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 01989e2104bd..166c60568d5e 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -61,8 +61,10 @@ static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port,
cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) |
be16_to_cpu(rs->rs_bound_port);
- if (cmp == needle)
+ if (cmp == needle) {
+ rds_sock_addref(rs);
return rs;
+ }
}
if (insert) {
@@ -94,10 +96,10 @@ struct rds_sock *rds_find_bound(__be32 addr, __be16 port)
rs = rds_bind_lookup(addr, port, NULL);
read_unlock_irqrestore(&rds_bind_lock, flags);
- if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD))
- rds_sock_addref(rs);
- else
+ if (rs && sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) {
+ rds_sock_put(rs);
rs = NULL;
+ }
rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr,
ntohs(port));
@@ -123,14 +125,18 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port)
write_lock_irqsave(&rds_bind_lock, flags);
do {
+ struct rds_sock *rrs;
if (rover == 0)
rover++;
- if (!rds_bind_lookup(addr, cpu_to_be16(rover), rs)) {
+ rrs = rds_bind_lookup(addr, cpu_to_be16(rover), rs);
+ if (!rrs) {
*port = rs->rs_bound_port;
ret = 0;
rdsdebug("rs %p binding to %pI4:%d\n",
rs, &addr, (int)ntohs(*port));
break;
+ } else {
+ rds_sock_put(rrs);
}
} while (rover++ != last);