]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/nfs/nfs4proc.c
NFS: Remove use of the Big Kernel Lock around calls to rpc_call_sync
[mv-sheeva.git] / fs / nfs / nfs4proc.c
index e6ee97f19d81191ebc98d25c74abfe0f459c8cf5..4b5fc714d7862fe8dd43960ad6f375fc73583141 100644 (file)
@@ -55,7 +55,7 @@
 
 #define NFSDBG_FACILITY                NFSDBG_PROC
 
-#define NFS4_POLL_RETRY_MIN    (1*HZ)
+#define NFS4_POLL_RETRY_MIN    (HZ/10)
 #define NFS4_POLL_RETRY_MAX    (15*HZ)
 
 struct nfs4_opendata;
@@ -64,7 +64,7 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
 static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
-static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp);
+static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
 
 /* Prevent leaks of NFSv4 errors into userland */
 int nfs4_map_errors(int err)
@@ -138,10 +138,10 @@ const u32 nfs4_fs_locations_bitmap[2] = {
        | FATTR4_WORD1_MOUNTED_ON_FILEID
 };
 
-static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
+static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
                struct nfs4_readdir_arg *readdir)
 {
-       u32 *start, *p;
+       __be32 *start, *p;
 
        BUG_ON(readdir->count < 80);
        if (cookie > 2) {
@@ -162,7 +162,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
         * when talking to the server, we always send cookie 0
         * instead of 1 or 2.
         */
-       start = p = (u32 *)kmap_atomic(*readdir->pages, KM_USER0);
+       start = p = kmap_atomic(*readdir->pages, KM_USER0);
        
        if (cookie == 0) {
                *p++ = xdr_one;                                  /* next */
@@ -195,7 +195,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
 
 static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
 {
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
        spin_lock(&clp->cl_lock);
        if (time_before(clp->cl_last_renewal,timestamp))
                clp->cl_last_renewal = timestamp;
@@ -252,7 +252,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
        atomic_inc(&sp->so_count);
        p->o_arg.fh = NFS_FH(dir);
        p->o_arg.open_flags = flags,
-       p->o_arg.clientid = server->nfs4_state->cl_clientid;
+       p->o_arg.clientid = server->nfs_client->cl_clientid;
        p->o_arg.id = sp->so_id;
        p->o_arg.name = &dentry->d_name;
        p->o_arg.server = server;
@@ -550,7 +550,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
                        case -NFS4ERR_STALE_STATEID:
                        case -NFS4ERR_EXPIRED:
                                /* Don't recall a delegation if it was lost */
-                               nfs4_schedule_state_recovery(server->nfs4_state);
+                               nfs4_schedule_state_recovery(server->nfs_client);
                                return err;
                }
                err = nfs4_handle_exception(server, err, &exception);
@@ -636,7 +636,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
                smp_wmb();
        } else
                status = data->rpc_status;
-       rpc_release_task(task);
+       rpc_put_task(task);
        return status;
 }
 
@@ -742,7 +742,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
                smp_wmb();
        } else
                status = data->rpc_status;
-       rpc_release_task(task);
+       rpc_put_task(task);
        if (status != 0)
                return status;
 
@@ -758,7 +758,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
        }
        nfs_confirm_seqid(&data->owner->so_seqid, 0);
        if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
-               return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
+               return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
        return 0;
 }
 
@@ -792,11 +792,18 @@ out:
 
 int nfs4_recover_expired_lease(struct nfs_server *server)
 {
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
+       int ret;
 
-       if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
+       for (;;) {
+               ret = nfs4_wait_clnt_recover(server->client, clp);
+               if (ret != 0)
+                       return ret;
+               if (!test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
+                       break;
                nfs4_schedule_state_recovery(clp);
-       return nfs4_wait_clnt_recover(server->client, clp);
+       }
+       return 0;
 }
 
 /*
@@ -867,7 +874,7 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
 {
        struct nfs_delegation *delegation;
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs4_state_owner *sp = NULL;
        struct nfs4_state *state = NULL;
@@ -953,7 +960,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
        struct nfs4_state_owner  *sp;
        struct nfs4_state     *state = NULL;
        struct nfs_server       *server = NFS_SERVER(dir);
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
        struct nfs4_opendata *opendata;
        int                     status;
 
@@ -970,7 +977,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
        status = -ENOMEM;
        opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
        if (opendata == NULL)
-               goto err_put_state_owner;
+               goto err_release_rwsem;
 
        status = _nfs4_proc_open(opendata);
        if (status != 0)
@@ -989,11 +996,11 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
        return 0;
 err_opendata_free:
        nfs4_opendata_free(opendata);
+err_release_rwsem:
+       up_read(&clp->cl_sem);
 err_put_state_owner:
        nfs4_put_state_owner(sp);
 out_err:
-       /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
-       up_read(&clp->cl_sem);
        *res = NULL;
        return status;
 }
@@ -1133,7 +1140,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
                        break;
                case -NFS4ERR_STALE_STATEID:
                case -NFS4ERR_EXPIRED:
-                       nfs4_schedule_state_recovery(server->nfs4_state);
+                       nfs4_schedule_state_recovery(server->nfs_client);
                        break;
                default:
                        if (nfs4_async_handle_error(task, server) == -EAGAIN) {
@@ -1268,7 +1275,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
                BUG_ON(nd->intent.open.flags & O_CREAT);
        }
 
-       cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
+       cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
        if (IS_ERR(cred))
                return (struct dentry *)cred;
        state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
@@ -1291,7 +1298,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
        struct rpc_cred *cred;
        struct nfs4_state *state;
 
-       cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
+       cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
        if (IS_ERR(cred))
                return PTR_ERR(cred);
        state = nfs4_open_delegated(dentry->d_inode, openflags, cred);
@@ -1307,11 +1314,9 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
                        case -EROFS:
                                lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
                                return 1;
-                       case -ENOENT:
-                               if (dentry->d_inode == NULL)
-                                       return 1;
+                       default:
+                               goto out_drop;
                }
-               goto out_drop;
        }
        if (state->inode == dentry->d_inode) {
                nfs4_intent_set_file(nd, dentry, state);
@@ -1393,70 +1398,19 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
        return err;
 }
 
+/*
+ * get the file handle for the "/" directory on the server
+ */
 static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
-               struct nfs_fsinfo *info)
+                             struct nfs_fsinfo *info)
 {
-       struct nfs_fattr *      fattr = info->fattr;
-       unsigned char *         p;
-       struct qstr             q;
-       struct nfs4_lookup_arg args = {
-               .dir_fh = fhandle,
-               .name = &q,
-               .bitmask = nfs4_fattr_bitmap,
-       };
-       struct nfs4_lookup_res res = {
-               .server = server,
-               .fattr = fattr,
-               .fh = fhandle,
-       };
-       struct rpc_message msg = {
-               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
-               .rpc_argp = &args,
-               .rpc_resp = &res,
-       };
        int status;
 
-       /*
-        * Now we do a separate LOOKUP for each component of the mount path.
-        * The LOOKUPs are done separately so that we can conveniently
-        * catch an ERR_WRONGSEC if it occurs along the way...
-        */
        status = nfs4_lookup_root(server, fhandle, info);
-       if (status)
-               goto out;
-
-       p = server->mnt_path;
-       for (;;) {
-               struct nfs4_exception exception = { };
-
-               while (*p == '/')
-                       p++;
-               if (!*p)
-                       break;
-               q.name = p;
-               while (*p && (*p != '/'))
-                       p++;
-               q.len = p - q.name;
-
-               do {
-                       nfs_fattr_init(fattr);
-                       status = nfs4_handle_exception(server,
-                                       rpc_call_sync(server->client, &msg, 0),
-                                       &exception);
-               } while (exception.retry);
-               if (status == 0)
-                       continue;
-               if (status == -ENOENT) {
-                       printk(KERN_NOTICE "NFS: mount path %s does not exist!\n", server->mnt_path);
-                       printk(KERN_NOTICE "NFS: suggestion: try mounting '/' instead.\n");
-               }
-               break;
-       }
        if (status == 0)
                status = nfs4_server_capabilities(server, fhandle);
        if (status == 0)
                status = nfs4_do_fsinfo(server, fhandle, info);
-out:
        return nfs4_map_errors(status);
 }
 
@@ -1565,7 +1519,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 
        nfs_fattr_init(fattr);
        
-       cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
+       cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
        if (IS_ERR(cred))
                return PTR_ERR(cred);
 
@@ -1583,6 +1537,52 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
        return status;
 }
 
+static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
+               struct qstr *name, struct nfs_fh *fhandle,
+               struct nfs_fattr *fattr)
+{
+       int                    status;
+       struct nfs4_lookup_arg args = {
+               .bitmask = server->attr_bitmask,
+               .dir_fh = dirfh,
+               .name = name,
+       };
+       struct nfs4_lookup_res res = {
+               .server = server,
+               .fattr = fattr,
+               .fh = fhandle,
+       };
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
+               .rpc_argp = &args,
+               .rpc_resp = &res,
+       };
+
+       nfs_fattr_init(fattr);
+
+       dprintk("NFS call  lookupfh %s\n", name->name);
+       status = rpc_call_sync(server->client, &msg, 0);
+       dprintk("NFS reply lookupfh: %d\n", status);
+       if (status == -NFS4ERR_MOVED)
+               status = -EREMOTE;
+       return status;
+}
+
+static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
+                             struct qstr *name, struct nfs_fh *fhandle,
+                             struct nfs_fattr *fattr)
+{
+       struct nfs4_exception exception = { };
+       int err;
+       do {
+               err = nfs4_handle_exception(server,
+                               _nfs4_proc_lookupfh(server, dirfh, name,
+                                                   fhandle, fattr),
+                               &exception);
+       } while (exception.retry);
+       return err;
+}
+
 static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
                struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
@@ -1881,7 +1881,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
        struct rpc_cred *cred;
        int status = 0;
 
-       cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
+       cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
        if (IS_ERR(cred)) {
                status = PTR_ERR(cred);
                goto out;
@@ -2089,24 +2089,24 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n
        return err;
 }
 
-static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
-               struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle,
-               struct nfs_fattr *fattr)
+static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+               struct page *page, unsigned int len, struct iattr *sattr)
 {
        struct nfs_server *server = NFS_SERVER(dir);
-       struct nfs_fattr dir_fattr;
+       struct nfs_fh fhandle;
+       struct nfs_fattr fattr, dir_fattr;
        struct nfs4_create_arg arg = {
                .dir_fh = NFS_FH(dir),
                .server = server,
-               .name = name,
+               .name = &dentry->d_name,
                .attrs = sattr,
                .ftype = NF4LNK,
                .bitmask = server->attr_bitmask,
        };
        struct nfs4_create_res res = {
                .server = server,
-               .fh = fhandle,
-               .fattr = fattr,
+               .fh = &fhandle,
+               .fattr = &fattr,
                .dir_fattr = &dir_fattr,
        };
        struct rpc_message msg = {
@@ -2116,29 +2116,32 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
        };
        int                     status;
 
-       if (path->len > NFS4_MAXPATHLEN)
+       if (len > NFS4_MAXPATHLEN)
                return -ENAMETOOLONG;
-       arg.u.symlink = path;
-       nfs_fattr_init(fattr);
+
+       arg.u.symlink.pages = &page;
+       arg.u.symlink.len = len;
+       nfs_fattr_init(&fattr);
        nfs_fattr_init(&dir_fattr);
        
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
-       if (!status)
+       if (!status) {
                update_changeattr(dir, &res.dir_cinfo);
-       nfs_post_op_update_inode(dir, res.dir_fattr);
+               nfs_post_op_update_inode(dir, res.dir_fattr);
+               status = nfs_instantiate(dentry, &fhandle, &fattr);
+       }
        return status;
 }
 
-static int nfs4_proc_symlink(struct inode *dir, struct qstr *name,
-               struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle,
-               struct nfs_fattr *fattr)
+static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+               struct page *page, unsigned int len, struct iattr *sattr)
 {
        struct nfs4_exception exception = { };
        int err;
        do {
                err = nfs4_handle_exception(NFS_SERVER(dir),
-                               _nfs4_proc_symlink(dir, name, path, sattr,
-                                       fhandle, fattr),
+                               _nfs4_proc_symlink(dir, dentry, page,
+                                                       len, sattr),
                                &exception);
        } while (exception.retry);
        return err;
@@ -2220,13 +2223,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                        dentry->d_parent->d_name.name,
                        dentry->d_name.name,
                        (unsigned long long)cookie);
-       lock_kernel();
        nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
        res.pgbase = args.pgbase;
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        if (status == 0)
                memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
-       unlock_kernel();
        dprintk("%s: returns %d\n", __FUNCTION__, status);
        return status;
 }
@@ -2521,7 +2522,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
  */
 static void nfs4_renew_done(struct rpc_task *task, void *data)
 {
-       struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
+       struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp;
        unsigned long timestamp = (unsigned long)data;
 
        if (task->tk_status < 0) {
@@ -2543,7 +2544,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
        .rpc_call_done = nfs4_renew_done,
 };
 
-int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
+int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2555,7 +2556,7 @@ int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
                        &nfs4_renew_ops, (void *)jiffies);
 }
 
-int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred)
+int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
 {
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2668,7 +2669,7 @@ out:
        nfs4_set_cached_acl(inode, acl);
 }
 
-static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
 {
        struct page *pages[NFS4ACL_MAXPAGES];
        struct nfs_getaclargs args = {
@@ -2721,6 +2722,19 @@ out_free:
        return ret;
 }
 
+static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+{
+       struct nfs4_exception exception = { };
+       ssize_t ret;
+       do {
+               ret = __nfs4_get_acl_uncached(inode, buf, buflen);
+               if (ret >= 0)
+                       break;
+               ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception);
+       } while (exception.retry);
+       return ret;
+}
+
 static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
 {
        struct nfs_server *server = NFS_SERVER(inode);
@@ -2737,7 +2751,7 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
        return nfs4_get_acl_uncached(inode, buf, buflen);
 }
 
-static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
 {
        struct nfs_server *server = NFS_SERVER(inode);
        struct page *pages[NFS4ACL_MAXPAGES];
@@ -2757,16 +2771,28 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
                return -EOPNOTSUPP;
        nfs_inode_return_delegation(inode);
        buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
-       ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
+       ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
        if (ret == 0)
                nfs4_write_cached_acl(inode, buf, buflen);
        return ret;
 }
 
+static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+{
+       struct nfs4_exception exception = { };
+       int err;
+       do {
+               err = nfs4_handle_exception(NFS_SERVER(inode),
+                               __nfs4_proc_set_acl(inode, buf, buflen),
+                               &exception);
+       } while (exception.retry);
+       return err;
+}
+
 static int
 nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
 {
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
 
        if (!clp || task->tk_status >= 0)
                return 0;
@@ -2803,7 +2829,7 @@ static int nfs4_wait_bit_interruptible(void *word)
        return 0;
 }
 
-static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp)
+static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
 {
        sigset_t oldset;
        int res;
@@ -2846,7 +2872,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
  */
 int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
 {
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
        int ret = errorcode;
 
        exception->retry = 0;
@@ -2861,6 +2887,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
                        if (ret == 0)
                                exception->retry = 1;
                        break;
+               case -NFS4ERR_FILE_OPEN:
                case -NFS4ERR_GRACE:
                case -NFS4ERR_DELAY:
                        ret = nfs4_delay(server->client, &exception->timeout);
@@ -2873,7 +2900,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
        return nfs4_map_errors(ret);
 }
 
-int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
 {
        nfs4_verifier sc_verifier;
        struct nfs4_setclientid setclientid = {
@@ -2886,18 +2913,18 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
                .rpc_resp = clp,
                .rpc_cred = cred,
        };
-       u32 *p;
+       __be32 *p;
        int loop = 0;
        int status;
 
-       p = (u32*)sc_verifier.data;
+       p = (__be32*)sc_verifier.data;
        *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
        *p = htonl((u32)clp->cl_boot_time.tv_nsec);
 
        for(;;) {
                setclientid.sc_name_len = scnprintf(setclientid.sc_name,
                                sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u",
-                               clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr),
+                               clp->cl_ipaddr, NIPQUAD(clp->cl_addr.sin_addr),
                                cred->cr_ops->cr_name,
                                clp->cl_id_uniquifier);
                setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
@@ -2920,7 +2947,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
        return status;
 }
 
-static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
 {
        struct nfs_fsinfo fsinfo;
        struct rpc_message msg = {
@@ -2944,7 +2971,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cr
        return status;
 }
 
-int nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred)
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
 {
        long timeout;
        int err;
@@ -3038,7 +3065,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
                if (status == 0)
                        nfs_post_op_update_inode(inode, &data->fattr);
        }
-       rpc_release_task(task);
+       rpc_put_task(task);
        return status;
 }
 
