diff -u --recursive --new-file linux-2.4.17-ping/fs/lockd/clntproc.c linux-2.4.17-rpc_bkl/fs/lockd/clntproc.c --- linux-2.4.17-ping/fs/lockd/clntproc.c Thu Oct 11 16:52:18 2001 +++ linux-2.4.17-rpc_bkl/fs/lockd/clntproc.c Wed Dec 19 13:11:06 2001 @@ -569,11 +569,15 @@ printk(KERN_WARNING "lockd: unexpected unlock status: %d\n", status); die: + lock_kernel(); nlm_release_host(req->a_host); + unlock_kernel(); kfree(req); return; retry_rebind: + lock_kernel(); nlm_rebind_host(req->a_host); + unlock_kernel(); retry_unlock: rpc_restart_call(task); } @@ -650,12 +654,16 @@ } die: + lock_kernel(); nlm_release_host(req->a_host); + unlock_kernel(); kfree(req); return; retry_cancel: + lock_kernel(); nlm_rebind_host(req->a_host); + unlock_kernel(); rpc_restart_call(task); rpc_delay(task, 30 * HZ); } diff -u --recursive --new-file linux-2.4.17-ping/fs/lockd/svc4proc.c linux-2.4.17-rpc_bkl/fs/lockd/svc4proc.c --- linux-2.4.17-ping/fs/lockd/svc4proc.c Mon Oct 1 22:45:47 2001 +++ linux-2.4.17-rpc_bkl/fs/lockd/svc4proc.c Wed Dec 19 13:11:06 2001 @@ -17,6 +17,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT @@ -499,7 +500,9 @@ dprintk("lockd: %4d callback failed (errno = %d)\n", task->tk_pid, -task->tk_status); } + lock_kernel(); nlm_release_host(call->a_host); + unlock_kernel(); kfree(call); } diff -u --recursive --new-file linux-2.4.17-ping/fs/lockd/svclock.c linux-2.4.17-rpc_bkl/fs/lockd/svclock.c --- linux-2.4.17-ping/fs/lockd/svclock.c Thu Oct 11 16:52:18 2001 +++ linux-2.4.17-rpc_bkl/fs/lockd/svclock.c Wed Dec 19 13:11:06 2001 @@ -576,9 +576,10 @@ dprintk("lockd: GRANT_MSG RPC callback\n"); dprintk("callback: looking for cookie %x \n", *(unsigned int *)(call->a_args.cookie.data)); + lock_kernel(); if (!(block = nlmsvc_find_block(&call->a_args.cookie))) { dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data)); - return; + goto out; } /* Technically, we should down the file semaphore here. Since we @@ -599,6 +600,8 @@ block->b_incall = 0; nlm_release_host(call->a_host); + out: + unlock_kernel(); } /* diff -u --recursive --new-file linux-2.4.17-ping/fs/lockd/svcproc.c linux-2.4.17-rpc_bkl/fs/lockd/svcproc.c --- linux-2.4.17-ping/fs/lockd/svcproc.c Thu Oct 11 16:52:18 2001 +++ linux-2.4.17-rpc_bkl/fs/lockd/svcproc.c Wed Dec 19 13:11:06 2001 @@ -18,6 +18,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT @@ -527,7 +528,9 @@ dprintk("lockd: %4d callback failed (errno = %d)\n", task->tk_pid, -task->tk_status); } + lock_kernel(); nlm_release_host(call->a_host); + unlock_kernel(); kfree(call); } diff -u --recursive --new-file linux-2.4.17-ping/fs/nfs/file.c linux-2.4.17-rpc_bkl/fs/nfs/file.c --- linux-2.4.17-ping/fs/nfs/file.c Wed Dec 19 13:07:56 2001 +++ linux-2.4.17-rpc_bkl/fs/nfs/file.c Wed Dec 19 13:11:06 2001 @@ -99,7 +99,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long) *ppos); + lock_kernel(); result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + unlock_kernel(); if (!result) result = generic_file_read(file, buf, count, ppos); return result; @@ -115,7 +117,9 @@ dfprintk(VFS, "nfs: mmap(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); + lock_kernel(); status = nfs_revalidate_inode(NFS_SERVER(inode), inode); + unlock_kernel(); if (!status) status = generic_file_mmap(file, vma); return status; @@ -134,13 +138,11 @@ dfprintk(VFS, "nfs: fsync(%x/%ld)\n", inode->i_dev, inode->i_ino); - lock_kernel(); status = nfs_wb_file(inode, file); if (!status) { status = file->f_error; file->f_error = 0; } - unlock_kernel(); return status; } @@ -160,12 +162,7 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) { - long status; - - lock_kernel(); - status = nfs_updatepage(file, page, offset, to-offset); - unlock_kernel(); - return status; + return nfs_updatepage(file, page, offset, to-offset); } /* @@ -219,7 +216,9 @@ result = -EBUSY; if (IS_SWAPFILE(inode)) goto out_swapfile; + lock_kernel(); result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + unlock_kernel(); if (result) goto out; diff -u --recursive --new-file linux-2.4.17-ping/fs/nfs/flushd.c linux-2.4.17-rpc_bkl/fs/nfs/flushd.c --- linux-2.4.17-ping/fs/nfs/flushd.c Fri Nov 9 23:28:15 2001 +++ linux-2.4.17-rpc_bkl/fs/nfs/flushd.c Wed Dec 19 13:11:06 2001 @@ -51,6 +51,19 @@ * This is the wait queue all cluster daemons sleep on */ static struct rpc_wait_queue flushd_queue = RPC_INIT_WAITQ("nfs_flushd"); +static spinlock_t nfs_flushd_lock = SPIN_LOCK_UNLOCKED; + +static inline void +nfs_lock_flushd(void) +{ + spin_lock(&nfs_flushd_lock); +} + +static inline void +nfs_unlock_flushd(void) +{ + spin_unlock(&nfs_flushd_lock); +} /* * Local function declarations. @@ -67,12 +80,11 @@ dprintk("NFS: writecache_init\n"); - lock_kernel(); - status = -ENOMEM; /* Create the RPC task */ if (!(task = rpc_new_task(server->client, NULL, RPC_TASK_ASYNC))) - goto out_unlock; + return -ENOMEM; + nfs_lock_flushd(); cache = server->rw_requests; status = 0; @@ -89,22 +101,21 @@ cache->auth = server->client->cl_auth; task->tk_action = nfs_flushd; task->tk_exit = nfs_flushd_exit; + nfs_unlock_flushd(); rpc_execute(task); - unlock_kernel(); return 0; out_unlock: - if (task) - rpc_release_task(task); - unlock_kernel(); - return status; + nfs_unlock_flushd(); + rpc_release_task(task); + return 0; } void nfs_reqlist_exit(struct nfs_server *server) { struct nfs_reqlist *cache; - lock_kernel(); + nfs_lock_flushd(); cache = server->rw_requests; if (!cache) goto out; @@ -114,11 +125,13 @@ while (cache->task) { rpc_exit(cache->task, 0); rpc_wake_up_task(cache->task); + nfs_unlock_flushd(); interruptible_sleep_on_timeout(&cache->request_wait, 1 * HZ); + nfs_lock_flushd(); } out: - unlock_kernel(); + nfs_unlock_flushd(); } int nfs_reqlist_alloc(struct nfs_server *server) @@ -183,11 +196,13 @@ } dprintk("NFS: %4d flushd back to sleep\n", task->tk_pid); + nfs_lock_flushd(); if (task->tk_action) { task->tk_timeout = NFS_FLUSHD_TIMEOUT; cache->runat = jiffies + task->tk_timeout; rpc_sleep_on(&flushd_queue, task, NULL, NULL); } + nfs_unlock_flushd(); } static void @@ -196,10 +211,13 @@ struct nfs_server *server; struct nfs_reqlist *cache; server = (struct nfs_server *) task->tk_calldata; + + nfs_lock_flushd(); cache = server->rw_requests; if (cache->task == task) cache->task = NULL; wake_up(&cache->request_wait); + nfs_unlock_flushd(); } diff -u --recursive --new-file linux-2.4.17-ping/fs/nfs/inode.c linux-2.4.17-rpc_bkl/fs/nfs/inode.c --- linux-2.4.17-ping/fs/nfs/inode.c Thu Dec 20 01:00:35 2001 +++ linux-2.4.17-rpc_bkl/fs/nfs/inode.c Thu Dec 20 01:01:13 2001 @@ -86,6 +86,9 @@ &nfs_rpcstat, }; +/* Spinlock to protect the NFS inode update */ +static spinlock_t nfs_inode_lock = SPIN_LOCK_UNLOCKED; + static inline unsigned long nfs_fattr_to_ino_t(struct nfs_fattr *fattr) { @@ -604,18 +607,30 @@ } /* + * Reset the read time on the local caches + */ +void +nfs_invalidate_caches(struct inode *inode) +{ + spin_lock(&nfs_inode_lock); + NFS_READTIME(inode) = jiffies - NFS_MAXATTRTIMEO(inode) - 1; + spin_unlock(&nfs_inode_lock); +} + +/* * Invalidate the local caches */ void nfs_zap_caches(struct inode *inode) { - NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); - NFS_ATTRTIMEO_UPDATE(inode) = jiffies; - invalidate_inode_pages(inode); + spin_lock(&nfs_inode_lock); + NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); + NFS_ATTRTIMEO_UPDATE(inode) = jiffies; memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); - NFS_CACHEINV(inode); + NFS_READTIME(inode) = jiffies - NFS_MAXATTRTIMEO(inode) - 1; + spin_unlock(&nfs_inode_lock); } /* @@ -842,7 +857,11 @@ nfs_revalidate(struct dentry *dentry) { struct inode *inode = dentry->d_inode; - return nfs_revalidate_inode(NFS_SERVER(inode), inode); + int status; + lock_kernel(); + status = nfs_revalidate_inode(NFS_SERVER(inode), inode); + unlock_kernel(); + return status; } /* @@ -886,13 +905,11 @@ struct rpc_auth *auth; struct rpc_cred *cred; - lock_kernel(); auth = NFS_CLIENT(inode)->cl_auth; cred = rpcauth_lookupcred(auth, 0); filp->private_data = cred; if (filp->f_mode & FMODE_WRITE) nfs_set_mmcred(inode, cred); - unlock_kernel(); return 0; } @@ -900,11 +917,9 @@ { struct rpc_cred *cred; - lock_kernel(); cred = nfs_file_cred(filp); if (cred) put_rpccred(cred); - unlock_kernel(); return 0; } @@ -921,7 +936,6 @@ dfprintk(PAGECACHE, "NFS: revalidating (%x/%Ld)\n", inode->i_dev, (long long)NFS_FILEID(inode)); - lock_kernel(); if (!inode || is_bad_inode(inode)) goto out_nowait; if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode) @@ -964,10 +978,22 @@ NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; wake_up(&inode->i_wait); out_nowait: - unlock_kernel(); return status; } +/** + * nfs_grow_isize - Extend inode->i_size + * @inode: inode + * @size: new file size + */ +void nfs_grow_isize(struct inode *inode, loff_t size) +{ + spin_lock(&nfs_inode_lock); + if (inode->i_size < size) + inode->i_size = size; + spin_unlock(&nfs_inode_lock); +} + /* * nfs_fattr_obsolete - Test if attribute data is newer than cached data * @inode: inode @@ -1041,6 +1067,7 @@ new_atime = nfs_time_to_secs(fattr->atime); /* Avoid races */ + spin_lock(&nfs_inode_lock); if (nfs_fattr_obsolete(inode, fattr)) goto out_nochange; @@ -1126,6 +1153,7 @@ NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; } + spin_unlock(&nfs_inode_lock); if (invalid) nfs_zap_caches(inode); @@ -1133,6 +1161,7 @@ out_nochange: if (new_atime - inode->i_atime > 0) inode->i_atime = new_atime; + spin_unlock(&nfs_inode_lock); return 0; out_changed: /* diff -u --recursive --new-file linux-2.4.17-ping/fs/nfs/read.c linux-2.4.17-rpc_bkl/fs/nfs/read.c --- linux-2.4.17-ping/fs/nfs/read.c Wed Dec 19 13:07:56 2001 +++ linux-2.4.17-rpc_bkl/fs/nfs/read.c Wed Dec 19 13:11:06 2001 @@ -113,11 +113,9 @@ inode->i_dev, (long long)NFS_FILEID(inode), (long long)offset, rsize, buffer); - lock_kernel(); result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, offset, rsize, buffer, &eof); nfs_refresh_inode(inode, &fattr); - unlock_kernel(); /* * Even if we had a partial success we can't mark the page @@ -272,9 +270,7 @@ rpc_clnt_sigmask(clnt, &oldset); rpc_call_setup(task, &msg, 0); - lock_kernel(); rpc_execute(task); - unlock_kernel(); rpc_clnt_sigunmask(clnt, &oldset); return 0; out_bad: diff -u --recursive --new-file linux-2.4.17-ping/fs/nfs/write.c linux-2.4.17-rpc_bkl/fs/nfs/write.c --- linux-2.4.17-ping/fs/nfs/write.c Wed Dec 19 13:07:56 2001 +++ linux-2.4.17-rpc_bkl/fs/nfs/write.c Wed Dec 19 13:11:06 2001 @@ -125,16 +125,18 @@ * under NFSv2 when the NFSv3 attribute patch is included. * For the moment, we just call nfs_refresh_inode(). */ -static __inline__ int +static inline int nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) { + int status; if ((fattr->valid & NFS_ATTR_FATTR) && !(fattr->valid & NFS_ATTR_WCC)) { fattr->pre_size = NFS_CACHE_ISIZE(inode); fattr->pre_mtime = NFS_CACHE_MTIME(inode); fattr->pre_ctime = NFS_CACHE_CTIME(inode); fattr->valid |= NFS_ATTR_WCC; } - return nfs_refresh_inode(inode, fattr); + status = nfs_refresh_inode(inode, fattr); + return status; } /* @@ -193,8 +195,7 @@ * If we've extended the file, update the inode * now so we don't invalidate the cache. */ - if (base > inode->i_size) - inode->i_size = base; + nfs_grow_isize(inode, base); } while (count); if (PageError(page)) @@ -225,9 +226,7 @@ nfs_unlock_request(req); nfs_strategy(inode); end = ((loff_t)page->index<i_size < end) - inode->i_size = end; - + nfs_grow_isize(inode, end); out: return status; } @@ -265,7 +264,6 @@ if (page->index >= end_index+1 || !offset) goto out; do_it: - lock_kernel(); if (NFS_SERVER(inode)->wsize >= PAGE_CACHE_SIZE && !IS_SYNC(inode)) { err = nfs_writepage_async(NULL, inode, page, 0, offset); if (err >= 0) @@ -275,7 +273,6 @@ if (err == offset) err = 0; } - unlock_kernel(); out: UnlockPage(page); return err; @@ -833,8 +830,7 @@ status = 0; end = ((loff_t)page->index<i_size < end) - inode->i_size = end; + nfs_grow_isize(inode, end); /* If we wrote past the end of the page. * Call the strategy routine so it can send out a bunch @@ -956,9 +952,7 @@ rpc_clnt_sigmask(clnt, &oldset); rpc_call_setup(task, &msg, 0); - lock_kernel(); rpc_execute(task); - unlock_kernel(); rpc_clnt_sigunmask(clnt, &oldset); return 0; out_bad: @@ -1182,9 +1176,7 @@ dprintk("NFS: %4d initiated commit call\n", task->tk_pid); rpc_clnt_sigmask(clnt, &oldset); rpc_call_setup(task, &msg, 0); - lock_kernel(); rpc_execute(task); - unlock_kernel(); rpc_clnt_sigunmask(clnt, &oldset); return 0; out_bad: diff -u --recursive --new-file linux-2.4.17-ping/include/linux/nfs_fs.h linux-2.4.17-rpc_bkl/include/linux/nfs_fs.h --- linux-2.4.17-ping/include/linux/nfs_fs.h Wed Dec 19 13:10:05 2001 +++ linux-2.4.17-rpc_bkl/include/linux/nfs_fs.h Wed Dec 19 13:23:07 2001 @@ -82,10 +82,7 @@ #define NFS_CACHE_MTIME(inode) ((inode)->u.nfs_i.read_cache_mtime) #define NFS_CACHE_ISIZE(inode) ((inode)->u.nfs_i.read_cache_isize) #define NFS_NEXTSCAN(inode) ((inode)->u.nfs_i.nextscan) -#define NFS_CACHEINV(inode) \ -do { \ - NFS_READTIME(inode) = jiffies - NFS_MAXATTRTIMEO(inode) - 1; \ -} while (0) +#define NFS_CACHEINV(inode) nfs_invalidate_caches(inode) #define NFS_ATTRTIMEO(inode) ((inode)->u.nfs_i.attrtimeo) #define NFS_MINATTRTIMEO(inode) \ (S_ISDIR(inode->i_mode)? NFS_SERVER(inode)->acdirmin \ @@ -149,12 +146,14 @@ * linux/fs/nfs/inode.c */ extern struct super_block *nfs_read_super(struct super_block *, void *, int); +extern void nfs_invalidate_caches(struct inode *); extern void nfs_zap_caches(struct inode *); extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *, struct nfs_fattr *); extern struct inode *nfs_fhget(struct dentry *, struct nfs_fh *, struct nfs_fattr *); extern int __nfs_refresh_inode(struct inode *, struct nfs_fattr *); +extern void nfs_grow_isize(struct inode *, loff_t); extern int nfs_revalidate(struct dentry *); extern int nfs_permission(struct inode *, int); extern int nfs_open(struct inode *, struct file *); diff -u --recursive --new-file linux-2.4.17-ping/net/sunrpc/sched.c linux-2.4.17-rpc_bkl/net/sunrpc/sched.c --- linux-2.4.17-ping/net/sunrpc/sched.c Thu Oct 11 17:12:52 2001 +++ linux-2.4.17-rpc_bkl/net/sunrpc/sched.c Wed Dec 19 13:11:07 2001 @@ -1052,7 +1052,6 @@ int rounds = 0; MOD_INC_USE_COUNT; - lock_kernel(); /* * Let our maker know we're running ... */