aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c580
1 files changed, 391 insertions, 189 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 99650aaf893..15fc7e4664e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -64,6 +64,7 @@
64#include "iostat.h" 64#include "iostat.h"
65#include "callback.h" 65#include "callback.h"
66#include "pnfs.h" 66#include "pnfs.h"
67#include "netns.h"
67 68
68#define NFSDBG_FACILITY NFSDBG_PROC 69#define NFSDBG_FACILITY NFSDBG_PROC
69 70
@@ -80,6 +81,7 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
80static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 81static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
81static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 82static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
82static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 83static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
84static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *);
83static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 85static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
84static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 86static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
85 struct nfs_fattr *fattr, struct iattr *sattr, 87 struct nfs_fattr *fattr, struct iattr *sattr,
@@ -101,6 +103,10 @@ static int nfs4_map_errors(int err)
101 case -NFS4ERR_BADOWNER: 103 case -NFS4ERR_BADOWNER:
102 case -NFS4ERR_BADNAME: 104 case -NFS4ERR_BADNAME:
103 return -EINVAL; 105 return -EINVAL;
106 case -NFS4ERR_SHARE_DENIED:
107 return -EACCES;
108 case -NFS4ERR_MINOR_VERS_MISMATCH:
109 return -EPROTONOSUPPORT;
104 default: 110 default:
105 dprintk("%s could not handle NFSv4 error %d\n", 111 dprintk("%s could not handle NFSv4 error %d\n",
106 __func__, -err); 112 __func__, -err);
@@ -112,7 +118,7 @@ static int nfs4_map_errors(int err)
112/* 118/*
113 * This is our standard bitmap for GETATTR requests. 119 * This is our standard bitmap for GETATTR requests.
114 */ 120 */
115const u32 nfs4_fattr_bitmap[2] = { 121const u32 nfs4_fattr_bitmap[3] = {
116 FATTR4_WORD0_TYPE 122 FATTR4_WORD0_TYPE
117 | FATTR4_WORD0_CHANGE 123 | FATTR4_WORD0_CHANGE
118 | FATTR4_WORD0_SIZE 124 | FATTR4_WORD0_SIZE
@@ -129,6 +135,24 @@ const u32 nfs4_fattr_bitmap[2] = {
129 | FATTR4_WORD1_TIME_MODIFY 135 | FATTR4_WORD1_TIME_MODIFY
130}; 136};
131 137
138static const u32 nfs4_pnfs_open_bitmap[3] = {
139 FATTR4_WORD0_TYPE
140 | FATTR4_WORD0_CHANGE
141 | FATTR4_WORD0_SIZE
142 | FATTR4_WORD0_FSID
143 | FATTR4_WORD0_FILEID,
144 FATTR4_WORD1_MODE
145 | FATTR4_WORD1_NUMLINKS
146 | FATTR4_WORD1_OWNER
147 | FATTR4_WORD1_OWNER_GROUP
148 | FATTR4_WORD1_RAWDEV
149 | FATTR4_WORD1_SPACE_USED
150 | FATTR4_WORD1_TIME_ACCESS
151 | FATTR4_WORD1_TIME_METADATA
152 | FATTR4_WORD1_TIME_MODIFY,
153 FATTR4_WORD2_MDSTHRESHOLD
154};
155
132const u32 nfs4_statfs_bitmap[2] = { 156const u32 nfs4_statfs_bitmap[2] = {
133 FATTR4_WORD0_FILES_AVAIL 157 FATTR4_WORD0_FILES_AVAIL
134 | FATTR4_WORD0_FILES_FREE 158 | FATTR4_WORD0_FILES_FREE
@@ -304,7 +328,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
304 case -NFS4ERR_SEQ_MISORDERED: 328 case -NFS4ERR_SEQ_MISORDERED:
305 dprintk("%s ERROR: %d Reset session\n", __func__, 329 dprintk("%s ERROR: %d Reset session\n", __func__,
306 errorcode); 330 errorcode);
307 nfs4_schedule_session_recovery(clp->cl_session); 331 nfs4_schedule_session_recovery(clp->cl_session, errorcode);
308 exception->retry = 1; 332 exception->retry = 1;
309 break; 333 break;
310#endif /* defined(CONFIG_NFS_V4_1) */ 334#endif /* defined(CONFIG_NFS_V4_1) */
@@ -772,7 +796,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
772 struct nfs_inode *nfsi = NFS_I(dir); 796 struct nfs_inode *nfsi = NFS_I(dir);
773 797
774 spin_lock(&dir->i_lock); 798 spin_lock(&dir->i_lock);
775 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; 799 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
776 if (!cinfo->atomic || cinfo->before != dir->i_version) 800 if (!cinfo->atomic || cinfo->before != dir->i_version)
777 nfs_force_lookup_revalidate(dir); 801 nfs_force_lookup_revalidate(dir);
778 dir->i_version = cinfo->after; 802 dir->i_version = cinfo->after;
@@ -788,7 +812,6 @@ struct nfs4_opendata {
788 struct nfs4_string owner_name; 812 struct nfs4_string owner_name;
789 struct nfs4_string group_name; 813 struct nfs4_string group_name;
790 struct nfs_fattr f_attr; 814 struct nfs_fattr f_attr;
791 struct nfs_fattr dir_attr;
792 struct dentry *dir; 815 struct dentry *dir;
793 struct dentry *dentry; 816 struct dentry *dentry;
794 struct nfs4_state_owner *owner; 817 struct nfs4_state_owner *owner;
@@ -804,12 +827,10 @@ struct nfs4_opendata {
804static void nfs4_init_opendata_res(struct nfs4_opendata *p) 827static void nfs4_init_opendata_res(struct nfs4_opendata *p)
805{ 828{
806 p->o_res.f_attr = &p->f_attr; 829 p->o_res.f_attr = &p->f_attr;
807 p->o_res.dir_attr = &p->dir_attr;
808 p->o_res.seqid = p->o_arg.seqid; 830 p->o_res.seqid = p->o_arg.seqid;
809 p->c_res.seqid = p->c_arg.seqid; 831 p->c_res.seqid = p->c_arg.seqid;
810 p->o_res.server = p->o_arg.server; 832 p->o_res.server = p->o_arg.server;
811 nfs_fattr_init(&p->f_attr); 833 nfs_fattr_init(&p->f_attr);
812 nfs_fattr_init(&p->dir_attr);
813 nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name); 834 nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
814} 835}
815 836
@@ -843,7 +864,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
843 p->o_arg.name = &dentry->d_name; 864 p->o_arg.name = &dentry->d_name;
844 p->o_arg.server = server; 865 p->o_arg.server = server;
845 p->o_arg.bitmask = server->attr_bitmask; 866 p->o_arg.bitmask = server->attr_bitmask;
846 p->o_arg.dir_bitmask = server->cache_consistency_bitmask; 867 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
847 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 868 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
848 if (attrs != NULL && attrs->ia_valid != 0) { 869 if (attrs != NULL && attrs->ia_valid != 0) {
849 __be32 verf[2]; 870 __be32 verf[2];
@@ -1332,7 +1353,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1332 case -NFS4ERR_BAD_HIGH_SLOT: 1353 case -NFS4ERR_BAD_HIGH_SLOT:
1333 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1354 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1334 case -NFS4ERR_DEADSESSION: 1355 case -NFS4ERR_DEADSESSION:
1335 nfs4_schedule_session_recovery(server->nfs_client->cl_session); 1356 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
1336 goto out; 1357 goto out;
1337 case -NFS4ERR_STALE_CLIENTID: 1358 case -NFS4ERR_STALE_CLIENTID:
1338 case -NFS4ERR_STALE_STATEID: 1359 case -NFS4ERR_STALE_STATEID:
@@ -1611,8 +1632,6 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1611 1632
1612 nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr); 1633 nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr);
1613 1634
1614 nfs_refresh_inode(dir, o_res->dir_attr);
1615
1616 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 1635 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1617 status = _nfs4_proc_open_confirm(data); 1636 status = _nfs4_proc_open_confirm(data);
1618 if (status != 0) 1637 if (status != 0)
@@ -1645,11 +1664,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1645 1664
1646 nfs_fattr_map_and_free_names(server, &data->f_attr); 1665 nfs_fattr_map_and_free_names(server, &data->f_attr);
1647 1666
1648 if (o_arg->open_flags & O_CREAT) { 1667 if (o_arg->open_flags & O_CREAT)
1649 update_changeattr(dir, &o_res->cinfo); 1668 update_changeattr(dir, &o_res->cinfo);
1650 nfs_post_op_update_inode(dir, o_res->dir_attr);
1651 } else
1652 nfs_refresh_inode(dir, o_res->dir_attr);
1653 if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) 1669 if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
1654 server->caps &= ~NFS_CAP_POSIX_LOCK; 1670 server->caps &= ~NFS_CAP_POSIX_LOCK;
1655 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 1671 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
@@ -1789,7 +1805,14 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
1789/* 1805/*
1790 * Returns a referenced nfs4_state 1806 * Returns a referenced nfs4_state
1791 */ 1807 */
1792static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) 1808static int _nfs4_do_open(struct inode *dir,
1809 struct dentry *dentry,
1810 fmode_t fmode,
1811 int flags,
1812 struct iattr *sattr,
1813 struct rpc_cred *cred,
1814 struct nfs4_state **res,
1815 struct nfs4_threshold **ctx_th)
1793{ 1816{
1794 struct nfs4_state_owner *sp; 1817 struct nfs4_state_owner *sp;
1795 struct nfs4_state *state = NULL; 1818 struct nfs4_state *state = NULL;
@@ -1814,6 +1837,12 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode
1814 if (opendata == NULL) 1837 if (opendata == NULL)
1815 goto err_put_state_owner; 1838 goto err_put_state_owner;
1816 1839
1840 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
1841 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
1842 if (!opendata->f_attr.mdsthreshold)
1843 goto err_opendata_put;
1844 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
1845 }
1817 if (dentry->d_inode != NULL) 1846 if (dentry->d_inode != NULL)
1818 opendata->state = nfs4_get_open_state(dentry->d_inode, sp); 1847 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
1819 1848
@@ -1839,11 +1868,19 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode
1839 nfs_setattr_update_inode(state->inode, sattr); 1868 nfs_setattr_update_inode(state->inode, sattr);
1840 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 1869 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
1841 } 1870 }
1871
1872 if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
1873 *ctx_th = opendata->f_attr.mdsthreshold;
1874 else
1875 kfree(opendata->f_attr.mdsthreshold);
1876 opendata->f_attr.mdsthreshold = NULL;
1877
1842 nfs4_opendata_put(opendata); 1878 nfs4_opendata_put(opendata);
1843 nfs4_put_state_owner(sp); 1879 nfs4_put_state_owner(sp);
1844 *res = state; 1880 *res = state;
1845 return 0; 1881 return 0;
1846err_opendata_put: 1882err_opendata_put:
1883 kfree(opendata->f_attr.mdsthreshold);
1847 nfs4_opendata_put(opendata); 1884 nfs4_opendata_put(opendata);
1848err_put_state_owner: 1885err_put_state_owner:
1849 nfs4_put_state_owner(sp); 1886 nfs4_put_state_owner(sp);
@@ -1853,14 +1890,22 @@ out_err:
1853} 1890}
1854 1891
1855 1892
1856static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) 1893static struct nfs4_state *nfs4_do_open(struct inode *dir,
1894 struct dentry *dentry,
1895 fmode_t fmode,
1896 int flags,
1897 struct iattr *sattr,
1898 struct rpc_cred *cred,
1899 struct nfs4_threshold **ctx_th)
1857{ 1900{
1858 struct nfs4_exception exception = { }; 1901 struct nfs4_exception exception = { };
1859 struct nfs4_state *res; 1902 struct nfs4_state *res;
1860 int status; 1903 int status;
1861 1904
1905 fmode &= FMODE_READ|FMODE_WRITE;
1862 do { 1906 do {
1863 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, &res); 1907 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
1908 &res, ctx_th);
1864 if (status == 0) 1909 if (status == 0)
1865 break; 1910 break;
1866 /* NOTE: BAD_SEQID means the server and client disagree about the 1911 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -2184,7 +2229,8 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags
2184 struct nfs4_state *state; 2229 struct nfs4_state *state;
2185 2230
2186 /* Protect against concurrent sillydeletes */ 2231 /* Protect against concurrent sillydeletes */
2187 state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, ctx->cred); 2232 state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr,
2233 ctx->cred, &ctx->mdsthreshold);
2188 if (IS_ERR(state)) 2234 if (IS_ERR(state))
2189 return ERR_CAST(state); 2235 return ERR_CAST(state);
2190 ctx->state = state; 2236 ctx->state = state;
@@ -2354,8 +2400,8 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
2354/* 2400/*
2355 * get the file handle for the "/" directory on the server 2401 * get the file handle for the "/" directory on the server
2356 */ 2402 */
2357static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 2403int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
2358 struct nfs_fsinfo *info) 2404 struct nfs_fsinfo *info)
2359{ 2405{
2360 int minor_version = server->nfs_client->cl_minorversion; 2406 int minor_version = server->nfs_client->cl_minorversion;
2361 int status = nfs4_lookup_root(server, fhandle, info); 2407 int status = nfs4_lookup_root(server, fhandle, info);
@@ -2372,6 +2418,31 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
2372 return nfs4_map_errors(status); 2418 return nfs4_map_errors(status);
2373} 2419}
2374 2420
2421static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
2422 struct nfs_fsinfo *info)
2423{
2424 int error;
2425 struct nfs_fattr *fattr = info->fattr;
2426
2427 error = nfs4_server_capabilities(server, mntfh);
2428 if (error < 0) {
2429 dprintk("nfs4_get_root: getcaps error = %d\n", -error);
2430 return error;
2431 }
2432
2433 error = nfs4_proc_getattr(server, mntfh, fattr);
2434 if (error < 0) {
2435 dprintk("nfs4_get_root: getattr error = %d\n", -error);
2436 return error;
2437 }
2438
2439 if (fattr->valid & NFS_ATTR_FATTR_FSID &&
2440 !nfs_fsid_equal(&server->fsid, &fattr->fsid))
2441 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
2442
2443 return error;
2444}
2445
2375/* 2446/*
2376 * Get locations and (maybe) other attributes of a referral. 2447 * Get locations and (maybe) other attributes of a referral.
2377 * Note that we'll actually follow the referral later when 2448 * Note that we'll actually follow the referral later when
@@ -2478,6 +2549,14 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2478 2549
2479 nfs_fattr_init(fattr); 2550 nfs_fattr_init(fattr);
2480 2551
2552 /* Deal with open(O_TRUNC) */
2553 if (sattr->ia_valid & ATTR_OPEN)
2554 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
2555
2556 /* Optimization: if the end result is no change, don't RPC */
2557 if ((sattr->ia_valid & ~(ATTR_FILE)) == 0)
2558 return 0;
2559
2481 /* Search for an existing open(O_WRITE) file */ 2560 /* Search for an existing open(O_WRITE) file */
2482 if (sattr->ia_valid & ATTR_FILE) { 2561 if (sattr->ia_valid & ATTR_FILE) {
2483 struct nfs_open_context *ctx; 2562 struct nfs_open_context *ctx;
@@ -2489,10 +2568,6 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2489 } 2568 }
2490 } 2569 }
2491 2570
2492 /* Deal with open(O_TRUNC) */
2493 if (sattr->ia_valid & ATTR_OPEN)
2494 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
2495
2496 status = nfs4_do_setattr(inode, cred, fattr, sattr, state); 2571 status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
2497 if (status == 0) 2572 if (status == 0)
2498 nfs_setattr_update_inode(inode, sattr); 2573 nfs_setattr_update_inode(inode, sattr);
@@ -2578,7 +2653,7 @@ out:
2578 return err; 2653 return err;
2579} 2654}
2580 2655
2581static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, 2656static int nfs4_proc_lookup(struct inode *dir, struct qstr *name,
2582 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2657 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2583{ 2658{
2584 int status; 2659 int status;
@@ -2761,7 +2836,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2761 fmode = ctx->mode; 2836 fmode = ctx->mode;
2762 } 2837 }
2763 sattr->ia_mode &= ~current_umask(); 2838 sattr->ia_mode &= ~current_umask();
2764 state = nfs4_do_open(dir, de, fmode, flags, sattr, cred); 2839 state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL);
2765 d_drop(dentry); 2840 d_drop(dentry);
2766 if (IS_ERR(state)) { 2841 if (IS_ERR(state)) {
2767 status = PTR_ERR(state); 2842 status = PTR_ERR(state);
@@ -2782,9 +2857,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
2782 struct nfs_server *server = NFS_SERVER(dir); 2857 struct nfs_server *server = NFS_SERVER(dir);
2783 struct nfs_removeargs args = { 2858 struct nfs_removeargs args = {
2784 .fh = NFS_FH(dir), 2859 .fh = NFS_FH(dir),
2785 .name.len = name->len, 2860 .name = *name,
2786 .name.name = name->name,
2787 .bitmask = server->attr_bitmask,
2788 }; 2861 };
2789 struct nfs_removeres res = { 2862 struct nfs_removeres res = {
2790 .server = server, 2863 .server = server,
@@ -2794,19 +2867,11 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
2794 .rpc_argp = &args, 2867 .rpc_argp = &args,
2795 .rpc_resp = &res, 2868 .rpc_resp = &res,
2796 }; 2869 };
2797 int status = -ENOMEM; 2870 int status;
2798
2799 res.dir_attr = nfs_alloc_fattr();
2800 if (res.dir_attr == NULL)
2801 goto out;
2802 2871
2803 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1); 2872 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
2804 if (status == 0) { 2873 if (status == 0)
2805 update_changeattr(dir, &res.cinfo); 2874 update_changeattr(dir, &res.cinfo);
2806 nfs_post_op_update_inode(dir, res.dir_attr);
2807 }
2808 nfs_free_fattr(res.dir_attr);
2809out:
2810 return status; 2875 return status;
2811} 2876}
2812 2877
@@ -2828,7 +2893,6 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
2828 struct nfs_removeargs *args = msg->rpc_argp; 2893 struct nfs_removeargs *args = msg->rpc_argp;
2829 struct nfs_removeres *res = msg->rpc_resp; 2894 struct nfs_removeres *res = msg->rpc_resp;
2830 2895
2831 args->bitmask = server->cache_consistency_bitmask;
2832 res->server = server; 2896 res->server = server;
2833 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 2897 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
2834 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1); 2898 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1);
@@ -2853,7 +2917,6 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2853 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2917 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2854 return 0; 2918 return 0;
2855 update_changeattr(dir, &res->cinfo); 2919 update_changeattr(dir, &res->cinfo);
2856 nfs_post_op_update_inode(dir, res->dir_attr);
2857 return 1; 2920 return 1;
2858} 2921}
2859 2922
@@ -2864,7 +2927,6 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
2864 struct nfs_renameres *res = msg->rpc_resp; 2927 struct nfs_renameres *res = msg->rpc_resp;
2865 2928
2866 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; 2929 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
2867 arg->bitmask = server->attr_bitmask;
2868 res->server = server; 2930 res->server = server;
2869 nfs41_init_sequence(&arg->seq_args, &res->seq_res, 1); 2931 nfs41_init_sequence(&arg->seq_args, &res->seq_res, 1);
2870} 2932}
@@ -2890,9 +2952,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
2890 return 0; 2952 return 0;
2891 2953
2892 update_changeattr(old_dir, &res->old_cinfo); 2954 update_changeattr(old_dir, &res->old_cinfo);
2893 nfs_post_op_update_inode(old_dir, res->old_fattr);
2894 update_changeattr(new_dir, &res->new_cinfo); 2955 update_changeattr(new_dir, &res->new_cinfo);
2895 nfs_post_op_update_inode(new_dir, res->new_fattr);
2896 return 1; 2956 return 1;
2897} 2957}
2898 2958
@@ -2905,7 +2965,6 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2905 .new_dir = NFS_FH(new_dir), 2965 .new_dir = NFS_FH(new_dir),
2906 .old_name = old_name, 2966 .old_name = old_name,
2907 .new_name = new_name, 2967 .new_name = new_name,
2908 .bitmask = server->attr_bitmask,
2909 }; 2968 };
2910 struct nfs_renameres res = { 2969 struct nfs_renameres res = {
2911 .server = server, 2970 .server = server,
@@ -2917,21 +2976,11 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2917 }; 2976 };
2918 int status = -ENOMEM; 2977 int status = -ENOMEM;
2919 2978
2920 res.old_fattr = nfs_alloc_fattr();
2921 res.new_fattr = nfs_alloc_fattr();
2922 if (res.old_fattr == NULL || res.new_fattr == NULL)
2923 goto out;
2924
2925 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 2979 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
2926 if (!status) { 2980 if (!status) {
2927 update_changeattr(old_dir, &res.old_cinfo); 2981 update_changeattr(old_dir, &res.old_cinfo);
2928 nfs_post_op_update_inode(old_dir, res.old_fattr);
2929 update_changeattr(new_dir, &res.new_cinfo); 2982 update_changeattr(new_dir, &res.new_cinfo);
2930 nfs_post_op_update_inode(new_dir, res.new_fattr);
2931 } 2983 }
2932out:
2933 nfs_free_fattr(res.new_fattr);
2934 nfs_free_fattr(res.old_fattr);
2935 return status; 2984 return status;
2936} 2985}
2937 2986
@@ -2969,18 +3018,15 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
2969 int status = -ENOMEM; 3018 int status = -ENOMEM;
2970 3019
2971 res.fattr = nfs_alloc_fattr(); 3020 res.fattr = nfs_alloc_fattr();
2972 res.dir_attr = nfs_alloc_fattr(); 3021 if (res.fattr == NULL)
2973 if (res.fattr == NULL || res.dir_attr == NULL)
2974 goto out; 3022 goto out;
2975 3023
2976 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3024 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
2977 if (!status) { 3025 if (!status) {
2978 update_changeattr(dir, &res.cinfo); 3026 update_changeattr(dir, &res.cinfo);
2979 nfs_post_op_update_inode(dir, res.dir_attr);
2980 nfs_post_op_update_inode(inode, res.fattr); 3027 nfs_post_op_update_inode(inode, res.fattr);
2981 } 3028 }
2982out: 3029out:
2983 nfs_free_fattr(res.dir_attr);
2984 nfs_free_fattr(res.fattr); 3030 nfs_free_fattr(res.fattr);
2985 return status; 3031 return status;
2986} 3032}
@@ -3003,7 +3049,6 @@ struct nfs4_createdata {
3003 struct nfs4_create_res res; 3049 struct nfs4_create_res res;
3004 struct nfs_fh fh; 3050 struct nfs_fh fh;
3005 struct nfs_fattr fattr; 3051 struct nfs_fattr fattr;
3006 struct nfs_fattr dir_fattr;
3007}; 3052};
3008 3053
3009static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, 3054static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
@@ -3027,9 +3072,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
3027 data->res.server = server; 3072 data->res.server = server;
3028 data->res.fh = &data->fh; 3073 data->res.fh = &data->fh;
3029 data->res.fattr = &data->fattr; 3074 data->res.fattr = &data->fattr;
3030 data->res.dir_fattr = &data->dir_fattr;
3031 nfs_fattr_init(data->res.fattr); 3075 nfs_fattr_init(data->res.fattr);
3032 nfs_fattr_init(data->res.dir_fattr);
3033 } 3076 }
3034 return data; 3077 return data;
3035} 3078}
@@ -3040,7 +3083,6 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
3040 &data->arg.seq_args, &data->res.seq_res, 1); 3083 &data->arg.seq_args, &data->res.seq_res, 1);
3041 if (status == 0) { 3084 if (status == 0) {
3042 update_changeattr(dir, &data->res.dir_cinfo); 3085 update_changeattr(dir, &data->res.dir_cinfo);
3043 nfs_post_op_update_inode(dir, data->res.dir_fattr);
3044 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 3086 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
3045 } 3087 }
3046 return status; 3088 return status;
@@ -3336,12 +3378,12 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
3336 3378
3337void __nfs4_read_done_cb(struct nfs_read_data *data) 3379void __nfs4_read_done_cb(struct nfs_read_data *data)
3338{ 3380{
3339 nfs_invalidate_atime(data->inode); 3381 nfs_invalidate_atime(data->header->inode);
3340} 3382}
3341 3383
3342static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) 3384static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3343{ 3385{
3344 struct nfs_server *server = NFS_SERVER(data->inode); 3386 struct nfs_server *server = NFS_SERVER(data->header->inode);
3345 3387
3346 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3388 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
3347 rpc_restart_call_prepare(task); 3389 rpc_restart_call_prepare(task);
@@ -3376,7 +3418,7 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
3376 3418
3377static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data) 3419static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
3378{ 3420{
3379 if (nfs4_setup_sequence(NFS_SERVER(data->inode), 3421 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3380 &data->args.seq_args, 3422 &data->args.seq_args,
3381 &data->res.seq_res, 3423 &data->res.seq_res,
3382 task)) 3424 task))
@@ -3384,25 +3426,9 @@ static void nfs4_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_da
3384 rpc_call_start(task); 3426 rpc_call_start(task);
3385} 3427}
3386 3428
3387/* Reset the the nfs_read_data to send the read to the MDS. */
3388void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data)
3389{
3390 dprintk("%s Reset task for i/o through\n", __func__);
3391 put_lseg(data->lseg);
3392 data->lseg = NULL;
3393 /* offsets will differ in the dense stripe case */
3394 data->args.offset = data->mds_offset;
3395 data->ds_clp = NULL;
3396 data->args.fh = NFS_FH(data->inode);
3397 data->read_done_cb = nfs4_read_done_cb;
3398 task->tk_ops = data->mds_ops;
3399 rpc_task_reset_client(task, NFS_CLIENT(data->inode));
3400}
3401EXPORT_SYMBOL_GPL(nfs4_reset_read);
3402
3403static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data) 3429static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data)
3404{ 3430{
3405 struct inode *inode = data->inode; 3431 struct inode *inode = data->header->inode;
3406 3432
3407 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3433 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3408 rpc_restart_call_prepare(task); 3434 rpc_restart_call_prepare(task);
@@ -3410,7 +3436,7 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data
3410 } 3436 }
3411 if (task->tk_status >= 0) { 3437 if (task->tk_status >= 0) {
3412 renew_lease(NFS_SERVER(inode), data->timestamp); 3438 renew_lease(NFS_SERVER(inode), data->timestamp);
3413 nfs_post_op_update_inode_force_wcc(inode, data->res.fattr); 3439 nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
3414 } 3440 }
3415 return 0; 3441 return 0;
3416} 3442}
@@ -3423,32 +3449,30 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
3423 nfs4_write_done_cb(task, data); 3449 nfs4_write_done_cb(task, data);
3424} 3450}
3425 3451
3426/* Reset the the nfs_write_data to send the write to the MDS. */ 3452static
3427void nfs4_reset_write(struct rpc_task *task, struct nfs_write_data *data) 3453bool nfs4_write_need_cache_consistency_data(const struct nfs_write_data *data)
3428{ 3454{
3429 dprintk("%s Reset task for i/o through\n", __func__); 3455 const struct nfs_pgio_header *hdr = data->header;
3430 put_lseg(data->lseg); 3456
3431 data->lseg = NULL; 3457 /* Don't request attributes for pNFS or O_DIRECT writes */
3432 data->ds_clp = NULL; 3458 if (data->ds_clp != NULL || hdr->dreq != NULL)
3433 data->write_done_cb = nfs4_write_done_cb; 3459 return false;
3434 data->args.fh = NFS_FH(data->inode); 3460 /* Otherwise, request attributes if and only if we don't hold
3435 data->args.bitmask = data->res.server->cache_consistency_bitmask; 3461 * a delegation
3436 data->args.offset = data->mds_offset; 3462 */
3437 data->res.fattr = &data->fattr; 3463 return nfs_have_delegation(hdr->inode, FMODE_READ) == 0;
3438 task->tk_ops = data->mds_ops;
3439 rpc_task_reset_client(task, NFS_CLIENT(data->inode));
3440} 3464}
3441EXPORT_SYMBOL_GPL(nfs4_reset_write);
3442 3465
3443static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg) 3466static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
3444{ 3467{
3445 struct nfs_server *server = NFS_SERVER(data->inode); 3468 struct nfs_server *server = NFS_SERVER(data->header->inode);
3446 3469
3447 if (data->lseg) { 3470 if (!nfs4_write_need_cache_consistency_data(data)) {
3448 data->args.bitmask = NULL; 3471 data->args.bitmask = NULL;
3449 data->res.fattr = NULL; 3472 data->res.fattr = NULL;
3450 } else 3473 } else
3451 data->args.bitmask = server->cache_consistency_bitmask; 3474 data->args.bitmask = server->cache_consistency_bitmask;
3475
3452 if (!data->write_done_cb) 3476 if (!data->write_done_cb)
3453 data->write_done_cb = nfs4_write_done_cb; 3477 data->write_done_cb = nfs4_write_done_cb;
3454 data->res.server = server; 3478 data->res.server = server;
@@ -3460,6 +3484,16 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
3460 3484
3461static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data) 3485static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
3462{ 3486{
3487 if (nfs4_setup_sequence(NFS_SERVER(data->header->inode),
3488 &data->args.seq_args,
3489 &data->res.seq_res,
3490 task))
3491 return;
3492 rpc_call_start(task);
3493}
3494
3495static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
3496{
3463 if (nfs4_setup_sequence(NFS_SERVER(data->inode), 3497 if (nfs4_setup_sequence(NFS_SERVER(data->inode),
3464 &data->args.seq_args, 3498 &data->args.seq_args,
3465 &data->res.seq_res, 3499 &data->res.seq_res,
@@ -3468,7 +3502,7 @@ static void nfs4_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_
3468 rpc_call_start(task); 3502 rpc_call_start(task);
3469} 3503}
3470 3504
3471static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *data) 3505static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_commit_data *data)
3472{ 3506{
3473 struct inode *inode = data->inode; 3507 struct inode *inode = data->inode;
3474 3508
@@ -3476,28 +3510,22 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *dat
3476 rpc_restart_call_prepare(task); 3510 rpc_restart_call_prepare(task);
3477 return -EAGAIN; 3511 return -EAGAIN;
3478 } 3512 }
3479 nfs_refresh_inode(inode, data->res.fattr);
3480 return 0; 3513 return 0;
3481} 3514}
3482 3515
3483static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) 3516static int nfs4_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
3484{ 3517{
3485 if (!nfs4_sequence_done(task, &data->res.seq_res)) 3518 if (!nfs4_sequence_done(task, &data->res.seq_res))
3486 return -EAGAIN; 3519 return -EAGAIN;
3487 return data->write_done_cb(task, data); 3520 return data->commit_done_cb(task, data);
3488} 3521}
3489 3522
3490static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) 3523static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)
3491{ 3524{
3492 struct nfs_server *server = NFS_SERVER(data->inode); 3525 struct nfs_server *server = NFS_SERVER(data->inode);
3493 3526
3494 if (data->lseg) { 3527 if (data->commit_done_cb == NULL)
3495 data->args.bitmask = NULL; 3528 data->commit_done_cb = nfs4_commit_done_cb;
3496 data->res.fattr = NULL;
3497 } else
3498 data->args.bitmask = server->cache_consistency_bitmask;
3499 if (!data->write_done_cb)
3500 data->write_done_cb = nfs4_commit_done_cb;
3501 data->res.server = server; 3529 data->res.server = server;
3502 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; 3530 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
3503 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 3531 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
@@ -3906,7 +3934,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3906 case -NFS4ERR_SEQ_MISORDERED: 3934 case -NFS4ERR_SEQ_MISORDERED:
3907 dprintk("%s ERROR %d, Reset session\n", __func__, 3935 dprintk("%s ERROR %d, Reset session\n", __func__,
3908 task->tk_status); 3936 task->tk_status);
3909 nfs4_schedule_session_recovery(clp->cl_session); 3937 nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
3910 task->tk_status = 0; 3938 task->tk_status = 0;
3911 return -EAGAIN; 3939 return -EAGAIN;
3912#endif /* CONFIG_NFS_V4_1 */ 3940#endif /* CONFIG_NFS_V4_1 */
@@ -3932,13 +3960,21 @@ wait_on_recovery:
3932 return -EAGAIN; 3960 return -EAGAIN;
3933} 3961}
3934 3962
3935static void nfs4_construct_boot_verifier(struct nfs_client *clp, 3963static void nfs4_init_boot_verifier(const struct nfs_client *clp,
3936 nfs4_verifier *bootverf) 3964 nfs4_verifier *bootverf)
3937{ 3965{
3938 __be32 verf[2]; 3966 __be32 verf[2];
3939 3967
3940 verf[0] = htonl((u32)clp->cl_boot_time.tv_sec); 3968 if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
3941 verf[1] = htonl((u32)clp->cl_boot_time.tv_nsec); 3969 /* An impossible timestamp guarantees this value
3970 * will never match a generated boot time. */
3971 verf[0] = 0;
3972 verf[1] = (__be32)(NSEC_PER_SEC + 1);
3973 } else {
3974 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
3975 verf[0] = (__be32)nn->boot_time.tv_sec;
3976 verf[1] = (__be32)nn->boot_time.tv_nsec;
3977 }
3942 memcpy(bootverf->data, verf, sizeof(bootverf->data)); 3978 memcpy(bootverf->data, verf, sizeof(bootverf->data));
3943} 3979}
3944 3980
@@ -3961,7 +3997,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3961 int loop = 0; 3997 int loop = 0;
3962 int status; 3998 int status;
3963 3999
3964 nfs4_construct_boot_verifier(clp, &sc_verifier); 4000 nfs4_init_boot_verifier(clp, &sc_verifier);
3965 4001
3966 for(;;) { 4002 for(;;) {
3967 rcu_read_lock(); 4003 rcu_read_lock();
@@ -4105,7 +4141,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
4105 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1); 4141 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
4106 data->args.fhandle = &data->fh; 4142 data->args.fhandle = &data->fh;
4107 data->args.stateid = &data->stateid; 4143 data->args.stateid = &data->stateid;
4108 data->args.bitmask = server->attr_bitmask; 4144 data->args.bitmask = server->cache_consistency_bitmask;
4109 nfs_copy_fh(&data->fh, NFS_FH(inode)); 4145 nfs_copy_fh(&data->fh, NFS_FH(inode));
4110 nfs4_stateid_copy(&data->stateid, stateid); 4146 nfs4_stateid_copy(&data->stateid, stateid);
4111 data->res.fattr = &data->fattr; 4147 data->res.fattr = &data->fattr;
@@ -4126,9 +4162,10 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
4126 if (status != 0) 4162 if (status != 0)
4127 goto out; 4163 goto out;
4128 status = data->rpc_status; 4164 status = data->rpc_status;
4129 if (status != 0) 4165 if (status == 0)
4130 goto out; 4166 nfs_post_op_update_inode_force_wcc(inode, &data->fattr);
4131 nfs_refresh_inode(inode, &data->fattr); 4167 else
4168 nfs_refresh_inode(inode, &data->fattr);
4132out: 4169out:
4133 rpc_put_task(task); 4170 rpc_put_task(task);
4134 return status; 4171 return status;
@@ -4838,7 +4875,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4838 case -NFS4ERR_BAD_HIGH_SLOT: 4875 case -NFS4ERR_BAD_HIGH_SLOT:
4839 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 4876 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4840 case -NFS4ERR_DEADSESSION: 4877 case -NFS4ERR_DEADSESSION:
4841 nfs4_schedule_session_recovery(server->nfs_client->cl_session); 4878 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
4842 goto out; 4879 goto out;
4843 case -ERESTARTSYS: 4880 case -ERESTARTSYS:
4844 /* 4881 /*
@@ -5080,7 +5117,8 @@ out_inval:
5080} 5117}
5081 5118
5082static bool 5119static bool
5083nfs41_same_server_scope(struct server_scope *a, struct server_scope *b) 5120nfs41_same_server_scope(struct nfs41_server_scope *a,
5121 struct nfs41_server_scope *b)
5084{ 5122{
5085 if (a->server_scope_sz == b->server_scope_sz && 5123 if (a->server_scope_sz == b->server_scope_sz &&
5086 memcmp(a->server_scope, b->server_scope, a->server_scope_sz) == 0) 5124 memcmp(a->server_scope, b->server_scope, a->server_scope_sz) == 0)
@@ -5090,6 +5128,61 @@ nfs41_same_server_scope(struct server_scope *a, struct server_scope *b)
5090} 5128}
5091 5129
5092/* 5130/*
5131 * nfs4_proc_bind_conn_to_session()
5132 *
5133 * The 4.1 client currently uses the same TCP connection for the
5134 * fore and backchannel.
5135 */
5136int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred)
5137{
5138 int status;
5139 struct nfs41_bind_conn_to_session_res res;
5140 struct rpc_message msg = {
5141 .rpc_proc =
5142 &nfs4_procedures[NFSPROC4_CLNT_BIND_CONN_TO_SESSION],
5143 .rpc_argp = clp,
5144 .rpc_resp = &res,
5145 .rpc_cred = cred,
5146 };
5147
5148 dprintk("--> %s\n", __func__);
5149 BUG_ON(clp == NULL);
5150
5151 res.session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
5152 if (unlikely(res.session == NULL)) {
5153 status = -ENOMEM;
5154 goto out;
5155 }
5156
5157 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5158 if (status == 0) {
5159 if (memcmp(res.session->sess_id.data,
5160 clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) {
5161 dprintk("NFS: %s: Session ID mismatch\n", __func__);
5162 status = -EIO;
5163 goto out_session;
5164 }
5165 if (res.dir != NFS4_CDFS4_BOTH) {
5166 dprintk("NFS: %s: Unexpected direction from server\n",
5167 __func__);
5168 status = -EIO;
5169 goto out_session;
5170 }
5171 if (res.use_conn_in_rdma_mode) {
5172 dprintk("NFS: %s: Server returned RDMA mode = true\n",
5173 __func__);
5174 status = -EIO;
5175 goto out_session;
5176 }
5177 }
5178out_session:
5179 kfree(res.session);
5180out:
5181 dprintk("<-- %s status= %d\n", __func__, status);
5182 return status;
5183}
5184
5185/*
5093 * nfs4_proc_exchange_id() 5186 * nfs4_proc_exchange_id()
5094 * 5187 *
5095 * Since the clientid has expired, all compounds using sessions 5188 * Since the clientid has expired, all compounds using sessions
@@ -5106,7 +5199,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5106 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER, 5199 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
5107 }; 5200 };
5108 struct nfs41_exchange_id_res res = { 5201 struct nfs41_exchange_id_res res = {
5109 .client = clp, 5202 0
5110 }; 5203 };
5111 int status; 5204 int status;
5112 struct rpc_message msg = { 5205 struct rpc_message msg = {
@@ -5119,7 +5212,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5119 dprintk("--> %s\n", __func__); 5212 dprintk("--> %s\n", __func__);
5120 BUG_ON(clp == NULL); 5213 BUG_ON(clp == NULL);
5121 5214
5122 nfs4_construct_boot_verifier(clp, &verifier); 5215 nfs4_init_boot_verifier(clp, &verifier);
5123 5216
5124 args.id_len = scnprintf(args.id, sizeof(args.id), 5217 args.id_len = scnprintf(args.id, sizeof(args.id),
5125 "%s/%s/%u", 5218 "%s/%s/%u",
@@ -5127,59 +5220,135 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5127 clp->cl_rpcclient->cl_nodename, 5220 clp->cl_rpcclient->cl_nodename,
5128 clp->cl_rpcclient->cl_auth->au_flavor); 5221 clp->cl_rpcclient->cl_auth->au_flavor);
5129 5222
5130 res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); 5223 res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
5131 if (unlikely(!res.server_scope)) { 5224 GFP_NOFS);
5225 if (unlikely(res.server_owner == NULL)) {
5132 status = -ENOMEM; 5226 status = -ENOMEM;
5133 goto out; 5227 goto out;
5134 } 5228 }
5135 5229
5136 res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_KERNEL); 5230 res.server_scope = kzalloc(sizeof(struct nfs41_server_scope),
5137 if (unlikely(!res.impl_id)) { 5231 GFP_NOFS);
5232 if (unlikely(res.server_scope == NULL)) {
5233 status = -ENOMEM;
5234 goto out_server_owner;
5235 }
5236
5237 res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_NOFS);
5238 if (unlikely(res.impl_id == NULL)) {
5138 status = -ENOMEM; 5239 status = -ENOMEM;
5139 goto out_server_scope; 5240 goto out_server_scope;
5140 } 5241 }
5141 5242
5142 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5243 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5143 if (!status) 5244 if (status == 0)
5144 status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); 5245 status = nfs4_check_cl_exchange_flags(res.flags);
5246
5247 if (status == 0) {
5248 clp->cl_clientid = res.clientid;
5249 clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
5250 if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R))
5251 clp->cl_seqid = res.seqid;
5252
5253 kfree(clp->cl_serverowner);
5254 clp->cl_serverowner = res.server_owner;
5255 res.server_owner = NULL;
5145 5256
5146 if (!status) {
5147 /* use the most recent implementation id */ 5257 /* use the most recent implementation id */
5148 kfree(clp->impl_id); 5258 kfree(clp->cl_implid);
5149 clp->impl_id = res.impl_id; 5259 clp->cl_implid = res.impl_id;
5150 } else
5151 kfree(res.impl_id);
5152 5260
5153 if (!status) { 5261 if (clp->cl_serverscope != NULL &&
5154 if (clp->server_scope && 5262 !nfs41_same_server_scope(clp->cl_serverscope,
5155 !nfs41_same_server_scope(clp->server_scope,
5156 res.server_scope)) { 5263 res.server_scope)) {
5157 dprintk("%s: server_scope mismatch detected\n", 5264 dprintk("%s: server_scope mismatch detected\n",
5158 __func__); 5265 __func__);
5159 set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state); 5266 set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
5160 kfree(clp->server_scope); 5267 kfree(clp->cl_serverscope);
5161 clp->server_scope = NULL; 5268 clp->cl_serverscope = NULL;
5162 } 5269 }
5163 5270
5164 if (!clp->server_scope) { 5271 if (clp->cl_serverscope == NULL) {
5165 clp->server_scope = res.server_scope; 5272 clp->cl_serverscope = res.server_scope;
5166 goto out; 5273 goto out;
5167 } 5274 }
5168 } 5275 } else
5276 kfree(res.impl_id);
5169 5277
5278out_server_owner:
5279 kfree(res.server_owner);
5170out_server_scope: 5280out_server_scope:
5171 kfree(res.server_scope); 5281 kfree(res.server_scope);
5172out: 5282out:
5173 if (clp->impl_id) 5283 if (clp->cl_implid != NULL)
5174 dprintk("%s: Server Implementation ID: " 5284 dprintk("%s: Server Implementation ID: "
5175 "domain: %s, name: %s, date: %llu,%u\n", 5285 "domain: %s, name: %s, date: %llu,%u\n",
5176 __func__, clp->impl_id->domain, clp->impl_id->name, 5286 __func__, clp->cl_implid->domain, clp->cl_implid->name,
5177 clp->impl_id->date.seconds, 5287 clp->cl_implid->date.seconds,
5178 clp->impl_id->date.nseconds); 5288 clp->cl_implid->date.nseconds);
5179 dprintk("<-- %s status= %d\n", __func__, status); 5289 dprintk("<-- %s status= %d\n", __func__, status);
5180 return status; 5290 return status;
5181} 5291}
5182 5292
5293static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
5294 struct rpc_cred *cred)
5295{
5296 struct rpc_message msg = {
5297 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_CLIENTID],
5298 .rpc_argp = clp,
5299 .rpc_cred = cred,
5300 };
5301 int status;
5302
5303 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5304 if (status)
5305 dprintk("NFS: Got error %d from the server %s on "
5306 "DESTROY_CLIENTID.", status, clp->cl_hostname);
5307 return status;
5308}
5309
5310static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
5311 struct rpc_cred *cred)
5312{
5313 unsigned int loop;
5314 int ret;
5315
5316 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
5317 ret = _nfs4_proc_destroy_clientid(clp, cred);
5318 switch (ret) {
5319 case -NFS4ERR_DELAY:
5320 case -NFS4ERR_CLIENTID_BUSY:
5321 ssleep(1);
5322 break;
5323 default:
5324 return ret;
5325 }
5326 }
5327 return 0;
5328}
5329
5330int nfs4_destroy_clientid(struct nfs_client *clp)
5331{
5332 struct rpc_cred *cred;
5333 int ret = 0;
5334
5335 if (clp->cl_mvops->minor_version < 1)
5336 goto out;
5337 if (clp->cl_exchange_flags == 0)
5338 goto out;
5339 cred = nfs4_get_exchange_id_cred(clp);
5340 ret = nfs4_proc_destroy_clientid(clp, cred);
5341 if (cred)
5342 put_rpccred(cred);
5343 switch (ret) {
5344 case 0:
5345 case -NFS4ERR_STALE_CLIENTID:
5346 clp->cl_exchange_flags = 0;
5347 }
5348out:
5349 return ret;
5350}
5351
5183struct nfs4_get_lease_time_data { 5352struct nfs4_get_lease_time_data {
5184 struct nfs4_get_lease_time_args *args; 5353 struct nfs4_get_lease_time_args *args;
5185 struct nfs4_get_lease_time_res *res; 5354 struct nfs4_get_lease_time_res *res;
@@ -5400,8 +5569,12 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
5400void nfs4_destroy_session(struct nfs4_session *session) 5569void nfs4_destroy_session(struct nfs4_session *session)
5401{ 5570{
5402 struct rpc_xprt *xprt; 5571 struct rpc_xprt *xprt;
5572 struct rpc_cred *cred;
5403 5573
5404 nfs4_proc_destroy_session(session); 5574 cred = nfs4_get_exchange_id_cred(session->clp);
5575 nfs4_proc_destroy_session(session, cred);
5576 if (cred)
5577 put_rpccred(cred);
5405 5578
5406 rcu_read_lock(); 5579 rcu_read_lock();
5407 xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt); 5580 xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
@@ -5511,7 +5684,8 @@ static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args,
5511 return nfs4_verify_back_channel_attrs(args, session); 5684 return nfs4_verify_back_channel_attrs(args, session);
5512} 5685}
5513 5686
5514static int _nfs4_proc_create_session(struct nfs_client *clp) 5687static int _nfs4_proc_create_session(struct nfs_client *clp,
5688 struct rpc_cred *cred)
5515{ 5689{
5516 struct nfs4_session *session = clp->cl_session; 5690 struct nfs4_session *session = clp->cl_session;
5517 struct nfs41_create_session_args args = { 5691 struct nfs41_create_session_args args = {
@@ -5525,6 +5699,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
5525 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], 5699 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION],
5526 .rpc_argp = &args, 5700 .rpc_argp = &args,
5527 .rpc_resp = &res, 5701 .rpc_resp = &res,
5702 .rpc_cred = cred,
5528 }; 5703 };
5529 int status; 5704 int status;
5530 5705
@@ -5549,7 +5724,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
5549 * It is the responsibility of the caller to verify the session is 5724 * It is the responsibility of the caller to verify the session is
5550 * expired before calling this routine. 5725 * expired before calling this routine.
5551 */ 5726 */
5552int nfs4_proc_create_session(struct nfs_client *clp) 5727int nfs4_proc_create_session(struct nfs_client *clp, struct rpc_cred *cred)
5553{ 5728{
5554 int status; 5729 int status;
5555 unsigned *ptr; 5730 unsigned *ptr;
@@ -5557,7 +5732,7 @@ int nfs4_proc_create_session(struct nfs_client *clp)
5557 5732
5558 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 5733 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
5559 5734
5560 status = _nfs4_proc_create_session(clp); 5735 status = _nfs4_proc_create_session(clp, cred);
5561 if (status) 5736 if (status)
5562 goto out; 5737 goto out;
5563 5738
@@ -5579,10 +5754,15 @@ out:
5579 * Issue the over-the-wire RPC DESTROY_SESSION. 5754 * Issue the over-the-wire RPC DESTROY_SESSION.
5580 * The caller must serialize access to this routine. 5755 * The caller must serialize access to this routine.
5581 */ 5756 */
5582int nfs4_proc_destroy_session(struct nfs4_session *session) 5757int nfs4_proc_destroy_session(struct nfs4_session *session,
5758 struct rpc_cred *cred)
5583{ 5759{
5760 struct rpc_message msg = {
5761 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION],
5762 .rpc_argp = session,
5763 .rpc_cred = cred,
5764 };
5584 int status = 0; 5765 int status = 0;
5585 struct rpc_message msg;
5586 5766
5587 dprintk("--> nfs4_proc_destroy_session\n"); 5767 dprintk("--> nfs4_proc_destroy_session\n");
5588 5768
@@ -5590,68 +5770,89 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
5590 if (session->clp->cl_cons_state != NFS_CS_READY) 5770 if (session->clp->cl_cons_state != NFS_CS_READY)
5591 return status; 5771 return status;
5592 5772
5593 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION];
5594 msg.rpc_argp = session;
5595 msg.rpc_resp = NULL;
5596 msg.rpc_cred = NULL;
5597 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5773 status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5598 5774
5599 if (status) 5775 if (status)
5600 printk(KERN_WARNING 5776 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
5601 "NFS: Got error %d from the server on DESTROY_SESSION. "
5602 "Session has been destroyed regardless...\n", status); 5777 "Session has been destroyed regardless...\n", status);
5603 5778
5604 dprintk("<-- nfs4_proc_destroy_session\n"); 5779 dprintk("<-- nfs4_proc_destroy_session\n");
5605 return status; 5780 return status;
5606} 5781}
5607 5782
5783/*
5784 * With sessions, the client is not marked ready until after a
5785 * successful EXCHANGE_ID and CREATE_SESSION.
5786 *
5787 * Map errors cl_cons_state errors to EPROTONOSUPPORT to indicate
5788 * other versions of NFS can be tried.
5789 */
5790static int nfs41_check_session_ready(struct nfs_client *clp)
5791{
5792 int ret;
5793
5794 if (clp->cl_cons_state == NFS_CS_SESSION_INITING) {
5795 ret = nfs4_client_recover_expired_lease(clp);
5796 if (ret)
5797 return ret;
5798 }
5799 if (clp->cl_cons_state < NFS_CS_READY)
5800 return -EPROTONOSUPPORT;
5801 smp_rmb();
5802 return 0;
5803}
5804
5608int nfs4_init_session(struct nfs_server *server) 5805int nfs4_init_session(struct nfs_server *server)
5609{ 5806{
5610 struct nfs_client *clp = server->nfs_client; 5807 struct nfs_client *clp = server->nfs_client;
5611 struct nfs4_session *session; 5808 struct nfs4_session *session;
5612 unsigned int rsize, wsize; 5809 unsigned int rsize, wsize;
5613 int ret;
5614 5810
5615 if (!nfs4_has_session(clp)) 5811 if (!nfs4_has_session(clp))
5616 return 0; 5812 return 0;
5617 5813
5618 session = clp->cl_session; 5814 session = clp->cl_session;
5619 if (!test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) 5815 spin_lock(&clp->cl_lock);
5620 return 0; 5816 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
5621 5817
5622 rsize = server->rsize; 5818 rsize = server->rsize;
5623 if (rsize == 0) 5819 if (rsize == 0)
5624 rsize = NFS_MAX_FILE_IO_SIZE; 5820 rsize = NFS_MAX_FILE_IO_SIZE;
5625 wsize = server->wsize; 5821 wsize = server->wsize;
5626 if (wsize == 0) 5822 if (wsize == 0)
5627 wsize = NFS_MAX_FILE_IO_SIZE; 5823 wsize = NFS_MAX_FILE_IO_SIZE;
5628 5824
5629 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead; 5825 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
5630 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead; 5826 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
5827 }
5828 spin_unlock(&clp->cl_lock);
5631 5829
5632 ret = nfs4_recover_expired_lease(server); 5830 return nfs41_check_session_ready(clp);
5633 if (!ret)
5634 ret = nfs4_check_client_ready(clp);
5635 return ret;
5636} 5831}
5637 5832
5638int nfs4_init_ds_session(struct nfs_client *clp) 5833int nfs4_init_ds_session(struct nfs_client *clp, unsigned long lease_time)
5639{ 5834{
5640 struct nfs4_session *session = clp->cl_session; 5835 struct nfs4_session *session = clp->cl_session;
5641 int ret; 5836 int ret;
5642 5837
5643 if (!test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) 5838 spin_lock(&clp->cl_lock);
5644 return 0; 5839 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
5645 5840 /*
5646 ret = nfs4_client_recover_expired_lease(clp); 5841 * Do not set NFS_CS_CHECK_LEASE_TIME instead set the
5647 if (!ret) 5842 * DS lease to be equal to the MDS lease.
5648 /* Test for the DS role */ 5843 */
5649 if (!is_ds_client(clp)) 5844 clp->cl_lease_time = lease_time;
5650 ret = -ENODEV; 5845 clp->cl_last_renewal = jiffies;
5651 if (!ret) 5846 }
5652 ret = nfs4_check_client_ready(clp); 5847 spin_unlock(&clp->cl_lock);
5653 return ret;
5654 5848
5849 ret = nfs41_check_session_ready(clp);
5850 if (ret)
5851 return ret;
5852 /* Test for the DS role */
5853 if (!is_ds_client(clp))
5854 return -ENODEV;
5855 return 0;
5655} 5856}
5656EXPORT_SYMBOL_GPL(nfs4_init_ds_session); 5857EXPORT_SYMBOL_GPL(nfs4_init_ds_session);
5657 5858
@@ -6558,6 +6759,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6558 .file_inode_ops = &nfs4_file_inode_operations, 6759 .file_inode_ops = &nfs4_file_inode_operations,
6559 .file_ops = &nfs4_file_operations, 6760 .file_ops = &nfs4_file_operations,
6560 .getroot = nfs4_proc_get_root, 6761 .getroot = nfs4_proc_get_root,
6762 .submount = nfs4_submount,
6561 .getattr = nfs4_proc_getattr, 6763 .getattr = nfs4_proc_getattr,
6562 .setattr = nfs4_proc_setattr, 6764 .setattr = nfs4_proc_setattr,
6563 .lookup = nfs4_proc_lookup, 6765 .lookup = nfs4_proc_lookup,
@@ -6590,13 +6792,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6590 .write_rpc_prepare = nfs4_proc_write_rpc_prepare, 6792 .write_rpc_prepare = nfs4_proc_write_rpc_prepare,
6591 .write_done = nfs4_write_done, 6793 .write_done = nfs4_write_done,
6592 .commit_setup = nfs4_proc_commit_setup, 6794 .commit_setup = nfs4_proc_commit_setup,
6795 .commit_rpc_prepare = nfs4_proc_commit_rpc_prepare,
6593 .commit_done = nfs4_commit_done, 6796 .commit_done = nfs4_commit_done,
6594 .lock = nfs4_proc_lock, 6797 .lock = nfs4_proc_lock,
6595 .clear_acl_cache = nfs4_zap_acl_attr, 6798 .clear_acl_cache = nfs4_zap_acl_attr,
6596 .close_context = nfs4_close_context, 6799 .close_context = nfs4_close_context,
6597 .open_context = nfs4_atomic_open, 6800 .open_context = nfs4_atomic_open,
6598 .init_client = nfs4_init_client, 6801 .init_client = nfs4_init_client,
6599 .secinfo = nfs4_proc_secinfo,
6600}; 6802};
6601 6803
6602static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { 6804static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {