Messages in this thread Patch in this message | | | Date | Wed, 5 May 1999 18:50:28 +0200 (CEST) | Subject | Re: NFS - rpcauth_gc_credcache looping | From | Trond Myklebust <> |
| |
>>>>> " " == Ben Blakely <brb@webserve.net> writes:
> Hi, I've tried both of the patches you sent (the vanilla 2.2.7 > and 2.2.7-ac1), and had mixed results, but I think I'm in good > shape now. Things seem to be happy now using the regular 2.2.7 > with your patch, and we had just been using the ac patches to > get around the nfs problems. At any rate, thanks for the > reply. Below are some more details:
Arrgh! I seem to have mangled the diffs. The appended patches have the correct modifications to fs/nfs/proc.c
Apologies, Trond
diff -u --recursive --new-file linux-2.2.7/fs/lockd/clntproc.c linux-2.2.7-patched/fs/lockd/clntproc.c --- linux-2.2.7/fs/lockd/clntproc.c Wed Feb 17 18:44:33 1999 +++ linux-2.2.7-patched/fs/lockd/clntproc.c Wed May 5 17:11:19 1999 @@ -220,11 +220,16 @@ struct rpc_clnt *clnt; struct nlm_args *argp = &req->a_args; struct nlm_res *resp = &req->a_res; + struct file *filp = argp->lock.fl.fl_file; + struct rpc_cred *cred = NULL; int status; dprintk("lockd: call procedure %s on %s\n", nlm_procname(proc), host->h_name); + if (filp) + cred = NFS_FILE_CRED(filp); + do { if (host->h_reclaiming && !argp->reclaim) { interruptible_sleep_on(&host->h_gracewait); @@ -236,7 +241,8 @@ return -ENOLCK; /* Perform the RPC call. If an error occurs, try again */ - if ((status = rpc_call(clnt, proc, argp, resp, 0)) < 0) { + if ((status = rpc_do_call(clnt, cred, proc, argp, resp, 0, + NULL, NULL)) < 0) { dprintk("lockd: rpc_call returned error %d\n", -status); switch (status) { case -EPROTONOSUPPORT: @@ -295,6 +301,8 @@ struct rpc_clnt *clnt; struct nlm_args *argp = &req->a_args; struct nlm_res *resp = &req->a_res; + struct file *filp = argp->lock.fl.fl_file; + struct rpc_cred *cred = NULL; int status; dprintk("lockd: call procedure %s on %s (async)\n", @@ -304,8 +312,11 @@ if ((clnt = nlm_bind_host(host)) == NULL) return -ENOLCK; + if (filp) + cred = NFS_FILE_CRED(filp); + /* bootstrap and kick off the async RPC call */ - status = rpc_do_call(clnt, proc, argp, resp, RPC_TASK_ASYNC, + status = rpc_do_call(clnt, cred, proc, argp, resp, RPC_TASK_ASYNC, callback, req); /* If the async call is proceeding, increment host refcount */ diff -u --recursive --new-file linux-2.2.7/fs/nfs/dir.c linux-2.2.7-patched/fs/nfs/dir.c --- linux-2.2.7/fs/nfs/dir.c Sat Apr 24 21:45:37 1999 +++ linux-2.2.7-patched/fs/nfs/dir.c Wed May 5 17:11:19 1999 @@ -26,6 +26,8 @@ #include <linux/mm.h> #include <linux/sunrpc/types.h> #include <linux/nfs_fs.h> +#include <linux/sunrpc/auth.h> +#include <linux/sunrpc/clnt.h> #include <asm/segment.h> /* for fs functions */ @@ -51,6 +53,8 @@ static int nfs_safe_remove(struct dentry *); +static int nfs_dir_open(struct inode *, struct file *); +static int nfs_dir_release(struct inode *, struct file *); static ssize_t nfs_dir_read(struct file *, char *, size_t, loff_t *); static int nfs_readdir(struct file *, void *, filldir_t); static struct dentry *nfs_lookup(struct inode *, struct dentry *); @@ -72,9 +76,9 @@ NULL, /* select - default */ NULL, /* ioctl - default */ NULL, /* mmap */ - NULL, /* no special open is needed */ + nfs_dir_open, /* open */ NULL, /* flush */ - NULL, /* no special release code */ + nfs_dir_release, /* release */ NULL /* fsync */ }; @@ -101,6 +105,27 @@ nfs_revalidate, /* revalidate */ }; +static int +nfs_dir_open(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + NFS_FILE_CRED(filp) = rpcauth_lookupcred(auth, 0); + return 0; +} + +static int +nfs_dir_release(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + if (NFS_FILE_CRED(filp)) { + rpcauth_releasecred(auth, NFS_FILE_CRED(filp)); + NFS_FILE_CRED(filp) = NULL; + } + return 0; +} + static ssize_t nfs_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos) { @@ -124,6 +149,7 @@ { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; + struct rpc_cred *cred = NFS_FILE_CRED(filp); static struct wait_queue *readdir_wait = NULL; struct wait_queue **waitp = NULL; struct nfs_dirent *cache, *free; @@ -239,7 +265,7 @@ } result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(dentry), - cookie, PAGE_SIZE, cache->entry); + cred, cookie, PAGE_SIZE, cache->entry); if (result <= 0) goto done; cache->size = result; diff -u --recursive --new-file linux-2.2.7/fs/nfs/file.c linux-2.2.7-patched/fs/nfs/file.c --- linux-2.2.7/fs/nfs/file.c Sat Apr 24 21:45:37 1999 +++ linux-2.2.7-patched/fs/nfs/file.c Wed May 5 17:11:19 1999 @@ -26,12 +26,16 @@ #include <linux/malloc.h> #include <linux/pagemap.h> #include <linux/lockd/bind.h> +#include <linux/sunrpc/auth.h> +#include <linux/sunrpc/clnt.h> #include <asm/segment.h> #include <asm/system.h> #define NFSDBG_FACILITY NFSDBG_FILE +static int nfs_file_open(struct inode *, struct file *); +static int nfs_file_release(struct inode *, struct file *); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_read(struct file *, char *, size_t, loff_t *); static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *); @@ -46,9 +50,9 @@ NULL, /* select - default */ NULL, /* ioctl - default */ nfs_file_mmap, /* mmap */ - NULL, /* no special open is needed */ + nfs_file_open, /* open */ nfs_file_flush, /* flush */ - NULL, /* release */ + nfs_file_release, /* release */ nfs_fsync, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ @@ -102,6 +106,27 @@ file->f_error = 0; } return status; +} + +static int +nfs_file_open(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + NFS_FILE_CRED(filp) = rpcauth_lookupcred(auth, 0); + return 0; +} + +static int +nfs_file_release(struct inode *inode, struct file *filp) +{ + struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth; + + if (NFS_FILE_CRED(filp)) { + rpcauth_releasecred(auth, NFS_FILE_CRED(filp)); + NFS_FILE_CRED(filp) = NULL; + } + return 0; } static ssize_t diff -u --recursive --new-file linux-2.2.7/fs/nfs/proc.c linux-2.2.7-patched/fs/nfs/proc.c --- linux-2.2.7/fs/nfs/proc.c Tue Jan 13 19:03:40 1998 +++ linux-2.2.7-patched/fs/nfs/proc.c Wed May 5 17:41:03 1999 @@ -109,7 +109,8 @@ } int -nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle, int swap, +nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, int swap, unsigned long offset, unsigned int count, void *buffer, struct nfs_fattr *fattr) { @@ -118,14 +119,15 @@ int status; dprintk("NFS call read %d @ %ld\n", count, offset); - status = rpc_call(server->client, NFSPROC_READ, &arg, &res, - swap? NFS_RPC_SWAPFLAGS : 0); + status = rpc_do_call(server->client, cred, NFSPROC_READ, &arg, &res, + swap? NFS_RPC_SWAPFLAGS : 0, NULL, NULL); dprintk("NFS reply read: %d\n", status); return status; } int -nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle, int swap, +nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, int swap, unsigned long offset, unsigned int count, const void *buffer, struct nfs_fattr *fattr) { @@ -133,8 +135,9 @@ int status; dprintk("NFS call write %d @ %ld\n", count, offset); - status = rpc_call(server->client, NFSPROC_WRITE, &arg, fattr, - swap? (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) : 0); + status = rpc_do_call(server->client, cred, NFSPROC_WRITE, &arg, fattr, + swap? (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) : 0, + NULL, NULL); dprintk("NFS reply read: %d\n", status); return status < 0? status : count; } @@ -241,6 +244,7 @@ */ int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, u32 cookie, unsigned int size, __u32 *entry) { struct nfs_readdirargs arg; @@ -282,7 +286,8 @@ res.bufsiz = size; dprintk("NFS call readdir %d\n", cookie); - status = rpc_call(server->client, NFSPROC_READDIR, &arg, &res, 0); + status = rpc_do_call(server->client, cred, + NFSPROC_READDIR, &arg, &res, 0, NULL, NULL); dprintk("NFS reply readdir: %d\n", status); free_page((unsigned long) buffer); out: diff -u --recursive --new-file linux-2.2.7/fs/nfs/read.c linux-2.2.7-patched/fs/nfs/read.c --- linux-2.2.7/fs/nfs/read.c Tue Dec 22 18:37:43 1998 +++ linux-2.2.7-patched/fs/nfs/read.c Wed May 5 17:11:19 1999 @@ -66,7 +66,8 @@ * Read a page synchronously. */ static int -nfs_readpage_sync(struct dentry *dentry, struct inode *inode, struct page *page) +nfs_readpage_sync(struct dentry *dentry, struct inode *inode, + struct rpc_cred *cred, struct page *page) { struct nfs_rreq rqst; unsigned long offset = page->offset; @@ -90,8 +91,9 @@ /* Set up arguments and perform rpc call */ nfs_readreq_setup(&rqst, NFS_FH(dentry), offset, buffer, rsize); - result = rpc_call(NFS_CLIENT(inode), NFSPROC_READ, - &rqst.ra_args, &rqst.ra_res, flags); + result = rpc_do_call(NFS_CLIENT(inode), cred, + NFSPROC_READ, &rqst.ra_args, &rqst.ra_res, + flags, NULL, NULL); /* * Even if we had a partial success we can't mark the page @@ -165,7 +167,7 @@ static inline int nfs_readpage_async(struct dentry *dentry, struct inode *inode, - struct page *page) + struct rpc_cred *cred, struct page *page) { unsigned long address = page_address(page); struct nfs_rreq *req; @@ -190,7 +192,7 @@ /* Start the async call */ dprintk("NFS: executing async READ request.\n"); - result = rpc_do_call(NFS_CLIENT(inode), NFSPROC_READ, + result = rpc_do_call(NFS_CLIENT(inode), cred, NFSPROC_READ, &req->ra_args, &req->ra_res, flags, nfs_readpage_result, req); if (result < 0) @@ -223,8 +225,9 @@ int nfs_readpage(struct file *file, struct page *page) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; + struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_inode; + struct rpc_cred *cred = NFS_FILE_CRED(file); int error; dprintk("NFS: nfs_readpage (%p %ld@%ld)\n", @@ -246,11 +249,11 @@ error = -1; if (!IS_SWAPFILE(inode) && !PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_SIZE) - error = nfs_readpage_async(dentry, inode, page); + error = nfs_readpage_async(dentry, inode, cred, page); if (error >= 0) goto out; - error = nfs_readpage_sync(dentry, inode, page); + error = nfs_readpage_sync(dentry, inode, cred, page); if (error < 0 && IS_SWAPFILE(inode)) printk("Aiee.. nfs swap-in of page failed!\n"); goto out_free; diff -u --recursive --new-file linux-2.2.7/fs/nfs/write.c linux-2.2.7-patched/fs/nfs/write.c --- linux-2.2.7/fs/nfs/write.c Wed Mar 3 20:17:02 1999 +++ linux-2.2.7-patched/fs/nfs/write.c Wed May 5 17:11:19 1999 @@ -86,6 +86,7 @@ */ static int nfs_writepage_sync(struct dentry *dentry, struct inode *inode, + struct rpc_cred *cred, struct page *page, unsigned long offset, unsigned int count) { unsigned int wsize = NFS_SERVER(inode)->wsize; @@ -105,6 +106,7 @@ wsize = count; result = nfs_proc_write(NFS_DSERVER(dentry), NFS_FH(dentry), + cred, IS_SWAPFILE(inode), offset, wsize, buffer, &fattr); @@ -284,7 +286,15 @@ task->tk_calldata = wreq; task->tk_action = nfs_wback_begin; - rpcauth_lookupcred(task); /* Obtain user creds */ + if (task->tk_status < 0) + goto out_req; + + task->tk_cred = NFS_FILE_CRED(file); + if (task->tk_cred) + rpcauth_holdcred(task); + else + rpcauth_bindcred(task); /* Obtain user creds */ + if (task->tk_status < 0) goto out_req; @@ -397,7 +407,9 @@ nfs_writepage(struct file * file, struct page *page) { struct dentry *dentry = file->f_dentry; - return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE); + struct rpc_cred *cred = NFS_FILE_CRED(file); + return nfs_writepage_sync(dentry, dentry->d_inode, cred, + page, 0, PAGE_SIZE); } /* @@ -438,7 +450,8 @@ * page synchronously. */ if (NFS_SERVER(inode)->wsize < PAGE_SIZE) - return nfs_writepage_sync(dentry, inode, page, offset, count); + return nfs_writepage_sync(dentry, inode, NFS_FILE_CRED(file), + page, offset, count); /* Create the write request. */ req = create_write_request(file, page, offset, count); diff -u --recursive --new-file linux-2.2.7/include/linux/nfs_fs.h linux-2.2.7-patched/include/linux/nfs_fs.h --- linux-2.2.7/include/linux/nfs_fs.h Tue Apr 27 18:56:22 1999 +++ linux-2.2.7-patched/include/linux/nfs_fs.h Wed May 5 17:21:03 1999 @@ -80,6 +80,8 @@ #define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATE) #define NFS_WRITEBACK(inode) ((inode)->u.nfs_i.writeback) +#define NFS_FILE_CRED(filp) ((struct rpc_cred*)((filp)->private_data)) + /* * These are the default flags for swap requests */ @@ -143,9 +145,11 @@ void **p0, char **string, unsigned int *len, unsigned int maxlen); extern int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, int swap, unsigned long offset, unsigned int count, void *buffer, struct nfs_fattr *fattr); extern int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, int swap, unsigned long offset, unsigned int count, const void *buffer, struct nfs_fattr *fattr); extern int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir, @@ -167,6 +171,7 @@ extern int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name); extern int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle, + struct rpc_cred *cred, u32 cookie, unsigned int size, __u32 *entry); extern int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *res); diff -u --recursive --new-file linux-2.2.7/include/linux/sunrpc/auth.h linux-2.2.7-patched/include/linux/sunrpc/auth.h --- linux-2.2.7/include/linux/sunrpc/auth.h Tue Apr 27 18:56:43 1999 +++ linux-2.2.7-patched/include/linux/sunrpc/auth.h Wed May 5 17:34:37 1999 @@ -64,10 +64,10 @@ struct rpc_auth * (*create)(struct rpc_clnt *); void (*destroy)(struct rpc_auth *); - struct rpc_cred * (*crcreate)(struct rpc_task *); + struct rpc_cred * (*crcreate)(int); void (*crdestroy)(struct rpc_cred *); - int (*crmatch)(struct rpc_task *, struct rpc_cred*); + int (*crmatch)(struct rpc_cred *, int); u32 * (*crmarshal)(struct rpc_task *, u32 *, int); int (*crrefresh)(struct rpc_task *); u32 * (*crvalidate)(struct rpc_task *, u32 *); @@ -83,10 +83,14 @@ int rpcauth_unregister(struct rpc_authops *); struct rpc_auth * rpcauth_create(unsigned int, struct rpc_clnt *); void rpcauth_destroy(struct rpc_auth *); -struct rpc_cred * rpcauth_lookupcred(struct rpc_task *); +struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); +struct rpc_cred * rpcauth_bindcred(struct rpc_task *); void rpcauth_holdcred(struct rpc_task *); -void rpcauth_releasecred(struct rpc_task *); -int rpcauth_matchcred(struct rpc_task *, struct rpc_cred *); +void rpcauth_releasecred(struct rpc_auth *, + struct rpc_cred *); +void rpcauth_unbindcred(struct rpc_task *); +int rpcauth_matchcred(struct rpc_auth *, + struct rpc_cred *, int); u32 * rpcauth_marshcred(struct rpc_task *, u32 *); u32 * rpcauth_checkverf(struct rpc_task *, u32 *); int rpcauth_refreshcred(struct rpc_task *); diff -u --recursive --new-file linux-2.2.7/include/linux/sunrpc/clnt.h linux-2.2.7-patched/include/linux/sunrpc/clnt.h --- linux-2.2.7/include/linux/sunrpc/clnt.h Tue Apr 27 18:56:46 1999 +++ linux-2.2.7-patched/include/linux/sunrpc/clnt.h Wed May 5 17:34:37 1999 @@ -117,15 +117,15 @@ void *argp, void *resp, int flags); void rpc_call_setup(struct rpc_task *task, u32 proc, void *argp, void *resp, int flags); -int rpc_do_call(struct rpc_clnt *clnt, u32 proc, - void *argp, void *resp, int flags, +int rpc_do_call(struct rpc_clnt *clnt, struct rpc_cred *cred, + u32 proc, void *argp, void *resp, int flags, rpc_action callback, void *clntdata); void rpc_restart_call(struct rpc_task *); void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset); void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); #define rpc_call(clnt, proc, argp, resp, flags) \ - rpc_do_call(clnt, proc, argp, resp, flags, NULL, NULL) + rpc_do_call(clnt, NULL, proc, argp, resp, flags, NULL, NULL) extern __inline__ void rpc_set_timeout(struct rpc_clnt *clnt, unsigned int retr, unsigned long incr) diff -u --recursive --new-file linux-2.2.7/net/sunrpc/auth.c linux-2.2.7-patched/net/sunrpc/auth.c --- linux-2.2.7/net/sunrpc/auth.c Mon Mar 22 17:00:15 1999 +++ linux-2.2.7-patched/net/sunrpc/auth.c Wed May 5 17:11:19 1999 @@ -78,6 +78,15 @@ auth->au_nextgc = jiffies + (auth->au_expire >> 1); } +static inline void +rpcauth_crdestroy(struct rpc_auth *auth, struct rpc_cred *cred) +{ + if (auth->au_ops->crdestroy) + auth->au_ops->crdestroy(cred); + else + rpc_free(cred); +} + /* * Clear the RPC credential cache */ @@ -107,17 +116,14 @@ rpcauth_gc_credcache(struct rpc_auth *auth) { struct rpc_cred **q, *cred, *free = NULL; - int i, safe = 0; + int i; dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); for (i = 0; i < RPC_CREDCACHE_NR; i++) { q = &auth->au_credcache[i]; while ((cred = *q) != NULL) { - if (++safe > 500) { - printk("RPC: rpcauth_gc_credcache looping!\n"); - break; - } - if (!cred->cr_count && time_before(cred->cr_expire, jiffies)) { + if (!cred->cr_count && + time_before(cred->cr_expire, jiffies)) { *q = cred->cr_next; cred->cr_next = free; free = cred; @@ -128,7 +134,7 @@ } while ((cred = free) != NULL) { free = cred->cr_next; - rpc_free(cred); + rpcauth_crdestroy(auth, cred); } auth->au_nextgc = jiffies + auth->au_expire; } @@ -136,7 +142,7 @@ /* * Insert credential into cache */ -inline void +void rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { int nr; @@ -144,39 +150,43 @@ nr = (cred->cr_uid % RPC_CREDCACHE_NR); cred->cr_next = auth->au_credcache[nr]; auth->au_credcache[nr] = cred; - cred->cr_expire = jiffies + auth->au_expire; - cred->cr_count++; } /* * Look up a process' credentials in the authentication cache */ static struct rpc_cred * -rpcauth_lookup_credcache(struct rpc_task *task) +rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) { - struct rpc_auth *auth = task->tk_auth; struct rpc_cred **q, *cred = NULL; - int nr; + int nr = 0; - nr = RPC_DO_ROOTOVERRIDE(task)? 0 : (current->uid % RPC_CREDCACHE_NR); + if (!(taskflags & RPC_TASK_ROOTCREDS)) + nr = current->uid % RPC_CREDCACHE_NR; if (time_before(auth->au_nextgc, jiffies)) rpcauth_gc_credcache(auth); q = &auth->au_credcache[nr]; while ((cred = *q) != NULL) { - if (auth->au_ops->crmatch(task, cred)) { + if (!(cred->cr_flags & RPCAUTH_CRED_DEAD) && + auth->au_ops->crmatch(cred, taskflags)) { *q = cred->cr_next; break; } q = &cred->cr_next; } - if (!cred) - cred = auth->au_ops->crcreate(task); + if (!cred) { + cred = auth->au_ops->crcreate(taskflags); + if (cred) + rpcauth_insert_credcache(auth, cred); + } - if (cred) - rpcauth_insert_credcache(auth, cred); + if (cred) { + cred->cr_count++; + cred->cr_expire = jiffies + auth->au_expire; + } return (struct rpc_cred *) cred; } @@ -184,7 +194,7 @@ /* * Remove cred handle from cache */ -static inline void +static void rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred) { struct rpc_cred **q, *cr; @@ -195,6 +205,7 @@ while ((cr = *q) != NULL) { if (cred == cr) { *q = cred->cr_next; + cred->cr_next = NULL; return; } q = &cred->cr_next; @@ -202,21 +213,32 @@ } struct rpc_cred * -rpcauth_lookupcred(struct rpc_task *task) +rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) +{ + dprintk("RPC: looking up %s cred\n", + auth->au_ops->au_name); + return rpcauth_lookup_credcache(auth, taskflags); +} + +struct rpc_cred * +rpcauth_bindcred(struct rpc_task *task) { + struct rpc_auth *auth = task->tk_auth; + dprintk("RPC: %4d looking up %s cred\n", task->tk_pid, task->tk_auth->au_ops->au_name); - return task->tk_cred = rpcauth_lookup_credcache(task); + task->tk_cred = rpcauth_lookup_credcache(auth, task->tk_flags); + if (task->tk_cred == 0) + task->tk_status = -ENOMEM; + return task->tk_cred; } int -rpcauth_matchcred(struct rpc_task *task, struct rpc_cred *cred) +rpcauth_matchcred(struct rpc_auth *auth, struct rpc_cred *cred, int taskflags) { - struct rpc_auth *auth = task->tk_auth; - - dprintk("RPC: %4d matching %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); - return auth->au_ops->crmatch(task, cred); + dprintk("RPC: matching %s cred %d\n", + auth->au_ops->au_name, taskflags); + return auth->au_ops->crmatch(cred, taskflags); } void @@ -224,27 +246,36 @@ { dprintk("RPC: %4d holding %s cred %p\n", task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_cred); - if (task->tk_cred) + if (task->tk_cred) { task->tk_cred->cr_count++; + task->tk_cred->cr_expire = jiffies + task->tk_auth->au_expire; + } } void -rpcauth_releasecred(struct rpc_task *task) +rpcauth_releasecred(struct rpc_auth *auth, struct rpc_cred *cred) { - struct rpc_auth *auth = task->tk_auth; - struct rpc_cred *cred; - - dprintk("RPC: %4d releasing %s cred %p\n", - task->tk_pid, auth->au_ops->au_name, task->tk_cred); - if ((cred = task->tk_cred) != NULL) { + if (cred != NULL) { cred->cr_count--; if (cred->cr_flags & RPCAUTH_CRED_DEAD) { rpcauth_remove_credcache(auth, cred); if (!cred->cr_count) - auth->au_ops->crdestroy(cred); + rpcauth_crdestroy(auth, cred); } - task->tk_cred = NULL; } +} + +void +rpcauth_unbindcred(struct rpc_task *task) +{ + struct rpc_auth *auth = task->tk_auth; + struct rpc_cred *cred = task->tk_cred; + + dprintk("RPC: %4d releasing %s cred %p\n", + task->tk_pid, auth->au_ops->au_name, cred); + + rpcauth_releasecred(auth, cred); + task->tk_cred = NULL; } u32 * diff -u --recursive --new-file linux-2.2.7/net/sunrpc/auth_null.c linux-2.2.7-patched/net/sunrpc/auth_null.c --- linux-2.2.7/net/sunrpc/auth_null.c Mon Mar 22 17:00:15 1999 +++ linux-2.2.7-patched/net/sunrpc/auth_null.c Wed May 5 17:11:19 1999 @@ -45,15 +45,12 @@ * Create NULL creds for current process */ static struct rpc_cred * -nul_create_cred(struct rpc_task *task) +nul_create_cred(int flags) { struct rpc_cred *cred; - if (!(cred = (struct rpc_cred *) rpc_malloc(task, sizeof(*cred)))) { - task->tk_status = -ENOMEM; + if (!(cred = (struct rpc_cred *) rpc_allocate(flags, sizeof(*cred)))) return NULL; - } - cred->cr_count = 0; cred->cr_flags = RPCAUTH_CRED_UPTODATE; @@ -73,7 +70,7 @@ * Match cred handle against current process */ static int -nul_match(struct rpc_task *task, struct rpc_cred *cred) +nul_match(struct rpc_cred *cred, int taskflags) { return 1; } diff -u --recursive --new-file linux-2.2.7/net/sunrpc/auth_unix.c linux-2.2.7-patched/net/sunrpc/auth_unix.c --- linux-2.2.7/net/sunrpc/auth_unix.c Mon Mar 22 17:00:15 1999 +++ linux-2.2.7-patched/net/sunrpc/auth_unix.c Wed May 5 17:11:19 1999 @@ -60,7 +60,7 @@ } static struct rpc_cred * -unx_create_cred(struct rpc_task *task) +unx_create_cred(int flags) { struct unx_cred *cred; int i; @@ -68,14 +68,12 @@ dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", current->uid, current->gid); - if (!(cred = (struct unx_cred *) rpc_malloc(task, sizeof(*cred)))) { - task->tk_status = -ENOMEM; + if (!(cred = (struct unx_cred *) rpc_allocate(flags, sizeof(*cred)))) return NULL; - } cred->uc_count = 0; cred->uc_flags = RPCAUTH_CRED_UPTODATE; - if (RPC_DO_ROOTOVERRIDE(task)) { + if (flags & RPC_TASK_ROOTCREDS) { cred->uc_uid = cred->uc_fsuid = 0; cred->uc_gid = cred->uc_fsgid = 0; cred->uc_gids[0] = NOGROUP; @@ -131,12 +129,12 @@ * request root creds (e.g. for NFS swapping). */ static int -unx_match(struct rpc_task * task, struct rpc_cred *rcred) +unx_match(struct rpc_cred *rcred, int taskflags) { struct unx_cred *cred = (struct unx_cred *) rcred; int i; - if (!RPC_DO_ROOTOVERRIDE(task)) { + if (!(taskflags & RPC_TASK_ROOTCREDS)) { int groups; if (cred->uc_uid != current->uid diff -u --recursive --new-file linux-2.2.7/net/sunrpc/clnt.c linux-2.2.7-patched/net/sunrpc/clnt.c --- linux-2.2.7/net/sunrpc/clnt.c Tue Oct 6 18:39:44 1998 +++ linux-2.2.7-patched/net/sunrpc/clnt.c Wed May 5 17:11:19 1999 @@ -237,8 +237,9 @@ * New rpc_call implementation */ int -rpc_do_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, - int flags, rpc_action func, void *data) +rpc_do_call(struct rpc_clnt *clnt, struct rpc_cred *cred, + u32 proc, void *argp, void *resp, + int flags, rpc_action func, void *data) { struct rpc_task my_task, *task = &my_task; sigset_t oldset; @@ -262,9 +263,15 @@ rpc_init_task(task, clnt, NULL, flags); } - /* Bind the user cred, set up the call info struct and - * execute the task */ - if (rpcauth_lookupcred(task) != NULL) { + /* Bind the user cred */ + if (cred != NULL) { + task->tk_cred = cred; + rpcauth_holdcred(task); + } else + cred = rpcauth_bindcred(task); + + /* Set up the call info struct and execute the task */ + if (cred != NULL) { rpc_call_setup(task, proc, argp, resp, 0); rpc_execute(task); } else diff -u --recursive --new-file linux-2.2.7/net/sunrpc/sched.c linux-2.2.7-patched/net/sunrpc/sched.c --- linux-2.2.7/net/sunrpc/sched.c Wed Feb 24 02:11:26 1999 +++ linux-2.2.7-patched/net/sunrpc/sched.c Wed May 5 17:11:19 1999 @@ -692,7 +692,7 @@ if (task->tk_rqstp) xprt_release(task); if (task->tk_cred) - rpcauth_releasecred(task); + rpcauth_unbindcred(task); if (task->tk_buffer) { rpc_free(task->tk_buffer); task->tk_buffer = NULL; diff -u --recursive --new-file linux-2.2.7/net/sunrpc/sunrpc_syms.c linux-2.2.7-patched/net/sunrpc/sunrpc_syms.c --- linux-2.2.7/net/sunrpc/sunrpc_syms.c Thu Aug 20 01:16:04 1998 +++ linux-2.2.7-patched/net/sunrpc/sunrpc_syms.c Wed May 5 17:11:19 1999 @@ -60,7 +60,9 @@ EXPORT_SYMBOL(rpcauth_free_credcache); EXPORT_SYMBOL(rpcauth_insert_credcache); EXPORT_SYMBOL(rpcauth_lookupcred); +EXPORT_SYMBOL(rpcauth_bindcred); EXPORT_SYMBOL(rpcauth_matchcred); +EXPORT_SYMBOL(rpcauth_holdcred); EXPORT_SYMBOL(rpcauth_releasecred); /* RPC server stuff */ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |