diff --git a/[refs] b/[refs] index d58dc3c676af..d72c395c4c42 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 00b464debf0038b1628996065f0be564ccfbfd86 +refs/heads/master: f9bdfa0ecb3304e8b7e74862b1f4b03b6feaaeef diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index 21934784f936..bdaa8aabdaa6 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -58,6 +58,7 @@ pcibios_find_pci_bus(struct device_node *dn) return find_bus_among_children(pdn->phb->bus, dn); } +EXPORT_SYMBOL_GPL(pcibios_find_pci_bus); /** * pcibios_remove_pci_devices - remove all devices under this bus @@ -106,6 +107,7 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) } } } +EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); static int pcibios_pci_config_bridge(struct pci_dev *dev) @@ -172,3 +174,4 @@ pcibios_add_pci_devices(struct pci_bus * bus) pcibios_pci_config_bridge(dev); } } +EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); diff --git a/trunk/fs/lockd/clntproc.c b/trunk/fs/lockd/clntproc.c index 220058d8616d..145524039577 100644 --- a/trunk/fs/lockd/clntproc.c +++ b/trunk/fs/lockd/clntproc.c @@ -22,14 +22,12 @@ #define NLMDBG_FACILITY NLMDBG_CLIENT #define NLMCLNT_GRACE_WAIT (5*HZ) #define NLMCLNT_POLL_TIMEOUT (30*HZ) -#define NLMCLNT_MAX_RETRIES 3 static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); static int nlm_stat_to_errno(u32 stat); static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); -static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *); static const struct rpc_call_ops nlmclnt_unlock_ops; static const struct rpc_call_ops nlmclnt_cancel_ops; @@ -600,7 +598,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) nlmclnt_finish_block(req); /* Cancel the blocked request if it is still pending */ if (resp->status == NLM_LCK_BLOCKED) - nlmclnt_cancel(host, req->a_args.block, fl); + nlmclnt_cancel(host, fl); out: nlmclnt_release_lockargs(req); return status; @@ -730,7 +728,8 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = { * We always use an async RPC call for this in order not to hang a * process that has been Ctrl-C'ed. */ -static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl) +int +nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) { struct nlm_rqst *req; unsigned long flags; @@ -751,7 +750,6 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl req->a_flags = RPC_TASK_ASYNC; nlmclnt_setlockargs(req, fl); - req->a_args.block = block; status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); if (status < 0) { @@ -803,9 +801,6 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) return; retry_cancel: - /* Don't ever retry more than 3 times */ - if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) - goto die; nlm_rebind_host(req->a_host); rpc_restart_call(task); rpc_delay(task, 30 * HZ); diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index 04ab2fc360e7..10ae377e68ff 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -481,7 +481,7 @@ static ssize_t nfs_direct_write_seg(struct inode *inode, if (wdata->verf.committed != NFS_FILE_SYNC) { need_commit = 1; if (memcmp(&first_verf.verifier, &wdata->verf.verifier, - sizeof(first_verf.verifier))) + sizeof(first_verf.verifier))); goto sync_retry; } diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index 920766cea79c..95c8fea293ba 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -84,7 +84,6 @@ struct nlm_rqst { struct nlm_args a_args; /* arguments */ struct nlm_res a_res; /* result */ struct nlm_wait * a_block; - unsigned int a_retries; /* Retry count */ char a_owner[NLMCLNT_OHSIZE]; }; @@ -149,6 +148,7 @@ struct nlm_rqst * nlmclnt_alloc_call(void); int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_rqst *req); long nlmclnt_block(struct nlm_rqst *req, long timeout); +int nlmclnt_cancel(struct nlm_host *, struct file_lock *); u32 nlmclnt_grant(struct nlm_lock *); void nlmclnt_recovery(struct nlm_host *, u32); int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); diff --git a/trunk/include/linux/sunrpc/auth.h b/trunk/include/linux/sunrpc/auth.h index be4772ed43c0..b68c11a2d6dd 100644 --- a/trunk/include/linux/sunrpc/auth.h +++ b/trunk/include/linux/sunrpc/auth.h @@ -48,7 +48,7 @@ struct rpc_cred { /* per-flavor data */ }; -#define RPCAUTH_CRED_NEW 0x0001 +#define RPCAUTH_CRED_LOCKED 0x0001 #define RPCAUTH_CRED_UPTODATE 0x0002 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 @@ -83,10 +83,9 @@ struct rpc_auth { struct rpc_cred_cache * au_credcache; /* per-flavor data */ }; - -/* Flags for rpcauth_lookupcred() */ -#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ -#define RPCAUTH_LOOKUP_ROOTCREDS 0x02 /* This really ought to go! */ +#define RPC_AUTH_PROC_CREDS 0x0010 /* process creds (including + * uid/gid, fs[ug]id, gids) + */ /* * Client authentication ops @@ -106,7 +105,6 @@ struct rpc_authops { struct rpc_credops { const char * cr_name; /* Name of the auth flavour */ - int (*cr_init)(struct rpc_auth *, struct rpc_cred *); void (*crdestroy)(struct rpc_cred *); int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); diff --git a/trunk/net/sunrpc/auth.c b/trunk/net/sunrpc/auth.c index 8d6f1a176b15..9ac1b8c26c01 100644 --- a/trunk/net/sunrpc/auth.c +++ b/trunk/net/sunrpc/auth.c @@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) */ struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, - int flags) + int taskflags) { struct rpc_cred_cache *cache = auth->au_credcache; HLIST_HEAD(free); @@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, *cred = NULL; int nr = 0; - if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) + if (!(taskflags & RPC_TASK_ROOTCREDS)) nr = acred->uid & RPC_CREDCACHE_MASK; retry: spin_lock(&rpc_credcache_lock); @@ -202,7 +202,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { struct rpc_cred *entry; entry = hlist_entry(pos, struct rpc_cred, cr_hash); - if (entry->cr_ops->crmatch(acred, entry, flags)) { + if (entry->cr_ops->crmatch(acred, entry, taskflags)) { hlist_del(&entry->cr_hash); cred = entry; break; @@ -224,7 +224,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, rpcauth_destroy_credlist(&free); if (!cred) { - new = auth->au_ops->crcreate(auth, acred, flags); + new = auth->au_ops->crcreate(auth, acred, taskflags); if (!IS_ERR(new)) { #ifdef RPC_DEBUG new->cr_magic = RPCAUTH_CRED_MAGIC; @@ -232,21 +232,13 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, goto retry; } else cred = new; - } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) - && cred->cr_ops->cr_init != NULL - && !(flags & RPCAUTH_LOOKUP_NEW)) { - int res = cred->cr_ops->cr_init(auth, cred); - if (res < 0) { - put_rpccred(cred); - cred = ERR_PTR(res); - } } return (struct rpc_cred *) cred; } struct rpc_cred * -rpcauth_lookupcred(struct rpc_auth *auth, int flags) +rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) { struct auth_cred acred = { .uid = current->fsuid, @@ -258,7 +250,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags) dprintk("RPC: looking up %s cred\n", auth->au_ops->au_name); get_group_info(acred.group_info); - ret = auth->au_ops->lookup_cred(auth, &acred, flags); + ret = auth->au_ops->lookup_cred(auth, &acred, taskflags); put_group_info(acred.group_info); return ret; } @@ -273,14 +265,11 @@ rpcauth_bindcred(struct rpc_task *task) .group_info = current->group_info, }; struct rpc_cred *ret; - int flags = 0; dprintk("RPC: %4d looking up %s cred\n", task->tk_pid, task->tk_auth->au_ops->au_name); get_group_info(acred.group_info); - if (task->tk_flags & RPC_TASK_ROOTCREDS) - flags |= RPCAUTH_LOOKUP_ROOTCREDS; - ret = auth->au_ops->lookup_cred(auth, &acred, flags); + ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags); if (!IS_ERR(ret)) task->tk_msg.rpc_cred = ret; else diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index bb46efd92e57..8d782282ec19 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -158,7 +158,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) old = gss_cred->gc_ctx; gss_cred->gc_ctx = ctx; cred->cr_flags |= RPCAUTH_CRED_UPTODATE; - cred->cr_flags &= ~RPCAUTH_CRED_NEW; write_unlock(&gss_ctx_lock); if (old) gss_put_ctx(old); @@ -581,7 +580,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) } else { struct auth_cred acred = { .uid = uid }; spin_unlock(&gss_auth->lock); - cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW); + cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0); if (IS_ERR(cred)) { err = PTR_ERR(cred); goto err_put_ctx; @@ -759,13 +758,13 @@ gss_destroy_cred(struct rpc_cred *rc) * Lookup RPCSEC_GSS cred for the current process */ static struct rpc_cred * -gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) +gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) { - return rpcauth_lookup_credcache(auth, acred, flags); + return rpcauth_lookup_credcache(auth, acred, taskflags); } static struct rpc_cred * -gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) +gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) { struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); struct gss_cred *cred = NULL; @@ -786,8 +785,13 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) */ cred->gc_flags = 0; cred->gc_base.cr_ops = &gss_credops; - cred->gc_base.cr_flags = RPCAUTH_CRED_NEW; cred->gc_service = gss_auth->service; + do { + err = gss_create_upcall(gss_auth, cred); + } while (err == -EAGAIN); + if (err < 0) + goto out_err; + return &cred->gc_base; out_err: @@ -797,34 +801,13 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) } static int -gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred) -{ - struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); - struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base); - int err; - - do { - err = gss_create_upcall(gss_auth, gss_cred); - } while (err == -EAGAIN); - return err; -} - -static int -gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) +gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags) { struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); - /* - * If the searchflags have set RPCAUTH_LOOKUP_NEW, then - * we don't really care if the credential has expired or not, - * since the caller should be prepared to reinitialise it. - */ - if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW)) - goto out; /* Don't match with creds that have expired. */ if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) return 0; -out: return (rc->cr_uid == acred->uid); } @@ -1258,7 +1241,6 @@ static struct rpc_authops authgss_ops = { static struct rpc_credops gss_credops = { .cr_name = "AUTH_GSS", .crdestroy = gss_destroy_cred, - .cr_init = gss_cred_init, .crmatch = gss_match, .crmarshal = gss_marshal, .crrefresh = gss_refresh, diff --git a/trunk/net/sunrpc/auth_unix.c b/trunk/net/sunrpc/auth_unix.c index df14b6bfbf10..1b3ed4fd1987 100644 --- a/trunk/net/sunrpc/auth_unix.c +++ b/trunk/net/sunrpc/auth_unix.c @@ -75,7 +75,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) atomic_set(&cred->uc_count, 1); cred->uc_flags = RPCAUTH_CRED_UPTODATE; - if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { + if (flags & RPC_TASK_ROOTCREDS) { cred->uc_uid = 0; cred->uc_gid = 0; cred->uc_gids[0] = NOGROUP; @@ -108,12 +108,12 @@ unx_destroy_cred(struct rpc_cred *cred) * request root creds (e.g. for NFS swapping). */ static int -unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) +unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags) { struct unx_cred *cred = (struct unx_cred *) rcred; int i; - if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) { + if (!(taskflags & RPC_TASK_ROOTCREDS)) { int groups; if (cred->uc_uid != acred->uid diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index a5c0c7b6e151..9764c80ab0b2 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -38,42 +38,44 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly; #define RPC_UPCALL_TIMEOUT (30*HZ) -static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, - void (*destroy_msg)(struct rpc_pipe_msg *), int err) +static void +__rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err) { struct rpc_pipe_msg *msg; + void (*destroy_msg)(struct rpc_pipe_msg *); - if (list_empty(head)) - return; - do { + destroy_msg = rpci->ops->destroy_msg; + while (!list_empty(head)) { msg = list_entry(head->next, struct rpc_pipe_msg, list); - list_del(&msg->list); + list_del_init(&msg->list); msg->errno = err; destroy_msg(msg); - } while (!list_empty(head)); + } +} + +static void +__rpc_purge_upcall(struct inode *inode, int err) +{ + struct rpc_inode *rpci = RPC_I(inode); + + __rpc_purge_list(rpci, &rpci->pipe, err); + rpci->pipelen = 0; wake_up(&rpci->waitq); } static void rpc_timeout_upcall_queue(void *data) { - LIST_HEAD(free_list); struct rpc_inode *rpci = (struct rpc_inode *)data; struct inode *inode = &rpci->vfs_inode; - void (*destroy_msg)(struct rpc_pipe_msg *); - spin_lock(&inode->i_lock); - if (rpci->ops == NULL) { - spin_unlock(&inode->i_lock); - return; - } - destroy_msg = rpci->ops->destroy_msg; - if (rpci->nreaders == 0) { - list_splice_init(&rpci->pipe, &free_list); - rpci->pipelen = 0; - } - spin_unlock(&inode->i_lock); - rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT); + mutex_lock(&inode->i_mutex); + if (rpci->ops == NULL) + goto out; + if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) + __rpc_purge_upcall(inode, -ETIMEDOUT); +out: + mutex_unlock(&inode->i_mutex); } int @@ -82,7 +84,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) struct rpc_inode *rpci = RPC_I(inode); int res = -EPIPE; - spin_lock(&inode->i_lock); + mutex_lock(&inode->i_mutex); if (rpci->ops == NULL) goto out; if (rpci->nreaders) { @@ -98,7 +100,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) res = 0; } out: - spin_unlock(&inode->i_lock); + mutex_unlock(&inode->i_mutex); wake_up(&rpci->waitq); return res; } @@ -113,29 +115,21 @@ static void rpc_close_pipes(struct inode *inode) { struct rpc_inode *rpci = RPC_I(inode); - struct rpc_pipe_ops *ops; mutex_lock(&inode->i_mutex); - ops = rpci->ops; - if (ops != NULL) { - LIST_HEAD(free_list); - - spin_lock(&inode->i_lock); + if (rpci->ops != NULL) { rpci->nreaders = 0; - list_splice_init(&rpci->in_upcall, &free_list); - list_splice_init(&rpci->pipe, &free_list); - rpci->pipelen = 0; - rpci->ops = NULL; - spin_unlock(&inode->i_lock); - rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); + __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); + __rpc_purge_upcall(inode, -EPIPE); rpci->nwriters = 0; - if (ops->release_pipe) - ops->release_pipe(inode); - cancel_delayed_work(&rpci->queue_timeout); - flush_scheduled_work(); + if (rpci->ops->release_pipe) + rpci->ops->release_pipe(inode); + rpci->ops = NULL; } rpc_inode_setowner(inode, NULL); mutex_unlock(&inode->i_mutex); + cancel_delayed_work(&rpci->queue_timeout); + flush_scheduled_work(); } static struct inode * @@ -183,26 +177,16 @@ rpc_pipe_release(struct inode *inode, struct file *filp) goto out; msg = (struct rpc_pipe_msg *)filp->private_data; if (msg != NULL) { - spin_lock(&inode->i_lock); msg->errno = -EAGAIN; - list_del(&msg->list); - spin_unlock(&inode->i_lock); + list_del_init(&msg->list); rpci->ops->destroy_msg(msg); } if (filp->f_mode & FMODE_WRITE) rpci->nwriters --; - if (filp->f_mode & FMODE_READ) { + if (filp->f_mode & FMODE_READ) rpci->nreaders --; - if (rpci->nreaders == 0) { - LIST_HEAD(free_list); - spin_lock(&inode->i_lock); - list_splice_init(&rpci->pipe, &free_list); - rpci->pipelen = 0; - spin_unlock(&inode->i_lock); - rpc_purge_list(rpci, &free_list, - rpci->ops->destroy_msg, -EAGAIN); - } - } + if (!rpci->nreaders) + __rpc_purge_upcall(inode, -EAGAIN); if (rpci->ops->release_pipe) rpci->ops->release_pipe(inode); out: @@ -225,7 +209,6 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) } msg = filp->private_data; if (msg == NULL) { - spin_lock(&inode->i_lock); if (!list_empty(&rpci->pipe)) { msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, @@ -235,7 +218,6 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) filp->private_data = msg; msg->copied = 0; } - spin_unlock(&inode->i_lock); if (msg == NULL) goto out_unlock; } @@ -243,9 +225,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) res = rpci->ops->upcall(filp, msg, buf, len); if (res < 0 || msg->len == msg->copied) { filp->private_data = NULL; - spin_lock(&inode->i_lock); - list_del(&msg->list); - spin_unlock(&inode->i_lock); + list_del_init(&msg->list); rpci->ops->destroy_msg(msg); } out_unlock: @@ -630,7 +610,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) return ERR_PTR(error); dir = nd->dentry->d_inode; mutex_lock(&dir->i_mutex); - dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len); + dentry = lookup_hash(nd); if (IS_ERR(dentry)) goto out_err; if (dentry->d_inode) { @@ -692,7 +672,7 @@ rpc_rmdir(char *path) return error; dir = nd.dentry->d_inode; mutex_lock(&dir->i_mutex); - dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); + dentry = lookup_hash(&nd); if (IS_ERR(dentry)) { error = PTR_ERR(dentry); goto out_release; @@ -753,7 +733,7 @@ rpc_unlink(char *path) return error; dir = nd.dentry->d_inode; mutex_lock(&dir->i_mutex); - dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); + dentry = lookup_hash(&nd); if (IS_ERR(dentry)) { error = PTR_ERR(dentry); goto out_release;