diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/lockd/mon.c linux-2.2.14-nfsv3/fs/lockd/mon.c --- linux-2.2.14-nfsv3-0.20.8/fs/lockd/mon.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/lockd/mon.c Sun Apr 2 18:13:01 2000 @@ -34,7 +34,7 @@ * Common procedure for SM_MON/SM_UNMON calls */ static int -nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nlm_res *res) +nsm_mon_unmon(struct nlm_host *host, u32 proc, struct nsm_res *res) { struct rpc_clnt *clnt; int status; @@ -67,7 +67,7 @@ int nsm_monitor(struct nlm_host *host) { - struct nlm_res res; + struct nsm_res res; int status; dprintk("lockd: nsm_monitor(%s)\n", host->h_name); @@ -87,7 +87,7 @@ int nsm_unmonitor(struct nlm_host *host) { - struct nlm_res res; + struct nsm_res res; int status; dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name); diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/dir.c linux-2.2.14-nfsv3/fs/nfs/dir.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/dir.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/dir.c Tue Apr 18 13:03:54 2000 @@ -124,13 +124,15 @@ if (!p) return -EIO; for(;;) { + u64 cookie; p = (u8*)decode((__u32*)p, entry, plus); if (IS_ERR(p)) break; pg_offset = p - start; entry->prev = entry->offset; entry->offset = base + pg_offset; - if ((use_cookie ? entry->cookie : entry->offset) > offset) + cookie = use_cookie ? entry->cookie : entry->offset; + if (cookie > (u64)offset) break; if (loop_count++ > 200) { loop_count = 0; @@ -192,7 +194,7 @@ long res = 0; int loop_count = 0; - dfprintk(VFS, "NFS: search_cached_dirent_pages() searching for cookie %ld\n", offset); + dfprintk(VFS, "NFS: search_cached_dirent_pages() searching for cookie %Ld\n", (long long)offset); for (;;) { res = find_dirent_page(inode, offset, entry); if (res == -EAGAIN) { @@ -300,7 +302,7 @@ use_cookie = NFS_MONOTONE_COOKIES(inode), loop_count = 0; - dfprintk(VFS, "NFS: refetch_to_readdir() searching for cookie %ld\n", off); + dfprintk(VFS, "NFS: refetch_to_readdir() searching for cookie %Ld\n", (long long)off); *dirent = *entry; entry->page = NULL; @@ -314,8 +316,9 @@ res = search_cached_dirent_pages(inode, off, dirent); if (res >= 0) { + u64 cookie = use_cookie ? dirent->cookie : (u64)dirent->offset; /* Cookie was found */ - if ((use_cookie?dirent->cookie:dirent->offset) > off) { + if (cookie > (u64)off) { *entry = *dirent; dirent->page = NULL; break; @@ -347,6 +350,12 @@ plus = 0; res = 0; } + /* If we're using the page offset scheme, and the page cache + * is invalidated, we just restart reading at the next entry + * since the file position pointer is going to be screwed up + * anyway */ + if (!use_cookie && off > dirent->offset) + off = dirent->offset; } if (dirent->page) page_cache_release(dirent->page); @@ -368,8 +377,8 @@ *start; unsigned long base = page_offset(page), offset = entry->offset, - pg_offset, - fileid; + pg_offset; + ino_t fileid; int plus = NFS_USE_READDIRPLUS(inode), use_cookie = NFS_MONOTONE_COOKIES(inode), loop_count = 0, @@ -397,6 +406,12 @@ pg_offset = p - start; entry->prev = entry->offset; entry->offset = base + pg_offset; + /* Is the server violating our monotonicity assumption ? */ + if (use_cookie && entry->prev_cookie > entry->cookie) { + use_cookie = 0; + NFS_SERVER(inode)->flags |= NFS_NONMONOTONE_COOKIES; + file->f_pos = 0; + } if (loop_count++ > 200) { loop_count = 0; schedule(); diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/inode.c linux-2.2.14-nfsv3/fs/nfs/inode.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/inode.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/inode.c Tue Apr 18 18:33:52 2000 @@ -222,7 +222,7 @@ nfs_calc_block_size(u64 tsize) { off_t used = nfs_size_to_off_t(tsize); - return (used + 511) / 512; + return (used + 511) >> 9; } /* @@ -781,9 +781,9 @@ { struct super_block *sb = dentry->d_sb; - dprintk("NFS: nfs_fhget(%s/%s fileid=%lu)\n", + dprintk("NFS: nfs_fhget(%s/%s fileid=%Lu)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - (unsigned long) fattr->fileid); + (long long) fattr->fileid); /* Install the file handle in the dentry */ memcpy(NFS_FH(dentry), (u8*)fhandle, sizeof(*fhandle)); diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/nfs3proc.c linux-2.2.14-nfsv3/fs/nfs/nfs3proc.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/nfs3proc.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/nfs3proc.c Thu Mar 23 02:38:44 2000 @@ -167,7 +167,8 @@ unsigned long offset, unsigned int count, void *buffer, struct nfs_writeverf *verf) { - struct nfs_writeargs arg = { NFS_FH(dentry), offset, count, 1, 1, + struct nfs_writeargs arg = { NFS_FH(dentry), offset, count, + NFS_FILE_SYNC, 1, {{buffer, count}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} }; struct nfs_writeres res = { fattr, verf, 0 }; diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/proc.c linux-2.2.14-nfsv3/fs/nfs/proc.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/proc.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/proc.c Thu Mar 23 02:38:06 2000 @@ -163,7 +163,8 @@ unsigned long offset, unsigned int count, void *buffer, struct nfs_writeverf *verf) { - struct nfs_writeargs arg = {NFS_FH(dentry), offset, count, 1, 1, + struct nfs_writeargs arg = {NFS_FH(dentry), offset, count, + NFS_FILE_SYNC, 1, {{buffer, count}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}}; struct nfs_writeres res = {fattr, verf, count}; diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/read.c linux-2.2.14-nfsv3/fs/nfs/read.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/read.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/read.c Sun Mar 26 19:55:44 2000 @@ -124,6 +124,7 @@ result = NFS_CALL(read, inode, (dentry, &fattr, cred, flags, offset, chunk, buffer, &eof)); + nfs_refresh_inode(inode, &fattr); /* * Even if we had a partial success we can't mark the page @@ -148,10 +149,7 @@ io_error: /* Note: we don't refresh if the call returned error */ - if (result >= 0) { - if (refresh) - nfs_refresh_inode(inode, &fattr); - } else + if (result < 0) set_bit(PG_error, &page->flags); return result; } @@ -233,6 +231,8 @@ dprintk("NFS: %4d received callback for %d pages %lx, result %d\n", task->tk_pid, npages, page_address(*pages), result); + nfs_refresh_inode(inode, &req->ra_fattr); + i = 0; if (result >= 0) { count = req->ra_res.count; @@ -252,7 +252,6 @@ /* * Refresh before we set PG_uptodate in case of invalidation */ - nfs_refresh_inode(inode, &req->ra_fattr); for (; i < npages && count > 0; i++, count -= PAGE_CACHE_SIZE) { struct page *page = pages[i]; if (count < PAGE_CACHE_SIZE) @@ -358,7 +357,8 @@ struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; int error = 0, - rsize = NFS_SERVER(inode)->rsize; + rsize = NFS_SERVER(inode)->rsize, + rpages = NFS_SERVER(inode)->rpages; atomic_inc(&page->count); while (!nfs_lock_page(page)) @@ -370,7 +370,7 @@ /* * Try to flush any pending writes to the file */ - error = nfs_sync_file(inode, 0, page_offset(page), rsize, FLUSH_WAIT|FLUSH_STABLE); + error = nfs_sync_file(inode, 0, page_index(page), rpages, FLUSH_WAIT|FLUSH_STABLE); if (error < 0) goto out_unlock; diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/fs/nfs/write.c linux-2.2.14-nfsv3/fs/nfs/write.c --- linux-2.2.14-nfsv3-0.20.8/fs/nfs/write.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/fs/nfs/write.c Sun Mar 26 23:57:30 2000 @@ -77,6 +77,7 @@ struct nfs_write_data { struct rpc_task task; struct file *file; + struct rpc_cred *cred; struct nfs_writeargs args; /* argument struct */ struct nfs_writeres res; /* result struct */ struct nfs_fattr fattr; @@ -89,6 +90,7 @@ wb_list, *wb_list_head; struct file *wb_file; + struct rpc_cred *wb_cred; struct page *wb_page; /* page to write out */ struct wait_queue *wb_wait; /* wait queue */ unsigned long wb_timeout; /* when to write/commit */ @@ -179,9 +181,9 @@ struct nfs_fattr fattr; struct nfs_writeverf verifier; - dprintk("NFS: nfs_writepage_sync(%s/%s %d@%ld)\n", + dprintk("NFS: nfs_writepage_sync(%s/%s %d@%Ld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - count, page_offset(page) + offset); + count, (long long)(page_offset(page) + offset)); buffer = (u8 *) page_address(page) + offset; offset += page_offset(page); @@ -195,6 +197,7 @@ result = NFS_CALL(write, inode, (dentry, &fattr, cred, flags, offset, wsize, buffer, &verifier)); + nfs_write_attributes(inode, &fattr); if (result < 0) { /* Must mark the page invalid after I/O error */ @@ -218,10 +221,6 @@ } while (count); io_error: - /* Note: we don't refresh if the call failed (fattr invalid) */ - if (refresh && result >= 0) - nfs_write_attributes(inode, &fattr); - return written? written : result; } @@ -545,6 +544,7 @@ else req->wb_timeout = jiffies + NFS_WRITEBACK_DELAY; req->wb_file = file; + req->wb_cred = nfs_file_cred(file); file->f_count++; req->wb_count = 1; @@ -621,20 +621,18 @@ * Interruptible by signals only if mounted with intr flag. */ static int -nfs_wait_on_requests(struct inode *inode, struct file *file, unsigned long start, unsigned int count) +nfs_wait_on_requests(struct inode *inode, struct file *file, unsigned long idx_start, unsigned int npages) { struct list_head *p, *head; - unsigned long idx_start, idx_end; - unsigned int pages = 0; + unsigned long idx_end; + unsigned int res = 0; int error; - idx_start = start >> PAGE_CACHE_SHIFT; - if (count == 0) + if (npages == 0) idx_end = ~0; - else { - unsigned long idx_count = count >> PAGE_CACHE_SHIFT; - idx_end = idx_start + idx_count; - } + else + idx_end = idx_start + npages - 1; + spin_lock(&nfs_wreq_lock); head = &inode->u.nfs_i.writeback; p = head->next; @@ -661,10 +659,10 @@ return error; spin_lock(&nfs_wreq_lock); p = head->next; - pages++; + res++; } spin_unlock(&nfs_wreq_lock); - return pages; + return res; } /* @@ -723,19 +721,18 @@ } static int -nfs_scan_list(struct list_head *src, struct list_head *dst, struct file *file, unsigned long start, unsigned int count) +nfs_scan_list(struct list_head *src, struct list_head *dst, struct file *file, unsigned long idx_start, unsigned int npages) { struct list_head *p; struct nfs_page *req; - unsigned long idx_start, idx_end; - int pages; + unsigned long idx_end; + int res; - pages = 0; - idx_start = start >> PAGE_CACHE_SHIFT; - if (count == 0) + res = 0; + if (npages == 0) idx_end = ~0; else - idx_end = idx_start + (count >> PAGE_CACHE_SHIFT); + idx_end = idx_start + npages - 1; p = src->next; while (p != src) { unsigned long pg_idx; @@ -754,35 +751,35 @@ continue; nfs_list_remove_request(req); nfs_list_add_request(req, dst); - pages++; + res++; } - return pages; + return res; } static int -nfs_scan_dirty(struct inode *inode, struct list_head *dst, struct file *file, unsigned long start, unsigned int count) +nfs_scan_dirty(struct inode *inode, struct list_head *dst, struct file *file, unsigned long idx_start, unsigned int npages) { - int pages; + int res; spin_lock(&nfs_wreq_lock); - pages = nfs_scan_list(&inode->u.nfs_i.dirty, dst, file, start, count); - inode->u.nfs_i.ndirty -= pages; + res = nfs_scan_list(&inode->u.nfs_i.dirty, dst, file, idx_start, npages); + inode->u.nfs_i.ndirty -= res; if ((inode->u.nfs_i.ndirty == 0) != list_empty(&inode->u.nfs_i.dirty)) printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); spin_unlock(&nfs_wreq_lock); - return pages; + return res; } static int -nfs_scan_commit(struct inode *inode, struct list_head *dst, struct file *file, unsigned long start, unsigned int count) +nfs_scan_commit(struct inode *inode, struct list_head *dst, struct file *file, unsigned long idx_start, unsigned int npages) { - int pages; + int res; spin_lock(&nfs_wreq_lock); - pages = nfs_scan_list(&inode->u.nfs_i.commit, dst, file, start, count); - inode->u.nfs_i.ncommit -= pages; + res = nfs_scan_list(&inode->u.nfs_i.commit, dst, file, idx_start, npages); + inode->u.nfs_i.ncommit -= res; if ((inode->u.nfs_i.ncommit == 0) != list_empty(&inode->u.nfs_i.commit)) printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n"); spin_unlock(&nfs_wreq_lock); - return pages; + return res; } @@ -1025,7 +1022,7 @@ if (sync) { int error; - error = nfs_sync_file(inode, file, page_offset(page) + offset, count, FLUSH_SYNC|FLUSH_STABLE); + error = nfs_sync_file(inode, file, page_index(page), 1, FLUSH_SYNC|FLUSH_STABLE); if (error < 0 || (error = file->f_error) < 0) status = error; file->f_error = 0; @@ -1073,6 +1070,7 @@ } req = nfs_list_entry(data->pages.next); data->file = req->wb_file; + data->cred = req->wb_cred; data->args.fh = NFS_FH(req->wb_file->f_dentry); data->args.offset = page_offset(req->wb_page) + req->wb_offset; data->args.count = count; @@ -1141,7 +1139,7 @@ msg.rpc_proc = (NFS_PROTO(inode)->version == 3) ? NFS3PROC_WRITE : NFSPROC_WRITE; msg.rpc_argp = &data->args; msg.rpc_resp = &data->res; - msg.rpc_cred = nfs_file_cred(file); + msg.rpc_cred = data->cred; dprintk("NFS: %4d initiated write call (req %s/%s count %d nriov %d)\n", task->tk_pid, @@ -1229,10 +1227,10 @@ static unsigned long complain = 0; if (time_before(complain, jiffies)) { - printk(KERN_NOTICE "NFS: faulty NFSv3 server %s:" - " (committed = %d) != (stable = %d)\n", - NFS_SERVER(inode)->hostname, - resp->verf->committed, argp->stable); + dprintk("NFS: faulty NFSv3 server %s:" + " (committed = %d) != (stable = %d)\n", + NFS_SERVER(inode)->hostname, + resp->verf->committed, argp->stable); complain = jiffies + 300 * HZ; } } @@ -1244,11 +1242,11 @@ req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); - dprintk("NFS: write (%s/%s %d@%ld)", + dprintk("NFS: write (%s/%s %d@%Ld)", req->wb_file->f_dentry->d_parent->d_name.name, req->wb_file->f_dentry->d_name.name, req->wb_bytes, - page_offset(req->wb_page) + req->wb_offset); + (long long)(page_offset(req->wb_page) + req->wb_offset)); if (task->tk_status < 0) { req->wb_file->f_error = task->tk_status; @@ -1290,6 +1288,7 @@ start = ~0; req = nfs_list_entry(head->next); data->file = req->wb_file; + data->cred = req->wb_cred; dentry = data->file->f_dentry; inode = dentry->d_inode; while (!list_empty(head)) { @@ -1360,7 +1359,7 @@ msg.rpc_proc = NFS3PROC_COMMIT; msg.rpc_argp = &data->args; msg.rpc_resp = &data->res; - msg.rpc_cred = nfs_file_cred(file); + msg.rpc_cred = data->cred; dprintk("NFS: %4d initiated commit call\n", task->tk_pid); rpc_clnt_sigmask(clnt, &oldset); @@ -1426,34 +1425,34 @@ } } -int nfs_flush_file(struct inode *inode, struct file *file, unsigned long start, - unsigned int count, int how) +int nfs_flush_file(struct inode *inode, struct file *file, unsigned long idx_start, + unsigned int npages, int how) { LIST_HEAD(head); - int pages, + int res, error = 0; - pages = nfs_scan_dirty(inode, &head, file, start, count); - if (pages) + res = nfs_scan_dirty(inode, &head, file, idx_start, npages); + if (res) error = nfs_flush_list(inode, &head, how); if (error < 0) return error; - return pages; + return res; } -int nfs_commit_file(struct inode *inode, struct file *file, unsigned long start, - unsigned int count, int how) +int nfs_commit_file(struct inode *inode, struct file *file, unsigned long idx_start, + unsigned int npages, int how) { LIST_HEAD(head); - int pages, + int res, error = 0; - pages = nfs_scan_commit(inode, &head, file, start, count); - if (pages) + res = nfs_scan_commit(inode, &head, file, idx_start, npages); + if (res) error = nfs_commit_list(&head, how); if (error < 0) return error; - return pages; + return res; } int nfs_flush_timeout(struct inode *inode, int how) @@ -1486,8 +1485,8 @@ return pages; } -int nfs_sync_file(struct inode *inode, struct file *file, unsigned long start, - unsigned int count, int how) +int nfs_sync_file(struct inode *inode, struct file *file, unsigned long idx_start, + unsigned int npages, int how) { int error, wait; @@ -1501,11 +1500,11 @@ do { error = 0; if (wait) - error = nfs_wait_on_requests(inode, file, start, count); + error = nfs_wait_on_requests(inode, file, idx_start, npages); if (error == 0) - error = nfs_flush_file(inode, file, start, count, how); + error = nfs_flush_file(inode, file, idx_start, npages, how); if (error == 0) - error = nfs_commit_file(inode, file, start, count, how); + error = nfs_commit_file(inode, file, idx_start, npages, how); } while (error > 0); return error; } diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/include/linux/nfs_fs.h linux-2.2.14-nfsv3/include/linux/nfs_fs.h --- linux-2.2.14-nfsv3-0.20.8/include/linux/nfs_fs.h Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/include/linux/nfs_fs.h Tue Apr 11 09:02:30 2000 @@ -331,7 +331,7 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page) { - int error = nfs_sync_file(inode, 0, page->offset, PAGE_CACHE_SIZE, FLUSH_WAIT | FLUSH_STABLE); + int error = nfs_sync_file(inode, 0, page_index(page), 1, FLUSH_WAIT | FLUSH_STABLE); return (error < 0) ? error : 0; } @@ -402,10 +402,10 @@ return (size > (__u64)LONG_MAX) ? (off_t)LONG_MAX : (off_t) size; } -static inline unsigned long +static inline ino_t nfs_fileid_to_ino_t(u64 fileid) { - unsigned long ino = (unsigned long) fileid; + ino_t ino = (unsigned long) fileid; if (sizeof(unsigned long) < sizeof(u64)) ino ^= fileid >> (sizeof(u64)-sizeof(unsigned long)) * 8; return ino; diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/include/linux/nfs_fs_i.h linux-2.2.14-nfsv3/include/linux/nfs_fs_i.h --- linux-2.2.14-nfsv3-0.20.8/include/linux/nfs_fs_i.h Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/include/linux/nfs_fs_i.h Tue Apr 11 08:58:45 2000 @@ -83,7 +83,7 @@ #define NFS_INO_INVALIDATE 0x0008 /* zap cache on next occasion */ #define NFS_IS_SNAPSHOT 0x0010 /* a snapshot file */ #define NFS_INO_STALE 0x0020 /* We suspect inode is stale */ -#define NFS_INO_FLUSH 0x0020 /* inode is due for flushing */ +#define NFS_INO_FLUSH 0x0040 /* inode is due for flushing */ /* * NFS ACL info. diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/net/sunrpc/clnt.c linux-2.2.14-nfsv3/net/sunrpc/clnt.c --- linux-2.2.14-nfsv3-0.20.8/net/sunrpc/clnt.c Tue Apr 11 18:14:55 2000 +++ linux-2.2.14-nfsv3/net/sunrpc/clnt.c Thu Mar 23 02:19:32 2000 @@ -719,10 +719,11 @@ */ if (task->tk_client->cl_prog == 100003 && (ntohl(*p) == NFSERR_ACCES || ntohl(*p) == NFSERR_PERM)) { - if (RPC_IS_SETUID(task) && (task->tk_suid_retry)--) { + if (RPC_IS_SETUID(task) && task->tk_suid_retry) { dprintk("RPC: %4d retry squashed uid\n", task->tk_pid); task->tk_flags ^= RPC_CALL_REALUID; task->tk_action = call_encode; + task->tk_suid_retry--; return; } } @@ -810,8 +811,9 @@ switch ((n = ntohl(*p++))) { case RPC_AUTH_REJECTEDCRED: case RPC_AUTH_REJECTEDVERF: - if (!task->tk_cred_retry--) + if (!task->tk_cred_retry) break; + task->tk_cred_retry--; dprintk("RPC: %4d call_verify: retry stale creds\n", task->tk_pid); rpcauth_invalcred(task); @@ -820,8 +822,9 @@ case RPC_AUTH_BADCRED: case RPC_AUTH_BADVERF: /* possibly garbled cred/verf? */ - if (!task->tk_garb_retry--) + if (!task->tk_garb_retry) break; + task->tk_garb_retry--; dprintk("RPC: %4d call_verify: retry garbled creds\n", task->tk_pid); task->tk_action = call_encode; @@ -855,9 +858,10 @@ garbage: dprintk("RPC: %4d call_verify: server saw garbage\n", task->tk_pid); task->tk_client->cl_stats->rpcgarbage++; - if (task->tk_garb_retry--) { + if (task->tk_garb_retry) { printk(KERN_WARNING "RPC: garbage, retrying %4d\n", task->tk_pid); task->tk_action = call_encode; + task->tk_garb_retry--; return NULL; } printk(KERN_WARNING "RPC: garbage, exit EIO\n"); diff -u --recursive --new-file linux-2.2.14-nfsv3-0.20.8/net/sunrpc/xprt.c linux-2.2.14-nfsv3/net/sunrpc/xprt.c --- linux-2.2.14-nfsv3-0.20.8/net/sunrpc/xprt.c Tue Apr 11 18:14:56 2000 +++ linux-2.2.14-nfsv3/net/sunrpc/xprt.c Wed Mar 22 13:31:19 2000 @@ -415,15 +415,15 @@ return; } - spin_lock_irqsave(&xprt_sock_lock, oldflags); + spin_lock(&xprt_lock); if (xprt->connecting) { task->tk_timeout = 0; rpc_sleep_on(&xprt->reconn, task, NULL, NULL); - spin_unlock_irqrestore(&xprt_sock_lock, oldflags); + spin_unlock(&xprt_lock); return; } xprt->connecting = 1; - spin_unlock_irqrestore(&xprt_sock_lock, oldflags); + spin_unlock(&xprt_lock); status = -ENOTCONN; if (!inet) { @@ -471,12 +471,14 @@ spin_unlock_irqrestore(&xprt_sock_lock, oldflags); } defer: + spin_lock(&xprt_lock); xprt->connecting = 0; if (status < 0) { rpc_delay(task, 5*HZ); task->tk_status = -ENOTCONN; } rpc_wake_up(&xprt->reconn); + spin_unlock(&xprt_lock); } /* @@ -491,9 +493,10 @@ dprintk("RPC: %4d xprt_reconn_timeout %d\n", task->tk_pid, task->tk_status); - /* Did we time out? */ + spin_lock(&xprt_lock); xprt->connecting = 0; rpc_wake_up(&xprt->reconn); + spin_unlock(&xprt_lock); } /* @@ -1048,9 +1051,8 @@ { struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; struct rpc_rqst *req = task->tk_rqstp; - unsigned long oldflags; - spin_lock_irqsave(&xprt_sock_lock, oldflags); + spin_lock(&xprt_lock); if (xprt->snd_task && xprt->snd_task != task) { dprintk("RPC: %4d TCP write queue full (task %d)\n", task->tk_pid, xprt->snd_task->tk_pid); @@ -1064,7 +1066,7 @@ #endif req->rq_bytes_sent = 0; } - spin_unlock_irqrestore(&xprt_sock_lock, oldflags); + spin_unlock(&xprt_lock); return xprt->snd_task == task; } @@ -1075,13 +1077,12 @@ xprt_up_transmit(struct rpc_task *task) { struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; - unsigned long oldflags; if (xprt->snd_task && xprt->snd_task == task) { - spin_lock_irqsave(&xprt_sock_lock, oldflags); + spin_lock(&xprt_lock); xprt->snd_task = NULL; rpc_wake_up_next(&xprt->sending); - spin_unlock_irqrestore(&xprt_sock_lock, oldflags); + spin_unlock(&xprt_lock); } } @@ -1520,8 +1521,8 @@ goto failed; } - /* If the caller has root privs, bind to a reserved port */ - if (!current->fsuid && xprt_bindresvport(sock) < 0) + /* If the caller has the capability, bind to a reserved port */ + if (capable(CAP_NET_BIND_SERVICE) && xprt_bindresvport(sock) < 0) goto failed; return sock;