diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_mech.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_mech.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 7 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 3 | ||||
-rw-r--r-- | net/sunrpc/pmap_clnt.c | 14 | ||||
-rw-r--r-- | net/sunrpc/socklib.c | 7 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 5 | ||||
-rw-r--r-- | net/sunrpc/svcauth.c | 5 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 8 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 33 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
12 files changed, 45 insertions, 48 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index b36b9463f5a..e5a84a482e5 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -198,11 +198,10 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - dest->data = kmalloc(len, GFP_KERNEL); + dest->data = kmemdup(p, len, GFP_KERNEL); if (unlikely(dest->data == NULL)) return ERR_PTR(-ENOMEM); dest->len = len; - memcpy(dest->data, p, len); return q; } diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 325e72e4fd3..754b8cd6439 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -70,10 +70,9 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - res->data = kmalloc(len, GFP_KERNEL); + res->data = kmemdup(p, len, GFP_KERNEL); if (unlikely(res->data == NULL)) return ERR_PTR(-ENOMEM); - memcpy(res->data, p, len); res->len = len; return q; } diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index bdedf456bc1..d57f6083889 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -76,10 +76,9 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - res->data = kmalloc(len, GFP_KERNEL); + res->data = kmemdup(p, len, GFP_KERNEL); if (unlikely(res->data == NULL)) return ERR_PTR(-ENOMEM); - memcpy(res->data, p, len); return q; } diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 1f0f079ffa6..700353b330f 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -113,9 +113,7 @@ static int rsi_match(struct cache_head *a, struct cache_head *b) static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len) { dst->len = len; - dst->data = (len ? kmalloc(len, GFP_KERNEL) : NULL); - if (dst->data) - memcpy(dst->data, src, len); + dst->data = (len ? kmemdup(src, len, GFP_KERNEL) : NULL); if (len && !dst->data) return -ENOMEM; return 0; @@ -756,10 +754,9 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) if (!new) goto out; kref_init(&new->h.ref); - new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); + new->h.name = kstrdup(name, GFP_KERNEL); if (!new->h.name) goto out_free_dom; - strcpy(new->h.name, name); new->h.flavour = &svcauthops_gss; new->pseudoflavor = pseudoflavor; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 78696f2dc7d..dfeea4fea95 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -253,10 +253,9 @@ rpc_clone_client(struct rpc_clnt *clnt) { struct rpc_clnt *new; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); if (!new) goto out_no_clnt; - memcpy(new, clnt, sizeof(*new)); atomic_set(&new->cl_count, 1); atomic_set(&new->cl_users, 0); new->cl_parent = clnt; diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index 919d5ba7ca0..e52afab413d 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c @@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task) /* Autobind on cloned rpc clients is discouraged */ BUG_ON(clnt->cl_parent != clnt); - if (xprt_test_and_set_binding(xprt)) { - task->tk_status = -EACCES; /* tell caller to check again */ - rpc_sleep_on(&xprt->binding, task, NULL, NULL); - return; - } + /* Put self on queue before sending rpcbind request, in case + * pmap_getport_done completes before we return from rpc_run_task */ + rpc_sleep_on(&xprt->binding, task, NULL, NULL); + + status = -EACCES; /* tell caller to check again */ + if (xprt_test_and_set_binding(xprt)) + goto bailout_nofree; /* Someone else may have bound if we slept */ status = 0; @@ -134,8 +136,6 @@ void rpc_getport(struct rpc_task *task) goto bailout; rpc_release_task(child); - rpc_sleep_on(&xprt->binding, task, NULL, NULL); - task->tk_xprt->stat.bind_count++; return; diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 6f17527b9e6..2635c543ba0 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c @@ -45,7 +45,8 @@ static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len) */ static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len) { - unsigned int csum2, pos; + unsigned int pos; + __wsum csum2; if (len > desc->count) len = desc->count; @@ -160,13 +161,13 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0) return -1; if (desc.offset != skb->len) { - unsigned int csum2; + __wsum csum2; csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0); desc.csum = csum_block_add(desc.csum, csum2, desc.offset); } if (desc.count) return -1; - if ((unsigned short)csum_fold(desc.csum)) + if (csum_fold(desc.csum)) return -1; if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) netdev_rx_csum_fault(skb->dev); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2807fa0eab4..eb44ec929ca 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -828,6 +828,11 @@ svc_process(struct svc_rqst *rqstp) *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); /* Encode reply */ + if (*statp == rpc_drop_reply) { + if (procp->pc_release) + procp->pc_release(rqstp, NULL, rqstp->rq_resp); + goto dropit; + } if (*statp == rpc_success && (xdr = procp->pc_encode) && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { dprintk("svc: failed to encode reply\n"); diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 8f2320aded5..ee9bb1522d5 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -126,6 +126,7 @@ void auth_domain_put(struct auth_domain *dom) if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { hlist_del(&dom->hash); dom->flavour->domain_release(dom); + spin_unlock(&auth_domain_lock); } } @@ -147,10 +148,8 @@ auth_domain_lookup(char *name, struct auth_domain *new) return hp; } } - if (new) { + if (new) hlist_add_head(&new->hash, head); - kref_get(&new->ref); - } spin_unlock(&auth_domain_lock); return new; } diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index e1bd933629f..a0a953a430c 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -101,9 +101,9 @@ static void ip_map_put(struct kref *kref) * IP addresses in reverse-endian (i.e. on a little-endian machine). * So use a trivial but reliable hash instead */ -static inline int hash_ip(unsigned long ip) +static inline int hash_ip(__be32 ip) { - int hash = ip ^ (ip>>16); + int hash = (__force u32)ip ^ ((__force u32)ip>>16); return (hash ^ (hash>>8)) & 0xff; } #endif @@ -284,7 +284,7 @@ static struct ip_map *ip_map_lookup(char *class, struct in_addr addr) ip.m_addr = addr; ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h, hash_str(class, IP_HASHBITS) ^ - hash_ip((unsigned long)addr.s_addr)); + hash_ip(addr.s_addr)); if (ch) return container_of(ch, struct ip_map, h); @@ -313,7 +313,7 @@ static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t ex ch = sunrpc_cache_update(&ip_map_cache, &ip.h, &ipm->h, hash_str(ipm->m_class, IP_HASHBITS) ^ - hash_ip((unsigned long)ipm->m_addr.s_addr)); + hash_ip(ipm->m_addr.s_addr)); if (!ch) return -ENOMEM; cache_put(ch, &ip_map_cache); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 61e307cca13..64ca1f61dd9 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -299,9 +299,15 @@ void svc_reserve(struct svc_rqst *rqstp, int space) static inline void svc_sock_put(struct svc_sock *svsk) { - if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { + if (atomic_dec_and_test(&svsk->sk_inuse) && + test_bit(SK_DEAD, &svsk->sk_flags)) { dprintk("svc: releasing dead socket\n"); - sock_release(svsk->sk_sock); + if (svsk->sk_sock->file) + sockfd_put(svsk->sk_sock); + else + sock_release(svsk->sk_sock); + if (svsk->sk_info_authunix != NULL) + svcauth_unix_info_release(svsk->sk_info_authunix); kfree(svsk); } } @@ -973,7 +979,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) return 0; } - if (test_bit(SK_CONN, &svsk->sk_flags)) { + if (svsk->sk_sk->sk_state == TCP_LISTEN) { svc_tcp_accept(svsk); svc_sock_received(svsk); return 0; @@ -1604,20 +1610,13 @@ svc_delete_socket(struct svc_sock *svsk) if (test_bit(SK_TEMP, &svsk->sk_flags)) serv->sv_tmpcnt--; - if (!atomic_read(&svsk->sk_inuse)) { - spin_unlock_bh(&serv->sv_lock); - if (svsk->sk_sock->file) - sockfd_put(svsk->sk_sock); - else - sock_release(svsk->sk_sock); - if (svsk->sk_info_authunix != NULL) - svcauth_unix_info_release(svsk->sk_info_authunix); - kfree(svsk); - } else { - spin_unlock_bh(&serv->sv_lock); - dprintk(KERN_NOTICE "svc: server socket destroy delayed\n"); - /* svsk->sk_server = NULL; */ - } + /* This atomic_inc should be needed - svc_delete_socket + * should have the semantic of dropping a reference. + * But it doesn't yet.... + */ + atomic_inc(&svsk->sk_inuse); + spin_unlock_bh(&serv->sv_lock); + svc_sock_put(svsk); } /* diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 28100e01922..757fc91ef25 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1366,7 +1366,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) if (xprt->slot == NULL) return -ENOMEM; - if (ntohs(addr->sin_port != 0)) + if (ntohs(addr->sin_port) != 0) xprt_set_bound(xprt); xprt->port = xs_get_random_port(); |