diff options
author | Santosh Shilimkar <santosh.shilimkar@oracle.com> | 2012-02-03 17:08:50 +0100 |
---|---|---|
committer | Santosh Shilimkar <ssantosh@kernel.org> | 2015-09-30 18:43:25 +0200 |
commit | 28126959882d3ec4745f2ec800f3a1d74368b2fe (patch) | |
tree | 54ac2d73bb2c97e5cb65afe2b2429bc0f1eeec52 /net/rds | |
parent | RDS: make socket bind/release locking scheme simple and more efficient (diff) | |
download | linux-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.c | 16 |
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); |