aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 22:16:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 22:16:57 -0400
commit1fad1e9a747687a7399bf58e87974f9b1bbcae06 (patch)
treefde2dc9a35321e21c99e06d4b79d5fa06fd34679 /fs/nfs/nfs4proc.c
parentbbeb0af25f493261c15ceee176c99b7fd6fd5479 (diff)
parentf44106e2173f08ccb1c9195d85a6c22388b461c1 (diff)
Merge tag 'nfs-for-3.6-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Features include: - More preparatory patches for modularising NFSv2/v3/v4. Split out the various NFSv2/v3/v4-specific code into separate files - More preparation for the NFSv4 migration code - Ensure that OPEN(O_CREATE) observes the pNFS mds threshold parameters - pNFS fast failover when the data servers are down - Various cleanups and debugging patches" * tag 'nfs-for-3.6-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (67 commits) nfs: fix fl_type tests in NFSv4 code NFS: fix pnfs regression with directio writes NFS: fix pnfs regression with directio reads sunrpc: clnt: Add missing braces nfs: fix stub return type warnings NFS: exit_nfs_v4() shouldn't be an __exit function SUNRPC: Add a missing spin_unlock to gss_mech_list_pseudoflavors NFS: Split out NFS v4 client functions NFS: Split out the NFS v4 filesystem types NFS: Create a single nfs_clone_super() function NFS: Split out NFS v4 server creating code NFS: Initialize the NFS v4 client from init_nfs_v4() NFS: Move the v4 getroot code to nfs4getroot.c NFS: Split out NFS v4 file operations NFS: Initialize v4 sysctls from nfs_init_v4() NFS: Create an init_nfs_v4() function NFS: Split out NFS v4 inode operations NFS: Split out NFS v3 inode operations NFS: Split out NFS v2 inode operations NFS: Clean up nfs4_proc_setclientid() and friends ...
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c303
1 files changed, 218 insertions, 85 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c157b2089b47..6843e0a37de8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -43,7 +43,6 @@
43#include <linux/printk.h> 43#include <linux/printk.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/sunrpc/clnt.h> 45#include <linux/sunrpc/clnt.h>
46#include <linux/sunrpc/gss_api.h>
47#include <linux/nfs.h> 46#include <linux/nfs.h>
48#include <linux/nfs4.h> 47#include <linux/nfs4.h>
49#include <linux/nfs_fs.h> 48#include <linux/nfs_fs.h>
@@ -259,7 +258,12 @@ static int nfs4_wait_clnt_recover(struct nfs_client *clp)
259 258
260 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, 259 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
261 nfs_wait_bit_killable, TASK_KILLABLE); 260 nfs_wait_bit_killable, TASK_KILLABLE);
262 return res; 261 if (res)
262 return res;
263
264 if (clp->cl_cons_state < 0)
265 return clp->cl_cons_state;
266 return 0;
263} 267}
264 268
265static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) 269static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
@@ -294,8 +298,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
294 case 0: 298 case 0:
295 return 0; 299 return 0;
296 case -NFS4ERR_OPENMODE: 300 case -NFS4ERR_OPENMODE:
297 if (inode && nfs_have_delegation(inode, FMODE_READ)) { 301 if (inode && nfs4_have_delegation(inode, FMODE_READ)) {
298 nfs_inode_return_delegation(inode); 302 nfs4_inode_return_delegation(inode);
299 exception->retry = 1; 303 exception->retry = 1;
300 return 0; 304 return 0;
301 } 305 }
@@ -1065,7 +1069,7 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo
1065 return; 1069 return;
1066 } 1070 }
1067 rcu_read_unlock(); 1071 rcu_read_unlock();
1068 nfs_inode_return_delegation(inode); 1072 nfs4_inode_return_delegation(inode);
1069} 1073}
1070 1074
1071static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) 1075static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
@@ -1756,33 +1760,70 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
1756} 1760}
1757 1761
1758#if defined(CONFIG_NFS_V4_1) 1762#if defined(CONFIG_NFS_V4_1)
1759static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *stateid, unsigned int flags) 1763static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
1760{ 1764{
1761 int status = NFS_OK;
1762 struct nfs_server *server = NFS_SERVER(state->inode); 1765 struct nfs_server *server = NFS_SERVER(state->inode);
1766 nfs4_stateid *stateid = &state->stateid;
1767 int status;
1768
1769 /* If a state reset has been done, test_stateid is unneeded */
1770 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
1771 return;
1763 1772
1764 if (state->flags & flags) { 1773 status = nfs41_test_stateid(server, stateid);
1765 status = nfs41_test_stateid(server, stateid); 1774 if (status != NFS_OK) {
1766 if (status != NFS_OK) { 1775 /* Free the stateid unless the server explicitly
1776 * informs us the stateid is unrecognized. */
1777 if (status != -NFS4ERR_BAD_STATEID)
1767 nfs41_free_stateid(server, stateid); 1778 nfs41_free_stateid(server, stateid);
1768 state->flags &= ~flags; 1779
1769 } 1780 clear_bit(NFS_DELEGATED_STATE, &state->flags);
1781 }
1782}
1783
1784/**
1785 * nfs41_check_open_stateid - possibly free an open stateid
1786 *
1787 * @state: NFSv4 state for an inode
1788 *
1789 * Returns NFS_OK if recovery for this stateid is now finished.
1790 * Otherwise a negative NFS4ERR value is returned.
1791 */
1792static int nfs41_check_open_stateid(struct nfs4_state *state)
1793{
1794 struct nfs_server *server = NFS_SERVER(state->inode);
1795 nfs4_stateid *stateid = &state->stateid;
1796 int status;
1797
1798 /* If a state reset has been done, test_stateid is unneeded */
1799 if ((test_bit(NFS_O_RDONLY_STATE, &state->flags) == 0) &&
1800 (test_bit(NFS_O_WRONLY_STATE, &state->flags) == 0) &&
1801 (test_bit(NFS_O_RDWR_STATE, &state->flags) == 0))
1802 return -NFS4ERR_BAD_STATEID;
1803
1804 status = nfs41_test_stateid(server, stateid);
1805 if (status != NFS_OK) {
1806 /* Free the stateid unless the server explicitly
1807 * informs us the stateid is unrecognized. */
1808 if (status != -NFS4ERR_BAD_STATEID)
1809 nfs41_free_stateid(server, stateid);
1810
1811 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1812 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1813 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1770 } 1814 }
1771 return status; 1815 return status;
1772} 1816}
1773 1817
1774static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) 1818static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
1775{ 1819{
1776 int deleg_status, open_status; 1820 int status;
1777 int deleg_flags = 1 << NFS_DELEGATED_STATE;
1778 int open_flags = (1 << NFS_O_RDONLY_STATE) | (1 << NFS_O_WRONLY_STATE) | (1 << NFS_O_RDWR_STATE);
1779
1780 deleg_status = nfs41_check_expired_stateid(state, &state->stateid, deleg_flags);
1781 open_status = nfs41_check_expired_stateid(state, &state->open_stateid, open_flags);
1782 1821
1783 if ((deleg_status == NFS_OK) && (open_status == NFS_OK)) 1822 nfs41_clear_delegation_stateid(state);
1784 return NFS_OK; 1823 status = nfs41_check_open_stateid(state);
1785 return nfs4_open_expired(sp, state); 1824 if (status != NFS_OK)
1825 status = nfs4_open_expired(sp, state);
1826 return status;
1786} 1827}
1787#endif 1828#endif
1788 1829
@@ -2375,11 +2416,15 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2375 int i, len, status = 0; 2416 int i, len, status = 0;
2376 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS]; 2417 rpc_authflavor_t flav_array[NFS_MAX_SECFLAVORS];
2377 2418
2378 len = gss_mech_list_pseudoflavors(&flav_array[0]); 2419 len = rpcauth_list_flavors(flav_array, ARRAY_SIZE(flav_array));
2379 flav_array[len] = RPC_AUTH_NULL; 2420 BUG_ON(len < 0);
2380 len += 1;
2381 2421
2382 for (i = 0; i < len; i++) { 2422 for (i = 0; i < len; i++) {
2423 /* AUTH_UNIX is the default flavor if none was specified,
2424 * thus has already been tried. */
2425 if (flav_array[i] == RPC_AUTH_UNIX)
2426 continue;
2427
2383 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); 2428 status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
2384 if (status == -NFS4ERR_WRONGSEC || status == -EACCES) 2429 if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
2385 continue; 2430 continue;
@@ -2766,9 +2811,7 @@ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
2766 * 2811 *
2767 * In the case of WRITE, we also want to put the GETATTR after 2812 * In the case of WRITE, we also want to put the GETATTR after
2768 * the operation -- in this case because we want to make sure 2813 * the operation -- in this case because we want to make sure
2769 * we get the post-operation mtime and size. This means that 2814 * we get the post-operation mtime and size.
2770 * we can't use xdr_encode_pages() as written: we need a variant
2771 * of it which would leave room in the 'tail' iovec.
2772 * 2815 *
2773 * Both of these changes to the XDR layer would in fact be quite 2816 * Both of these changes to the XDR layer would in fact be quite
2774 * minor, but I decided to leave them for a subsequent patch. 2817 * minor, but I decided to leave them for a subsequent patch.
@@ -2821,7 +2864,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2821 return PTR_ERR(ctx); 2864 return PTR_ERR(ctx);
2822 2865
2823 sattr->ia_mode &= ~current_umask(); 2866 sattr->ia_mode &= ~current_umask();
2824 state = nfs4_do_open(dir, dentry, ctx->mode, flags, sattr, ctx->cred, NULL); 2867 state = nfs4_do_open(dir, dentry, ctx->mode,
2868 flags, sattr, ctx->cred,
2869 &ctx->mdsthreshold);
2825 d_drop(dentry); 2870 d_drop(dentry);
2826 if (IS_ERR(state)) { 2871 if (IS_ERR(state)) {
2827 status = PTR_ERR(state); 2872 status = PTR_ERR(state);
@@ -3315,8 +3360,14 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
3315 3360
3316static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) 3361static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
3317{ 3362{
3363 int error;
3364
3318 nfs_fattr_init(fsinfo->fattr); 3365 nfs_fattr_init(fsinfo->fattr);
3319 return nfs4_do_fsinfo(server, fhandle, fsinfo); 3366 error = nfs4_do_fsinfo(server, fhandle, fsinfo);
3367 if (error == 0)
3368 set_pnfs_layoutdriver(server, fhandle, fsinfo->layouttype);
3369
3370 return error;
3320} 3371}
3321 3372
3322static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, 3373static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -3443,7 +3494,7 @@ bool nfs4_write_need_cache_consistency_data(const struct nfs_write_data *data)
3443 /* Otherwise, request attributes if and only if we don't hold 3494 /* Otherwise, request attributes if and only if we don't hold
3444 * a delegation 3495 * a delegation
3445 */ 3496 */
3446 return nfs_have_delegation(hdr->inode, FMODE_READ) == 0; 3497 return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
3447} 3498}
3448 3499
3449static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg) 3500static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
@@ -3732,7 +3783,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
3732 .rpc_argp = &args, 3783 .rpc_argp = &args,
3733 .rpc_resp = &res, 3784 .rpc_resp = &res,
3734 }; 3785 };
3735 int ret = -ENOMEM, npages, i, acl_len = 0; 3786 int ret = -ENOMEM, npages, i;
3787 size_t acl_len = 0;
3736 3788
3737 npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; 3789 npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
3738 /* As long as we're doing a round trip to the server anyway, 3790 /* As long as we're doing a round trip to the server anyway,
@@ -3847,7 +3899,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
3847 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 3899 i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
3848 if (i < 0) 3900 if (i < 0)
3849 return i; 3901 return i;
3850 nfs_inode_return_delegation(inode); 3902 nfs4_inode_return_delegation(inode);
3851 ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3903 ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3852 3904
3853 /* 3905 /*
@@ -3961,6 +4013,16 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp,
3961 memcpy(bootverf->data, verf, sizeof(bootverf->data)); 4013 memcpy(bootverf->data, verf, sizeof(bootverf->data));
3962} 4014}
3963 4015
4016/**
4017 * nfs4_proc_setclientid - Negotiate client ID
4018 * @clp: state data structure
4019 * @program: RPC program for NFSv4 callback service
4020 * @port: IP port number for NFS4 callback service
4021 * @cred: RPC credential to use for this call
4022 * @res: where to place the result
4023 *
4024 * Returns zero, a negative errno, or a negative NFS4ERR status code.
4025 */
3964int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, 4026int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3965 unsigned short port, struct rpc_cred *cred, 4027 unsigned short port, struct rpc_cred *cred,
3966 struct nfs4_setclientid_res *res) 4028 struct nfs4_setclientid_res *res)
@@ -3977,44 +4039,44 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3977 .rpc_resp = res, 4039 .rpc_resp = res,
3978 .rpc_cred = cred, 4040 .rpc_cred = cred,
3979 }; 4041 };
3980 int loop = 0;
3981 int status; 4042 int status;
3982 4043
4044 /* nfs_client_id4 */
3983 nfs4_init_boot_verifier(clp, &sc_verifier); 4045 nfs4_init_boot_verifier(clp, &sc_verifier);
3984 4046 rcu_read_lock();
3985 for(;;) { 4047 setclientid.sc_name_len = scnprintf(setclientid.sc_name,
3986 rcu_read_lock(); 4048 sizeof(setclientid.sc_name), "%s/%s %s",
3987 setclientid.sc_name_len = scnprintf(setclientid.sc_name, 4049 clp->cl_ipaddr,
3988 sizeof(setclientid.sc_name), "%s/%s %s %s %u", 4050 rpc_peeraddr2str(clp->cl_rpcclient,
3989 clp->cl_ipaddr, 4051 RPC_DISPLAY_ADDR),
3990 rpc_peeraddr2str(clp->cl_rpcclient, 4052 rpc_peeraddr2str(clp->cl_rpcclient,
3991 RPC_DISPLAY_ADDR), 4053 RPC_DISPLAY_PROTO));
3992 rpc_peeraddr2str(clp->cl_rpcclient, 4054 /* cb_client4 */
3993 RPC_DISPLAY_PROTO), 4055 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
3994 clp->cl_rpcclient->cl_auth->au_ops->au_name,
3995 clp->cl_id_uniquifier);
3996 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
3997 sizeof(setclientid.sc_netid), 4056 sizeof(setclientid.sc_netid),
3998 rpc_peeraddr2str(clp->cl_rpcclient, 4057 rpc_peeraddr2str(clp->cl_rpcclient,
3999 RPC_DISPLAY_NETID)); 4058 RPC_DISPLAY_NETID));
4000 setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr, 4059 rcu_read_unlock();
4060 setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr,
4001 sizeof(setclientid.sc_uaddr), "%s.%u.%u", 4061 sizeof(setclientid.sc_uaddr), "%s.%u.%u",
4002 clp->cl_ipaddr, port >> 8, port & 255); 4062 clp->cl_ipaddr, port >> 8, port & 255);
4003 rcu_read_unlock();
4004 4063
4005 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4064 dprintk("NFS call setclientid auth=%s, '%.*s'\n",
4006 if (status != -NFS4ERR_CLID_INUSE) 4065 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4007 break; 4066 setclientid.sc_name_len, setclientid.sc_name);
4008 if (loop != 0) { 4067 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4009 ++clp->cl_id_uniquifier; 4068 dprintk("NFS reply setclientid: %d\n", status);
4010 break;
4011 }
4012 ++loop;
4013 ssleep(clp->cl_lease_time / HZ + 1);
4014 }
4015 return status; 4069 return status;
4016} 4070}
4017 4071
4072/**
4073 * nfs4_proc_setclientid_confirm - Confirm client ID
4074 * @clp: state data structure
4075 * @res: result of a previous SETCLIENTID
4076 * @cred: RPC credential to use for this call
4077 *
4078 * Returns zero, a negative errno, or a negative NFS4ERR status code.
4079 */
4018int nfs4_proc_setclientid_confirm(struct nfs_client *clp, 4080int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4019 struct nfs4_setclientid_res *arg, 4081 struct nfs4_setclientid_res *arg,
4020 struct rpc_cred *cred) 4082 struct rpc_cred *cred)
@@ -4029,6 +4091,9 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4029 unsigned long now; 4091 unsigned long now;
4030 int status; 4092 int status;
4031 4093
4094 dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n",
4095 clp->cl_rpcclient->cl_auth->au_ops->au_name,
4096 clp->cl_clientid);
4032 now = jiffies; 4097 now = jiffies;
4033 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 4098 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
4034 if (status == 0) { 4099 if (status == 0) {
@@ -4037,6 +4102,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
4037 clp->cl_last_renewal = now; 4102 clp->cl_last_renewal = now;
4038 spin_unlock(&clp->cl_lock); 4103 spin_unlock(&clp->cl_lock);
4039 } 4104 }
4105 dprintk("NFS reply setclientid_confirm: %d\n", status);
4040 return status; 4106 return status;
4041} 4107}
4042 4108
@@ -4681,9 +4747,17 @@ out:
4681} 4747}
4682 4748
4683#if defined(CONFIG_NFS_V4_1) 4749#if defined(CONFIG_NFS_V4_1)
4750/**
4751 * nfs41_check_expired_locks - possibly free a lock stateid
4752 *
4753 * @state: NFSv4 state for an inode
4754 *
4755 * Returns NFS_OK if recovery for this stateid is now finished.
4756 * Otherwise a negative NFS4ERR value is returned.
4757 */
4684static int nfs41_check_expired_locks(struct nfs4_state *state) 4758static int nfs41_check_expired_locks(struct nfs4_state *state)
4685{ 4759{
4686 int status, ret = NFS_OK; 4760 int status, ret = -NFS4ERR_BAD_STATEID;
4687 struct nfs4_lock_state *lsp; 4761 struct nfs4_lock_state *lsp;
4688 struct nfs_server *server = NFS_SERVER(state->inode); 4762 struct nfs_server *server = NFS_SERVER(state->inode);
4689 4763
@@ -4691,7 +4765,11 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
4691 if (lsp->ls_flags & NFS_LOCK_INITIALIZED) { 4765 if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
4692 status = nfs41_test_stateid(server, &lsp->ls_stateid); 4766 status = nfs41_test_stateid(server, &lsp->ls_stateid);
4693 if (status != NFS_OK) { 4767 if (status != NFS_OK) {
4694 nfs41_free_stateid(server, &lsp->ls_stateid); 4768 /* Free the stateid unless the server
4769 * informs us the stateid is unrecognized. */
4770 if (status != -NFS4ERR_BAD_STATEID)
4771 nfs41_free_stateid(server,
4772 &lsp->ls_stateid);
4695 lsp->ls_flags &= ~NFS_LOCK_INITIALIZED; 4773 lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
4696 ret = status; 4774 ret = status;
4697 } 4775 }
@@ -4707,9 +4785,9 @@ static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *reques
4707 4785
4708 if (test_bit(LK_STATE_IN_USE, &state->flags)) 4786 if (test_bit(LK_STATE_IN_USE, &state->flags))
4709 status = nfs41_check_expired_locks(state); 4787 status = nfs41_check_expired_locks(state);
4710 if (status == NFS_OK) 4788 if (status != NFS_OK)
4711 return status; 4789 status = nfs4_lock_expired(state, request);
4712 return nfs4_lock_expired(state, request); 4790 return status;
4713} 4791}
4714#endif 4792#endif
4715 4793
@@ -4807,7 +4885,7 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
4807 * Don't rely on the VFS having checked the file open mode, 4885 * Don't rely on the VFS having checked the file open mode,
4808 * since it won't do this for flock() locks. 4886 * since it won't do this for flock() locks.
4809 */ 4887 */
4810 switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) { 4888 switch (request->fl_type) {
4811 case F_RDLCK: 4889 case F_RDLCK:
4812 if (!(filp->f_mode & FMODE_READ)) 4890 if (!(filp->f_mode & FMODE_READ))
4813 return -EBADF; 4891 return -EBADF;
@@ -5168,6 +5246,8 @@ out:
5168/* 5246/*
5169 * nfs4_proc_exchange_id() 5247 * nfs4_proc_exchange_id()
5170 * 5248 *
5249 * Returns zero, a negative errno, or a negative NFS4ERR status code.
5250 *
5171 * Since the clientid has expired, all compounds using sessions 5251 * Since the clientid has expired, all compounds using sessions
5172 * associated with the stale clientid will be returning 5252 * associated with the stale clientid will be returning
5173 * NFS4ERR_BADSESSION in the sequence operation, and will therefore 5253 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
@@ -5192,16 +5272,14 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5192 .rpc_cred = cred, 5272 .rpc_cred = cred,
5193 }; 5273 };
5194 5274
5195 dprintk("--> %s\n", __func__);
5196 BUG_ON(clp == NULL);
5197
5198 nfs4_init_boot_verifier(clp, &verifier); 5275 nfs4_init_boot_verifier(clp, &verifier);
5199
5200 args.id_len = scnprintf(args.id, sizeof(args.id), 5276 args.id_len = scnprintf(args.id, sizeof(args.id),
5201 "%s/%s/%u", 5277 "%s/%s",
5202 clp->cl_ipaddr, 5278 clp->cl_ipaddr,
5203 clp->cl_rpcclient->cl_nodename, 5279 clp->cl_rpcclient->cl_nodename);
5204 clp->cl_rpcclient->cl_auth->au_flavor); 5280 dprintk("NFS call exchange_id auth=%s, '%.*s'\n",
5281 clp->cl_rpcclient->cl_auth->au_ops->au_name,
5282 args.id_len, args.id);
5205 5283
5206 res.server_owner = kzalloc(sizeof(struct nfs41_server_owner), 5284 res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
5207 GFP_NOFS); 5285 GFP_NOFS);
@@ -5264,12 +5342,12 @@ out_server_scope:
5264 kfree(res.server_scope); 5342 kfree(res.server_scope);
5265out: 5343out:
5266 if (clp->cl_implid != NULL) 5344 if (clp->cl_implid != NULL)
5267 dprintk("%s: Server Implementation ID: " 5345 dprintk("NFS reply exchange_id: Server Implementation ID: "
5268 "domain: %s, name: %s, date: %llu,%u\n", 5346 "domain: %s, name: %s, date: %llu,%u\n",
5269 __func__, clp->cl_implid->domain, clp->cl_implid->name, 5347 clp->cl_implid->domain, clp->cl_implid->name,
5270 clp->cl_implid->date.seconds, 5348 clp->cl_implid->date.seconds,
5271 clp->cl_implid->date.nseconds); 5349 clp->cl_implid->date.nseconds);
5272 dprintk("<-- %s status= %d\n", __func__, status); 5350 dprintk("NFS reply exchange_id: %d\n", status);
5273 return status; 5351 return status;
5274} 5352}
5275 5353
@@ -6570,22 +6648,36 @@ static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6570 .rpc_resp = &res, 6648 .rpc_resp = &res,
6571 }; 6649 };
6572 6650
6651 dprintk("NFS call test_stateid %p\n", stateid);
6573 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 6652 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
6574 status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1); 6653 status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
6575 6654 if (status != NFS_OK) {
6576 if (status == NFS_OK) 6655 dprintk("NFS reply test_stateid: failed, %d\n", status);
6577 return res.status; 6656 return status;
6578 return status; 6657 }
6658 dprintk("NFS reply test_stateid: succeeded, %d\n", -res.status);
6659 return -res.status;
6579} 6660}
6580 6661
6662/**
6663 * nfs41_test_stateid - perform a TEST_STATEID operation
6664 *
6665 * @server: server / transport on which to perform the operation
6666 * @stateid: state ID to test
6667 *
6668 * Returns NFS_OK if the server recognizes that "stateid" is valid.
6669 * Otherwise a negative NFS4ERR value is returned if the operation
6670 * failed or the state ID is not currently valid.
6671 */
6581static int nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid) 6672static int nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6582{ 6673{
6583 struct nfs4_exception exception = { }; 6674 struct nfs4_exception exception = { };
6584 int err; 6675 int err;
6585 do { 6676 do {
6586 err = nfs4_handle_exception(server, 6677 err = _nfs41_test_stateid(server, stateid);
6587 _nfs41_test_stateid(server, stateid), 6678 if (err != -NFS4ERR_DELAY)
6588 &exception); 6679 break;
6680 nfs4_handle_exception(server, err, &exception);
6589 } while (exception.retry); 6681 } while (exception.retry);
6590 return err; 6682 return err;
6591} 6683}
@@ -6601,19 +6693,34 @@ static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6601 .rpc_argp = &args, 6693 .rpc_argp = &args,
6602 .rpc_resp = &res, 6694 .rpc_resp = &res,
6603 }; 6695 };
6696 int status;
6604 6697
6698 dprintk("NFS call free_stateid %p\n", stateid);
6605 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 6699 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
6606 return nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1); 6700 status = nfs4_call_sync_sequence(server->client, server, &msg,
6701 &args.seq_args, &res.seq_res, 1);
6702 dprintk("NFS reply free_stateid: %d\n", status);
6703 return status;
6607} 6704}
6608 6705
6706/**
6707 * nfs41_free_stateid - perform a FREE_STATEID operation
6708 *
6709 * @server: server / transport on which to perform the operation
6710 * @stateid: state ID to release
6711 *
6712 * Returns NFS_OK if the server freed "stateid". Otherwise a
6713 * negative NFS4ERR value is returned.
6714 */
6609static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid) 6715static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6610{ 6716{
6611 struct nfs4_exception exception = { }; 6717 struct nfs4_exception exception = { };
6612 int err; 6718 int err;
6613 do { 6719 do {
6614 err = nfs4_handle_exception(server, 6720 err = _nfs4_free_stateid(server, stateid);
6615 _nfs4_free_stateid(server, stateid), 6721 if (err != -NFS4ERR_DELAY)
6616 &exception); 6722 break;
6723 nfs4_handle_exception(server, err, &exception);
6617 } while (exception.retry); 6724 } while (exception.retry);
6618 return err; 6725 return err;
6619} 6726}
@@ -6725,6 +6832,26 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
6725#endif 6832#endif
6726}; 6833};
6727 6834
6835const struct inode_operations nfs4_dir_inode_operations = {
6836 .create = nfs_create,
6837 .lookup = nfs_lookup,
6838 .atomic_open = nfs_atomic_open,
6839 .link = nfs_link,
6840 .unlink = nfs_unlink,
6841 .symlink = nfs_symlink,
6842 .mkdir = nfs_mkdir,
6843 .rmdir = nfs_rmdir,
6844 .mknod = nfs_mknod,
6845 .rename = nfs_rename,
6846 .permission = nfs_permission,
6847 .getattr = nfs_getattr,
6848 .setattr = nfs_setattr,
6849 .getxattr = generic_getxattr,
6850 .setxattr = generic_setxattr,
6851 .listxattr = generic_listxattr,
6852 .removexattr = generic_removexattr,
6853};
6854
6728static const struct inode_operations nfs4_file_inode_operations = { 6855static const struct inode_operations nfs4_file_inode_operations = {
6729 .permission = nfs_permission, 6856 .permission = nfs_permission,
6730 .getattr = nfs_getattr, 6857 .getattr = nfs_getattr,
@@ -6769,9 +6896,11 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6769 .set_capabilities = nfs4_server_capabilities, 6896 .set_capabilities = nfs4_server_capabilities,
6770 .decode_dirent = nfs4_decode_dirent, 6897 .decode_dirent = nfs4_decode_dirent,
6771 .read_setup = nfs4_proc_read_setup, 6898 .read_setup = nfs4_proc_read_setup,
6899 .read_pageio_init = pnfs_pageio_init_read,
6772 .read_rpc_prepare = nfs4_proc_read_rpc_prepare, 6900 .read_rpc_prepare = nfs4_proc_read_rpc_prepare,
6773 .read_done = nfs4_read_done, 6901 .read_done = nfs4_read_done,
6774 .write_setup = nfs4_proc_write_setup, 6902 .write_setup = nfs4_proc_write_setup,
6903 .write_pageio_init = pnfs_pageio_init_write,
6775 .write_rpc_prepare = nfs4_proc_write_rpc_prepare, 6904 .write_rpc_prepare = nfs4_proc_write_rpc_prepare,
6776 .write_done = nfs4_write_done, 6905 .write_done = nfs4_write_done,
6777 .commit_setup = nfs4_proc_commit_setup, 6906 .commit_setup = nfs4_proc_commit_setup,
@@ -6781,7 +6910,11 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6781 .clear_acl_cache = nfs4_zap_acl_attr, 6910 .clear_acl_cache = nfs4_zap_acl_attr,
6782 .close_context = nfs4_close_context, 6911 .close_context = nfs4_close_context,
6783 .open_context = nfs4_atomic_open, 6912 .open_context = nfs4_atomic_open,
6913 .have_delegation = nfs4_have_delegation,
6914 .return_delegation = nfs4_inode_return_delegation,
6915 .alloc_client = nfs4_alloc_client,
6784 .init_client = nfs4_init_client, 6916 .init_client = nfs4_init_client,
6917 .free_client = nfs4_free_client,
6785}; 6918};
6786 6919
6787static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { 6920static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {