extern int nfs4_map_errors(int err);
 extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
 extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
-extern int nfs4_proc_async_renew(struct nfs4_client *);
-extern int nfs4_proc_renew(struct nfs4_client *);
+extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *);
+extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *);
 extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
 extern void nfs4_put_client(struct nfs4_client *clp);
 extern int nfs4_init_client(struct nfs4_client *clp);
 extern struct nfs4_client *nfs4_find_client(struct in_addr *);
+struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp);
 extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
 
 extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
 
        int open_flags = flags & (FMODE_READ|FMODE_WRITE);
        int err;
 
+       err = -ENOMEM;
+       if (!(sp = nfs4_get_state_owner(server, cred))) {
+               dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
+               return err;
+       }
        err = nfs4_recover_expired_lease(server);
        if (err != 0)
-               return err;
+               goto out_put_state_owner;
        /* Protect against reboot recovery - NOTE ORDER! */
        down_read(&clp->cl_sem);
        /* Protect against delegation recall */
        if (delegation == NULL || (delegation->type & open_flags) != open_flags)
                goto out_err;
        err = -ENOMEM;
-       if (!(sp = nfs4_get_state_owner(server, cred))) {
-               dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
-               goto out_err;
-       }
        state = nfs4_get_open_state(inode, sp);
        if (state == NULL)
                goto out_err;
                spin_unlock(&inode->i_lock);
                goto out_ok;
        } else if (state->state != 0)
-               goto out_err;
+               goto out_put_open_state;
 
        lock_kernel();
        err = _nfs4_do_access(inode, cred, open_flags);
        unlock_kernel();
        if (err != 0)
-               goto out_err;
+               goto out_put_open_state;
        set_bit(NFS_DELEGATED_STATE, &state->flags);
        update_open_stateid(state, &delegation->stateid, open_flags);
 out_ok:
        up_read(&nfsi->rwsem);
        up_read(&clp->cl_sem);
        *res = state;
-       return 0; 
+       return 0;
+out_put_open_state:
+       nfs4_put_open_state(state);
 out_err:
-       if (sp != NULL) {
-               if (state != NULL)
-                       nfs4_put_open_state(state);
-               nfs4_put_state_owner(sp);
-       }
        up_read(&nfsi->rwsem);
        up_read(&clp->cl_sem);
        if (err != -EACCES)
                nfs_inode_return_delegation(inode);
+out_put_state_owner:
+       nfs4_put_state_owner(sp);
        return err;
 }
 
        }
        status = nfs4_recover_expired_lease(server);
        if (status != 0)
-               goto out_err;
+               goto err_put_state_owner;
        down_read(&clp->cl_sem);
        status = -ENOMEM;
        opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
        .rpc_call_done = nfs4_renew_done,
 };
 
-int
-nfs4_proc_async_renew(struct nfs4_client *clp)
+int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
                .rpc_argp       = clp,
-               .rpc_cred       = clp->cl_cred,
+               .rpc_cred       = cred,
        };
 
        return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
                        &nfs4_renew_ops, (void *)jiffies);
 }
 
-int
-nfs4_proc_renew(struct nfs4_client *clp)
+int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
                .rpc_argp       = clp,
-               .rpc_cred       = clp->cl_cred,
+               .rpc_cred       = cred,
        };
        unsigned long now = jiffies;
        int status;
 
 nfs4_renew_state(void *data)
 {
        struct nfs4_client *clp = (struct nfs4_client *)data;
+       struct rpc_cred *cred;
        long lease, timeout;
        unsigned long last, now;
 
        timeout = (2 * lease) / 3 + (long)last - (long)now;
        /* Are we close to a lease timeout? */
        if (time_after(now, last + lease/3)) {
-               if (list_empty(&clp->cl_state_owners)) {
+               cred = nfs4_get_renew_cred(clp);
+               if (cred == NULL) {
                        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
                        spin_unlock(&clp->cl_lock);
                        nfs_expire_all_delegations(clp);
                }
                spin_unlock(&clp->cl_lock);
                /* Queue an asynchronous RENEW. */
-               nfs4_proc_async_renew(clp);
+               nfs4_proc_async_renew(clp, cred);
+               put_rpccred(cred);
                timeout = (2 * lease) / 3;
                spin_lock(&clp->cl_lock);
        } else
 
        return sp;
 }
 
+struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp)
+{
+       struct nfs4_state_owner *sp;
+       struct rpc_cred *cred = NULL;
+
+       list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
+               if (list_empty(&sp->so_states))
+                       continue;
+               cred = get_rpccred(sp->so_cred);
+               break;
+       }
+       return cred;
+}
+
 static struct nfs4_state_owner *
 nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred)
 {
        if (list_empty(&clp->cl_superblocks))
                goto out;
 restart_loop:
-       status = nfs4_proc_renew(clp);
+       status = nfs4_proc_renew(clp, clp->cl_cred);
        switch (status) {
                case 0:
                case -NFS4ERR_CB_PATH_DOWN: