diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/dir.c linux-2.2.17-nfsv3/fs/nfs/dir.c --- linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/dir.c Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/fs/nfs/dir.c Mon Aug 21 01:26:18 2000 @@ -1043,9 +1043,8 @@ rehash = 1; } - dfprintk(VFS, "NFS: safe_remove(%s/%s, %ld)\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino); + dfprintk(VFS, "NFS: safe_remove(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); /* N.B. not needed now that d_delete is done in advance? */ error = -EBUSY; @@ -1065,7 +1064,8 @@ } nfs_zap_caches(dir_i); - NFS_CACHEINV(inode); + if (inode) + NFS_CACHEINV(inode); error = NFS_CALL(remove, dir_i, (dir, &dir_attr, &dentry->d_name, cred)); nfs_refresh_inode(dir_i, &dir_attr); if (error < 0) diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/inode.c linux-2.2.17-nfsv3/fs/nfs/inode.c --- linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/inode.c Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/fs/nfs/inode.c Thu Aug 31 22:27:24 2000 @@ -465,10 +465,6 @@ if (data->wsize == 0) server->wsize = nfs_block_size(fsinfo.wtpref, NULL); - server->dtsize = nfs_block_size(fsinfo.dtpref, NULL); - if (server->dtsize > PAGE_CACHE_SIZE) - server->dtsize = PAGE_CACHE_SIZE; - /* NFSv3: we don't have bsize, but rather rtmult and wtmult... */ if (!fsinfo.bsize) fsinfo.bsize = (fsinfo.rtmult>fsinfo.wtmult) ? fsinfo.rtmult : fsinfo.wtmult; @@ -496,6 +492,12 @@ server->wpages = NFS_WRITE_MAXIOV; server->wsize = server->wpages << PAGE_CACHE_SHIFT; } + + server->dtsize = nfs_block_size(fsinfo.dtpref, NULL); + if (server->dtsize > PAGE_CACHE_SIZE) + server->dtsize = PAGE_CACHE_SIZE; + if (server->dtsize > server->rsize) + server->dtsize = server->rsize; maxlen = (version == 2) ? NFS2_MAXNAMLEN : NFS3_MAXNAMLEN; diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/proc.c linux-2.2.17-nfsv3/fs/nfs/proc.c --- linux-2.2.17pre19-nfsv3-0.22.3/fs/nfs/proc.c Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/fs/nfs/proc.c Mon Aug 21 01:26:18 2000 @@ -351,11 +351,7 @@ struct nfs_readdirargs arg; struct nfs_readdirres res; struct rpc_message msg = { NFSPROC_READDIR, &arg, &res, cred }; - struct nfs_server *server = NFS_DSERVER(dir); int status; - - if (server->rsize < size) - size = server->rsize; dir_attr->valid = 0; arg.fh = NFS_FH(dir); diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/include/linux/sunrpc/sched.h linux-2.2.17-nfsv3/include/linux/sunrpc/sched.h --- linux-2.2.17pre19-nfsv3-0.22.3/include/linux/sunrpc/sched.h Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/include/linux/sunrpc/sched.h Mon Aug 21 01:34:31 2000 @@ -42,6 +42,7 @@ #endif struct rpc_task * tk_next_task; /* global list of tasks */ struct rpc_task * tk_prev_task; /* global list of tasks */ + struct rpc_task * tk_parent; /* parent task */ struct rpc_clnt * tk_client; /* RPC client */ struct rpc_rqst * tk_rqstp; /* RPC request */ volatile int tk_status; /* result of last operation */ @@ -76,14 +77,14 @@ struct timer_list tk_timer; /* kernel timer */ struct wait_queue * tk_wait; /* sync: sleep on this q */ unsigned long tk_timeout; /* timeout for rpc_sleep() */ - unsigned short tk_flags; /* misc flags */ - unsigned short tk_lock; /* Task lock counter */ + unsigned int tk_flags; /* misc flags */ + unsigned int tk_lock; /* Task lock counter */ unsigned char tk_active : 1,/* Task has been activated */ tk_wakeup : 1;/* Task waiting to wake up */ volatile unsigned char tk_running : 1,/* Task is running */ tk_sleeping : 1;/* Task is truly asleep */ #ifdef RPC_DEBUG - unsigned short tk_pid; /* debugging aid */ + unsigned int tk_pid; /* debugging aid */ #endif }; #define tk_auth tk_client->cl_auth @@ -148,23 +149,16 @@ int rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *); void rpc_remove_wait_queue(struct rpc_task *); -void __rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, - rpc_action action, rpc_action timer); void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, rpc_action action, rpc_action timer); void rpc_sleep_locked(struct rpc_wait_queue *, struct rpc_task *, rpc_action action, rpc_action timer); void rpc_add_timer(struct rpc_task *task, rpc_action timer); -void __rpc_wake_up_task(struct rpc_task *); void rpc_wake_up_task(struct rpc_task *); -void __rpc_wake_up(struct rpc_wait_queue *); void rpc_wake_up(struct rpc_wait_queue *); -struct rpc_task *__rpc_wake_up_next(struct rpc_wait_queue *); struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); -void __rpc_wake_up_status(struct rpc_wait_queue *, int); void rpc_wake_up_status(struct rpc_wait_queue *, int); int __rpc_lock_task(struct rpc_task *); -void __rpc_unlock_task(struct rpc_task *); void rpc_unlock_task(struct rpc_task *); void rpc_delay(struct rpc_task *, unsigned long); void * rpc_allocate(unsigned int flags, unsigned int); diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/include/linux/sunrpc/xprt.h linux-2.2.17-nfsv3/include/linux/sunrpc/xprt.h --- linux-2.2.17pre19-nfsv3-0.22.3/include/linux/sunrpc/xprt.h Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/include/linux/sunrpc/xprt.h Mon Aug 21 01:39:09 2000 @@ -185,7 +185,9 @@ unsigned long); int xprt_reserve(struct rpc_task *); +int xprt_down_transmit(struct rpc_task *); void xprt_transmit(struct rpc_task *); +void xprt_up_transmit(struct rpc_task *); void xprt_receive(struct rpc_task *); int xprt_adjust_timeout(struct rpc_timeout *); void xprt_release(struct rpc_task *); @@ -205,6 +207,24 @@ { if (xprt_tcp_pending()) __rpciod_tcp_dispatcher(); +} + +static inline +int xprt_connected(struct rpc_xprt *xprt) +{ + return xprt->connected; +} + +static inline +void xprt_set_connected(struct rpc_xprt *xprt) +{ + xprt->connected = 1; +} + +static inline +void xprt_clear_connected(struct rpc_xprt *xprt) +{ + xprt->connected = 0; } #endif /* __KERNEL__*/ diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/clnt.c linux-2.2.17-nfsv3/net/sunrpc/clnt.c --- linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/clnt.c Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/net/sunrpc/clnt.c Thu Aug 31 22:08:51 2000 @@ -78,6 +78,10 @@ xdr_init(); +#ifdef RPC_DEBUG + rpc_register_sysctl(); +#endif + if (!xprt) goto out; if (vers >= program->nrvers || !(version = program->version[vers])) @@ -503,7 +507,7 @@ struct rpc_clnt *clnt = task->tk_client; struct rpc_xprt *xprt = task->tk_xprt; - task->tk_action = (xprt->connected) ? call_transmit : call_reconnect; + task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_reconnect; if (!clnt->cl_port) { task->tk_action = call_reconnect; @@ -659,7 +663,7 @@ else if (!clnt->cl_port) { task->tk_action = call_bind; clnt->cl_stats->rpcretrans++; - } else if (clnt->cl_xprt->stream && !clnt->cl_xprt->connected) { + } else if (clnt->cl_xprt->stream && !xprt_connected(clnt->cl_xprt)) { task->tk_action = call_reconnect; clnt->cl_stats->rpcretrans++; } else { diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/sched.c linux-2.2.17-nfsv3/net/sunrpc/sched.c --- linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/sched.c Mon Aug 21 01:26:07 2000 +++ linux-2.2.17-nfsv3/net/sunrpc/sched.c Wed Aug 23 13:03:19 2000 @@ -310,7 +310,7 @@ * NB: An RPC task will only receive interrupt-driven events as long * as it's on a wait queue. */ -void +static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, rpc_action action, rpc_action timer) { @@ -378,7 +378,7 @@ * It would probably suffice to cli/sti the del_timer and remove_wait_queue * operations individually. */ -void +static inline void __rpc_wake_up_task(struct rpc_task *task) { dprintk("RPC: %4d __rpc_wake_up (now %ld inh %d)\n", @@ -401,6 +401,8 @@ return; __rpc_disable_timer(task); + if (task->tk_rpcwait != &schedq) + __rpc_remove_wait_queue(task); /* If the task has been locked, then set tk_wakeup so that * rpc_unlock_task() wakes us up... */ @@ -410,8 +412,6 @@ } else task->tk_wakeup = 0; - if (task->tk_rpcwait != &schedq) - __rpc_remove_wait_queue(task); __rpc_make_runnable(task); dprintk("RPC: __rpc_wake_up done\n"); @@ -448,7 +448,7 @@ /* * Wake up the next task on the wait queue. */ -struct rpc_task * +static inline struct rpc_task * __rpc_wake_up_next(struct rpc_wait_queue *queue) { struct rpc_task *task; @@ -476,19 +476,13 @@ * Wake up all tasks on a queue */ void -__rpc_wake_up(struct rpc_wait_queue *queue) -{ - while (queue->task) - __rpc_wake_up_task(queue->task); -} - -void rpc_wake_up(struct rpc_wait_queue *queue) { unsigned long oldflags; spin_lock_irqsave(&rpc_queue_lock, oldflags); - __rpc_wake_up(queue); + while (queue->task) + __rpc_wake_up_task(queue->task); spin_unlock_irqrestore(&rpc_queue_lock, oldflags); } @@ -496,23 +490,16 @@ * Wake up all tasks on a queue, and set their status value. */ void -__rpc_wake_up_status(struct rpc_wait_queue *queue, int status) +rpc_wake_up_status(struct rpc_wait_queue *queue, int status) { struct rpc_task *task; + unsigned long oldflags; + spin_lock_irqsave(&rpc_queue_lock, oldflags); while ((task = queue->task) != NULL) { task->tk_status = status; __rpc_wake_up_task(task); } -} - -void -rpc_wake_up_status(struct rpc_wait_queue *queue, int status) -{ - unsigned long oldflags; - - spin_lock_irqsave(&rpc_queue_lock, oldflags); - __rpc_wake_up_status(queue, status); spin_unlock_irqrestore(&rpc_queue_lock, oldflags); } @@ -531,7 +518,7 @@ return 0; } -void +static inline void __rpc_unlock_task(struct rpc_task *task) { if (task->tk_lock && !--task->tk_lock && task->tk_wakeup) @@ -968,14 +955,18 @@ * parent task may already have gone away */ static inline struct rpc_task * -rpc_find_parent(struct rpc_task *child) +__rpc_find_parent(struct rpc_task *child) { - struct rpc_task *temp, *parent; + struct rpc_task *head, *parent; - parent = (struct rpc_task *) child->tk_calldata; - for (temp = childq.task; temp; temp = temp->tk_next) { - if (temp == parent) - return parent; + parent = child->tk_parent; + if ((head = childq.task) != NULL) { + struct rpc_task *task = head; + do { + if (task == parent) + return parent; + task = task->tk_next; + } while (task != head); } return NULL; } @@ -987,7 +978,7 @@ unsigned long oldflags; spin_lock_irqsave(&rpc_queue_lock, oldflags); - if ((parent = rpc_find_parent(child)) != NULL) { + if ((parent = __rpc_find_parent(child)) != NULL) { parent->tk_status = child->tk_status; __rpc_wake_up_task(parent); } @@ -1006,7 +997,7 @@ if (!task) goto fail; task->tk_exit = rpc_child_exit; - task->tk_calldata = parent; + task->tk_parent = parent; return task; fail: diff -u --recursive --new-file linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/xprt.c linux-2.2.17-nfsv3/net/sunrpc/xprt.c --- linux-2.2.17pre19-nfsv3-0.22.3/net/sunrpc/xprt.c Mon Aug 21 01:26:08 2000 +++ linux-2.2.17-nfsv3/net/sunrpc/xprt.c Thu Aug 31 16:38:24 2000 @@ -412,7 +412,7 @@ } __xprt_disable_tcp_timer(xprt); - xprt->connected = 0; + xprt_clear_connected(xprt); __xprt_remove_pending(xprt); rpc_wake_up_status(&xprt->pending, -ENOTCONN); @@ -445,9 +445,8 @@ __xprt_disconnect(struct rpc_xprt *xprt) { dprintk("RPC: disconnected transport %p\n", xprt); - xprt->connected = 0; + xprt_clear_connected(xprt); __xprt_append_pending(xprt); - rpc_wake_up_status(&xprt->pending, -ENOTCONN); } /* @@ -462,7 +461,7 @@ int status; dprintk("RPC: %4d xprt_reconnect %p connected %d\n", - task->tk_pid, xprt, xprt->connected); + task->tk_pid, xprt, xprt_connected(xprt)); if (xprt->shutdown) return; @@ -519,10 +518,10 @@ } dprintk("RPC: %4d connect status %d connected %d\n", - task->tk_pid, status, xprt->connected); + task->tk_pid, status, xprt_connected(xprt)); start_bh_atomic(); - if (!xprt->connected) { + if (!xprt_connected(xprt)) { task->tk_timeout = xprt->timeout.to_maxval; rpc_sleep_on(&xprt->reconn, task, xprt_reconn_status, NULL); end_bh_atomic(); @@ -540,17 +539,13 @@ } /* - * Reconnect timeout. We just mark the transport as not being in the - * process of reconnecting, and leave the rest to the upper layers. + * Reconnect done */ static void xprt_reconn_status(struct rpc_task *task) { struct rpc_xprt *xprt = task->tk_xprt; - dprintk("RPC: %4d xprt_reconn_timeout %d\n", - task->tk_pid, task->tk_status); - xprt->connecting = 0; rpc_wake_up(&xprt->reconn); } @@ -849,7 +844,7 @@ if (xprt->shutdown) return -EIO; - if (!xprt->connected) + if (!xprt_connected(xprt)) return -ENOTCONN; /* Read in a new fragment marker if necessary */ @@ -956,15 +951,13 @@ while ((xprt = xprt_remove_pending_next()) != NULL) { dprintk("rpciod_tcp_dispatcher: Processing %p\n", xprt); - if (!xprt->connected && !xprt->connecting) { - xprt_close(xprt); - continue; - } - do { result = tcp_input_record(xprt); } while (result >= 0); + if (!xprt_connected(xprt) && !xprt->connecting) + xprt_close(xprt); + if (safe_retry++ > 200) { schedule(); safe_retry = 0; @@ -996,7 +989,7 @@ dprintk("RPC: tcp_data_ready client %p\n", xprt); dprintk("RPC: state %x conn %d dead %d zapped %d\n", - sk->state, xprt->connected, + sk->state, xprt_connected(xprt), sk->dead, sk->zapped); wake: wake_up_interruptible(sk->sleep); @@ -1012,12 +1005,12 @@ goto wake; dprintk("RPC: tcp_state_change client %p...\n", xprt); dprintk("RPC: state %x conn %d dead %d zapped %d\n", - sk->state, xprt->connected, + sk->state, xprt_connected(xprt), sk->dead, sk->zapped); switch (sk->state) { case TCP_ESTABLISHED: - xprt->connected = 1; + xprt_set_connected(xprt); if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending) rpc_wake_up_task(xprt->snd_task); rpc_wake_up(&xprt->reconn); @@ -1117,7 +1110,7 @@ * Serialize access to sockets, in order to prevent different * requests from interfering with each other. */ -static int +int xprt_down_transmit(struct rpc_task *task) { struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; @@ -1143,7 +1136,7 @@ /* * Releases the socket for use by other requests. */ -static inline void +void xprt_up_transmit(struct rpc_task *task) { struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; @@ -1165,13 +1158,12 @@ struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = req->rq_xprt; - dprintk("RPC: %4d xprt_transmit(%x)\n", task->tk_pid, - *(u32 *)(req->rq_svec[0].iov_base)); + dprintk("RPC: %4d xprt_transmit(%x)\n", task->tk_pid, req->rq_xid); if (xprt->shutdown) task->tk_status = -EIO; - if (!xprt->connected) + if (!xprt_connected(xprt)) task->tk_status = -ENOTCONN; if (task->tk_status < 0) @@ -1271,13 +1263,13 @@ spin_unlock_irqrestore(&xprt_sock_lock, oldflags); return; case -EAGAIN: - /* Keep holding the socket if it is blocked */ - rpc_delay(task, HZ>>4); - return; case -ECONNREFUSED: case -ENOTCONN: - if (!xprt->stream) + /* Keep holding the socket if it is blocked */ + if (!xprt->stream) { + rpc_delay(task, HZ>>4); return; + } default: goto out_release; } @@ -1553,12 +1545,12 @@ if (xprt->prot == IPPROTO_UDP) { sk->data_ready = udp_data_ready; sk->write_space = udp_write_space; - xprt->connected = 1; + xprt_set_connected(xprt); } else { sk->data_ready = tcp_data_ready; sk->state_change = tcp_state_change; sk->write_space = tcp_write_space; - xprt->connected = 0; + xprt_clear_connected(xprt); } /* Reset to new socket */