include/linux/sunrpc/xprt.h | 6 +++++- net/sunrpc/xprt.c | 27 +++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.3-06-fix_oops/include/linux/sunrpc/xprt.h linux-2.6.3-07-XID/include/linux/sunrpc/xprt.h --- linux-2.6.3-06-fix_oops/include/linux/sunrpc/xprt.h 2004-02-14 16:21:33.000000000 +0100 +++ linux-2.6.3-07-XID/include/linux/sunrpc/xprt.h 2004-02-15 11:20:56.000000000 +0100 @@ -102,7 +102,6 @@ struct rpc_rqst { struct xdr_buf rq_private_buf; /* The receive buffer * used in the softirq. */ - /* * For authentication (e.g. auth_des) */ @@ -155,6 +154,11 @@ struct rpc_xprt { stream : 1; /* TCP */ /* + * XID + */ + __u32 xid; /* Next XID value to use */ + + /* * State of TCP reply receive stuff */ u32 tcp_recm, /* Fragment header */ diff -u --recursive --new-file --show-c-function linux-2.6.3-06-fix_oops/net/sunrpc/xprt.c linux-2.6.3-07-XID/net/sunrpc/xprt.c --- linux-2.6.3-06-fix_oops/net/sunrpc/xprt.c 2004-02-14 16:21:22.000000000 +0100 +++ linux-2.6.3-07-XID/net/sunrpc/xprt.c 2004-02-15 09:13:34.000000000 +0100 @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -1333,22 +1334,14 @@ do_xprt_reserve(struct rpc_task *task) /* * Allocate a 'unique' XID */ -static u32 -xprt_alloc_xid(void) +static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) { - static spinlock_t xid_lock = SPIN_LOCK_UNLOCKED; - static int need_init = 1; - static u32 xid; - u32 ret; - - spin_lock(&xid_lock); - if (unlikely(need_init)) { - xid = get_seconds() << 12; - need_init = 0; - } - ret = xid++; - spin_unlock(&xid_lock); - return ret; + return xprt->xid++; +} + +static inline void xprt_init_xid(struct rpc_xprt *xprt) +{ + get_random_bytes(&xprt->xid, sizeof(xprt->xid)); } /* @@ -1362,7 +1355,7 @@ xprt_request_init(struct rpc_task *task, req->rq_timeout = xprt->timeout; req->rq_task = task; req->rq_xprt = xprt; - req->rq_xid = xprt_alloc_xid(); + req->rq_xid = xprt_alloc_xid(xprt); INIT_LIST_HEAD(&req->rq_list); dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, req->rq_xid); @@ -1481,6 +1474,8 @@ xprt_setup(int proto, struct sockaddr_in req->rq_next = NULL; xprt->free = xprt->slot; + xprt_init_xid(xprt); + /* Check whether we want to use a reserved port */ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;