@@ -3052,7 +3079,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
                switch (err) {
                        case -NFS4ERR_STALE_STATEID:
                        case -NFS4ERR_EXPIRED:
-                               nfs4_schedule_state_recovery(server->nfs4_state);
+                               nfs4_schedule_state_recovery(server->nfs_client);
                        case 0:
                                return 0;
                }
@@ -3081,7 +3108,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
 {
        struct inode *inode = state->inode;
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs4_client *clp = server->nfs4_state;
+       struct nfs_client *clp = server->nfs_client;
        struct nfs_lockt_args arg = {
                .fh = NFS_FH(inode),
                .fl = request,
@@ -3206,7 +3233,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
                        break;
                case -NFS4ERR_STALE_STATEID:
                case -NFS4ERR_EXPIRED:
-                       nfs4_schedule_state_recovery(calldata->server->nfs4_state);
+                       nfs4_schedule_state_recovery(calldata->server->nfs_client);
                        break;
                default:
                        if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) {
@@ -3285,7 +3312,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
        if (IS_ERR(task))
                goto out;
        status = nfs4_wait_for_completion_rpc_task(task);
-       rpc_release_task(task);
+       rpc_put_task(task);
 out:
        return status;
 }
@@ -3318,7 +3345,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
        if (p->arg.lock_seqid == NULL)
                goto out_free;
        p->arg.lock_stateid = &lsp->ls_stateid;
-       p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid;
+       p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
        p->arg.lock_owner.id = lsp->ls_id;
        p->lsp = lsp;
        atomic_inc(&lsp->ls_count);
@@ -3401,7 +3428,7 @@ static void nfs4_lock_release(void *calldata)
                task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,
                                data->arg.lock_seqid);
                if (!IS_ERR(task))
-                       rpc_release_task(task);
+                       rpc_put_task(task);
                dprintk("%s: cancelling lock!\n", __FUNCTION__);
        } else
                nfs_free_seqid(data->arg.lock_seqid);
@@ -3443,7 +3470,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
                        ret = -EAGAIN;
        } else
                data->cancelled = 1;
-       rpc_release_task(task);
+       rpc_put_task(task);
        dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret);
        return ret;
 }
@@ -3488,7 +3515,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
 
 static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
 {
-       struct nfs4_client *clp = state->owner->so_client;
+       struct nfs_client *clp = state->owner->so_client;
        unsigned char fl_flags = request->fl_flags;
        int status;
 
@@ -3690,7 +3717,7 @@ static struct inode_operations nfs4_file_inode_operations = {
        .listxattr      = nfs4_listxattr,
 };
 
-struct nfs_rpc_ops     nfs_v4_clientops = {
+const struct nfs_rpc_ops nfs_v4_clientops = {
        .version        = 4,                    /* protocol version */
        .dentry_ops     = &nfs4_dentry_operations,
        .dir_inode_ops  = &nfs4_dir_inode_operations,
@@ -3698,6 +3725,7 @@ struct nfs_rpc_ops        nfs_v4_clientops = {
        .getroot        = nfs4_proc_get_root,
        .getattr        = nfs4_proc_getattr,
        .setattr        = nfs4_proc_setattr,
+       .lookupfh       = nfs4_proc_lookupfh,
        .lookup         = nfs4_proc_lookup,
        .access         = nfs4_proc_access,
        .readlink       = nfs4_proc_readlink,
@@ -3718,6 +3746,7 @@ struct nfs_rpc_ops        nfs_v4_clientops = {
        .statfs         = nfs4_proc_statfs,
        .fsinfo         = nfs4_proc_fsinfo,
        .pathconf       = nfs4_proc_pathconf,
+       .set_capabilities = nfs4_server_capabilities,
        .decode_dirent  = nfs4_decode_dirent,
        .read_setup     = nfs4_proc_read_setup,
        .read_done      = nfs4_read_done,