diff -urNp 2.4.19rc2/fs/lockd/clntproc.c 2.4.19rc2aa1/fs/lockd/clntproc.c --- 2.4.19rc2/fs/lockd/clntproc.c Tue Jan 22 18:54:59 2002 +++ 2.4.19rc2aa1/fs/lockd/clntproc.c Wed Jul 17 13:48:08 2002 @@ -569,11 +569,15 @@ nlmclnt_unlock_callback(struct rpc_task 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 @@ nlmclnt_cancel_callback(struct rpc_task } 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 -urNp 2.4.19rc2/fs/lockd/svc4proc.c 2.4.19rc2aa1/fs/lockd/svc4proc.c --- 2.4.19rc2/fs/lockd/svc4proc.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/lockd/svc4proc.c Wed Jul 17 13:48:08 2002 @@ -17,6 +17,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT @@ -503,7 +504,9 @@ nlm4svc_callback_exit(struct rpc_task *t 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 -urNp 2.4.19rc2/fs/lockd/svclock.c 2.4.19rc2aa1/fs/lockd/svclock.c --- 2.4.19rc2/fs/lockd/svclock.c Tue Jan 22 18:54:59 2002 +++ 2.4.19rc2aa1/fs/lockd/svclock.c Wed Jul 17 13:48:08 2002 @@ -576,9 +576,10 @@ nlmsvc_grant_callback(struct rpc_task *t 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 @@ nlmsvc_grant_callback(struct rpc_task *t block->b_incall = 0; nlm_release_host(call->a_host); + out: + unlock_kernel(); } /* diff -urNp 2.4.19rc2/fs/lockd/svcproc.c 2.4.19rc2aa1/fs/lockd/svcproc.c --- 2.4.19rc2/fs/lockd/svcproc.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/lockd/svcproc.c Wed Jul 17 13:48:08 2002 @@ -18,6 +18,7 @@ #include #include #include +#include #define NLMDBG_FACILITY NLMDBG_CLIENT @@ -531,7 +532,9 @@ nlmsvc_callback_exit(struct rpc_task *ta 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 -urNp 2.4.19rc2/fs/nfs/file.c 2.4.19rc2aa1/fs/nfs/file.c --- 2.4.19rc2/fs/nfs/file.c Mon Feb 25 22:05:08 2002 +++ 2.4.19rc2aa1/fs/nfs/file.c Wed Jul 17 13:48:08 2002 @@ -99,7 +99,9 @@ nfs_file_read(struct file * file, char * 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 @@ nfs_file_mmap(struct file * file, struct 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 @@ nfs_fsync(struct file *file, struct dent 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_prepare_write(struct file 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 @@ nfs_file_write(struct file *file, const 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 -urNp 2.4.19rc2/fs/nfs/flushd.c 2.4.19rc2aa1/fs/nfs/flushd.c --- 2.4.19rc2/fs/nfs/flushd.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/nfs/flushd.c Wed Jul 17 13:48:08 2002 @@ -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 @@ static int nfs_reqlist_init(struct nfs_s 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 @@ static int nfs_reqlist_init(struct nfs_s 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 @@ void nfs_reqlist_exit(struct nfs_server 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 @@ nfs_flushd(struct rpc_task *task) } 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 @@ nfs_flushd_exit(struct rpc_task *task) 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 -urNp 2.4.19rc2/fs/nfs/inode.c 2.4.19rc2aa1/fs/nfs/inode.c --- 2.4.19rc2/fs/nfs/inode.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/nfs/inode.c Wed Jul 17 13:48:15 2002 @@ -86,6 +86,9 @@ struct rpc_program nfs_program = { &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) { @@ -595,18 +598,30 @@ static int nfs_show_options(struct seq_f } /* + * 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); } /* @@ -821,7 +836,11 @@ int 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; } /* @@ -850,13 +869,11 @@ int nfs_open(struct inode *inode, struct 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; } @@ -864,11 +881,9 @@ int nfs_release(struct inode *inode, str { struct rpc_cred *cred; - lock_kernel(); cred = nfs_file_cred(filp); if (cred) put_rpccred(cred); - unlock_kernel(); return 0; } @@ -885,7 +900,6 @@ __nfs_revalidate_inode(struct nfs_server 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) @@ -928,10 +942,22 @@ out: 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 @@ -1004,6 +1030,7 @@ __nfs_refresh_inode(struct inode *inode, new_atime = nfs_time_to_secs(fattr->atime); /* Avoid races */ + spin_lock(&nfs_inode_lock); if (nfs_fattr_obsolete(inode, fattr)) goto out_nochange; @@ -1097,11 +1124,13 @@ __nfs_refresh_inode(struct inode *inode, NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode); NFS_ATTRTIMEO_UPDATE(inode) = jiffies; } + spin_unlock(&nfs_inode_lock); return 0; out_nochange: if (new_atime - inode->i_atime > 0) inode->i_atime = new_atime; + spin_unlock(&nfs_inode_lock); return 0; out_changed: /* diff -urNp 2.4.19rc2/fs/nfs/read.c 2.4.19rc2aa1/fs/nfs/read.c --- 2.4.19rc2/fs/nfs/read.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/nfs/read.c Wed Jul 17 13:48:08 2002 @@ -113,11 +113,9 @@ nfs_readpage_sync(struct file *file, str 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 @@ -273,9 +271,7 @@ nfs_pagein_one(struct list_head *head, s 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 -urNp 2.4.19rc2/fs/nfs/write.c 2.4.19rc2aa1/fs/nfs/write.c --- 2.4.19rc2/fs/nfs/write.c Wed Jul 17 13:28:43 2002 +++ 2.4.19rc2aa1/fs/nfs/write.c Wed Jul 17 13:48:08 2002 @@ -193,8 +193,7 @@ nfs_writepage_sync(struct file *file, st * 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 +224,7 @@ nfs_writepage_async(struct file *file, s 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; } @@ -259,7 +256,6 @@ nfs_writepage(struct page *page) 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) @@ -269,7 +265,6 @@ do_it: if (err == offset) err = 0; } - unlock_kernel(); out: UnlockPage(page); return err; @@ -833,8 +828,7 @@ nfs_updatepage(struct file *file, struct 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 +950,7 @@ nfs_flush_one(struct list_head *head, st 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 +1174,7 @@ nfs_commit_list(struct list_head *head, 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 -urNp 2.4.19rc2/include/linux/nfs_fs.h 2.4.19rc2aa1/include/linux/nfs_fs.h --- 2.4.19rc2/include/linux/nfs_fs.h Wed Jul 17 13:28:51 2002 +++ 2.4.19rc2aa1/include/linux/nfs_fs.h Wed Jul 17 13:48:08 2002 @@ -83,10 +83,7 @@ static inline struct nfs_inode_info *NFS #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 \ @@ -142,12 +139,14 @@ unsigned long page_index(struct page *pa * 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 -urNp 2.4.19rc2/net/sunrpc/sched.c 2.4.19rc2aa1/net/sunrpc/sched.c --- 2.4.19rc2/net/sunrpc/sched.c Wed Jul 17 13:28:51 2002 +++ 2.4.19rc2aa1/net/sunrpc/sched.c Wed Jul 17 13:48:08 2002 @@ -1050,7 +1050,6 @@ rpciod(void *ptr) int rounds = 0; MOD_INC_USE_COUNT; - lock_kernel(); /* * Let our maker know we're running ... */