]> err.no Git - linux-2.6/blobdiff - net/sunrpc/xprtsock.c
[PATCH] REPORTING-BUGS: request .config file
[linux-2.6] / net / sunrpc / xprtsock.c
index cb8e6c34e12f7a1f2a7fa53722bbf3e5c204b0a3..2fc4a3123261b1b9c37ff3ef122da2d10e817129 100644 (file)
@@ -215,7 +215,6 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a
        struct page **ppage = xdr->pages;
        unsigned int len, pglen = xdr->page_len;
        int err, ret = 0;
-       ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
 
        if (unlikely(!sock))
                return -ENOTCONN;
@@ -248,7 +247,6 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a
                base &= ~PAGE_CACHE_MASK;
        }
 
-       sendpage = sock->ops->sendpage ? : sock_no_sendpage;
        do {
                int flags = XS_SENDMSG_FLAGS;
 
@@ -261,10 +259,7 @@ static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int a
                if (pglen != len || xdr->tail[0].iov_len != 0)
                        flags |= MSG_MORE;
 
-               /* Hmm... We might be dealing with highmem pages */
-               if (PageHighMem(*ppage))
-                       sendpage = sock_no_sendpage;
-               err = sendpage(sock, *ppage, base, len, flags);
+               err = kernel_sendpage(sock, *ppage, base, len, flags);
                if (ret == 0)
                        ret = err;
                else if (err > 0)
@@ -341,7 +336,7 @@ static int xs_udp_send_request(struct rpc_task *task)
 
        req->rq_xtime = jiffies;
        status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr,
-                               sizeof(xprt->addr), xdr, req->rq_bytes_sent);
+                               xprt->addrlen, xdr, req->rq_bytes_sent);
 
        dprintk("RPC:      xs_udp_send_request(%u) = %d\n",
                        xdr->len - req->rq_bytes_sent, status);
@@ -553,7 +548,8 @@ static void xs_udp_data_ready(struct sock *sk, int len)
        struct rpc_rqst *rovr;
        struct sk_buff *skb;
        int err, repsize, copied;
-       u32 _xid, *xp;
+       u32 _xid;
+       __be32 *xp;
 
        read_lock(&sk->sk_callback_lock);
        dprintk("RPC:      xs_udp_data_ready...\n");
@@ -1027,8 +1023,11 @@ static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_forma
  */
 static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
 {
+       struct sockaddr_in *sap = (struct sockaddr_in *) &xprt->addr;
+
        dprintk("RPC:      setting port for xprt %p to %u\n", xprt, port);
-       xprt->addr.sin_port = htons(port);
+
+       sap->sin_port = htons(port);
 }
 
 static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
@@ -1041,7 +1040,7 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
 
        do {
                myaddr.sin_port = htons(port);
-               err = sock->ops->bind(sock, (struct sockaddr *) &myaddr,
+               err = kernel_bind(sock, (struct sockaddr *) &myaddr,
                                                sizeof(myaddr));
                if (err == 0) {
                        xprt->port = port;
@@ -1059,15 +1058,45 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
        return err;
 }
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key xs_key[2];
+static struct lock_class_key xs_slock_key[2];
+
+static inline void xs_reclassify_socket(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+       BUG_ON(sk->sk_lock.owner != NULL);
+       switch (sk->sk_family) {
+       case AF_INET:
+               sock_lock_init_class_and_name(sk, "slock-AF_INET-NFS",
+                       &xs_slock_key[0], "sk_lock-AF_INET-NFS", &xs_key[0]);
+               break;
+
+       case AF_INET6:
+               sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFS",
+                       &xs_slock_key[1], "sk_lock-AF_INET6-NFS", &xs_key[1]);
+               break;
+
+       default:
+               BUG();
+       }
+}
+#else
+static inline void xs_reclassify_socket(struct socket *sock)
+{
+}
+#endif
+
 /**
  * xs_udp_connect_worker - set up a UDP socket
- * @args: RPC transport to connect
+ * @work: RPC transport to connect
  *
  * Invoked by a work queue tasklet.
  */
-static void xs_udp_connect_worker(void *args)
+static void xs_udp_connect_worker(struct work_struct *work)
 {
-       struct rpc_xprt *xprt = (struct rpc_xprt *) args;
+       struct rpc_xprt *xprt =
+               container_of(work, struct rpc_xprt, connect_worker.work);
        struct socket *sock = xprt->sock;
        int err, status = -EIO;
 
@@ -1081,6 +1110,7 @@ static void xs_udp_connect_worker(void *args)
                dprintk("RPC:      can't create UDP transport socket (%d).\n", -err);
                goto out;
        }
+       xs_reclassify_socket(sock);
 
        if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
                sock_release(sock);
@@ -1137,7 +1167,7 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
         */
        memset(&any, 0, sizeof(any));
        any.sa_family = AF_UNSPEC;
-       result = sock->ops->connect(sock, &any, sizeof(any), 0);
+       result = kernel_connect(sock, &any, sizeof(any), 0);
        if (result)
                dprintk("RPC:      AF_UNSPEC connect return code %d\n",
                                result);
@@ -1145,13 +1175,14 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
 
 /**
  * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
- * @args: RPC transport to connect
+ * @work: RPC transport to connect
  *
  * Invoked by a work queue tasklet.
  */
-static void xs_tcp_connect_worker(void *args)
+static void xs_tcp_connect_worker(struct work_struct *work)
 {
-       struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+       struct rpc_xprt *xprt =
+               container_of(work, struct rpc_xprt, connect_worker.work);
        struct socket *sock = xprt->sock;
        int err, status = -EIO;
 
@@ -1164,6 +1195,7 @@ static void xs_tcp_connect_worker(void *args)
                        dprintk("RPC:      can't create TCP transport socket (%d).\n", -err);
                        goto out;
                }
+               xs_reclassify_socket(sock);
 
                if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) {
                        sock_release(sock);
@@ -1208,8 +1240,8 @@ static void xs_tcp_connect_worker(void *args)
        /* Tell the socket layer to start connecting... */
        xprt->stat.connect_count++;
        xprt->stat.connect_start = jiffies;
-       status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
-                       sizeof(xprt->addr), O_NONBLOCK);
+       status = kernel_connect(sock, (struct sockaddr *) &xprt->addr,
+                       xprt->addrlen, O_NONBLOCK);
        dprintk("RPC: %p  connect status %d connected %d sock state %d\n",
                        xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
        if (status < 0) {
@@ -1263,7 +1295,7 @@ static void xs_connect(struct rpc_task *task)
                        xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
        } else {
                dprintk("RPC:      xs_connect scheduled xprt %p\n", xprt);
-               schedule_work(&xprt->connect_worker);
+               schedule_delayed_work(&xprt->connect_worker, 0);
 
                /* flush_scheduled_work can sleep... */
                if (!RPC_IS_ASYNC(task))
@@ -1359,6 +1391,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
 int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
 {
        size_t slot_table_size;
+       struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
 
        xprt->max_reqs = xprt_udp_slot_table_entries;
        slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
@@ -1366,17 +1399,16 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
        if (xprt->slot == NULL)
                return -ENOMEM;
 
-       if (ntohs(xprt->addr.sin_port) != 0)
+       if (ntohs(addr->sin_port) != 0)
                xprt_set_bound(xprt);
        xprt->port = xs_get_random_port();
 
        xprt->prot = IPPROTO_UDP;
        xprt->tsh_size = 0;
-       xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
        /* XXX: header size can vary due to auth type, IPv6, etc. */
        xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
 
-       INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt);
+       INIT_DELAYED_WORK(&xprt->connect_worker, xs_udp_connect_worker);
        xprt->bind_timeout = XS_BIND_TO;
        xprt->connect_timeout = XS_UDP_CONN_TO;
        xprt->reestablish_timeout = XS_UDP_REEST_TO;
@@ -1405,6 +1437,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
 int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
 {
        size_t slot_table_size;
+       struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
 
        xprt->max_reqs = xprt_tcp_slot_table_entries;
        slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
@@ -1412,16 +1445,15 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
        if (xprt->slot == NULL)
                return -ENOMEM;
 
-       if (ntohs(xprt->addr.sin_port) != 0)
+       if (ntohs(addr->sin_port) != 0)
                xprt_set_bound(xprt);
        xprt->port = xs_get_random_port();
 
        xprt->prot = IPPROTO_TCP;
        xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
-       xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
        xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
 
-       INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt);
+       INIT_DELAYED_WORK(&xprt->connect_worker, xs_tcp_connect_worker);
        xprt->bind_timeout = XS_BIND_TO;
        xprt->connect_timeout = XS_TCP_CONN_TO;
        xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;