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.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d48dbefa0e7..15fc7e4664e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -105,6 +105,8 @@ static int nfs4_map_errors(int err)
105 return -EINVAL; 105 return -EINVAL;
106 case -NFS4ERR_SHARE_DENIED: 106 case -NFS4ERR_SHARE_DENIED:
107 return -EACCES; 107 return -EACCES;
108 case -NFS4ERR_MINOR_VERS_MISMATCH:
109 return -EPROTONOSUPPORT;
108 default: 110 default:
109 dprintk("%s could not handle NFSv4 error %d\n", 111 dprintk("%s could not handle NFSv4 error %d\n",
110 __func__, -err); 112 __func__, -err);
@@ -116,7 +118,7 @@ static int nfs4_map_errors(int err)
116/* 118/*
117 * This is our standard bitmap for GETATTR requests. 119 * This is our standard bitmap for GETATTR requests.
118 */ 120 */
119const u32 nfs4_fattr_bitmap[2] = { 121const u32 nfs4_fattr_bitmap[3] = {
120 FATTR4_WORD0_TYPE 122 FATTR4_WORD0_TYPE
121 | FATTR4_WORD0_CHANGE 123 | FATTR4_WORD0_CHANGE
122 | FATTR4_WORD0_SIZE 124 | FATTR4_WORD0_SIZE
@@ -133,6 +135,24 @@ const u32 nfs4_fattr_bitmap[2] = {
133 | FATTR4_WORD1_TIME_MODIFY 135 | FATTR4_WORD1_TIME_MODIFY
134}; 136};
135 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
136const u32 nfs4_statfs_bitmap[2] = { 156const u32 nfs4_statfs_bitmap[2] = {
137 FATTR4_WORD0_FILES_AVAIL 157 FATTR4_WORD0_FILES_AVAIL
138 | FATTR4_WORD0_FILES_FREE 158 | FATTR4_WORD0_FILES_FREE
@@ -844,6 +864,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
844 p->o_arg.name = &dentry->d_name; 864 p->o_arg.name = &dentry->d_name;
845 p->o_arg.server = server; 865 p->o_arg.server = server;
846 p->o_arg.bitmask = server->attr_bitmask; 866 p->o_arg.bitmask = server->attr_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];
@@ -1820,6 +1841,7 @@ static int _nfs4_do_open(struct inode *dir,
1820 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 1841 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
1821 if (!opendata->f_attr.mdsthreshold) 1842 if (!opendata->f_attr.mdsthreshold)
1822 goto err_opendata_put; 1843 goto err_opendata_put;
1844 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
1823 } 1845 }
1824 if (dentry->d_inode != NULL) 1846 if (dentry->d_inode != NULL)
1825 opendata->state = nfs4_get_open_state(dentry->d_inode, sp); 1847 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
@@ -1880,6 +1902,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
1880 struct nfs4_state *res; 1902 struct nfs4_state *res;
1881 int status; 1903 int status;
1882 1904
1905 fmode &= FMODE_READ|FMODE_WRITE;
1883 do { 1906 do {
1884 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred, 1907 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
1885 &res, ctx_th); 1908 &res, ctx_th);
@@ -2526,6 +2549,14 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2526 2549
2527 nfs_fattr_init(fattr); 2550 nfs_fattr_init(fattr);
2528 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
2529 /* Search for an existing open(O_WRITE) file */ 2560 /* Search for an existing open(O_WRITE) file */
2530 if (sattr->ia_valid & ATTR_FILE) { 2561 if (sattr->ia_valid & ATTR_FILE) {
2531 struct nfs_open_context *ctx; 2562 struct nfs_open_context *ctx;
@@ -2537,10 +2568,6 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2537 } 2568 }
2538 } 2569 }
2539 2570
2540 /* Deal with open(O_TRUNC) */
2541 if (sattr->ia_valid & ATTR_OPEN)
2542 sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
2543
2544 status = nfs4_do_setattr(inode, cred, fattr, sattr, state); 2571 status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
2545 if (status == 0) 2572 if (status == 0)
2546 nfs_setattr_update_inode(inode, sattr); 2573 nfs_setattr_update_inode(inode, sattr);
@@ -5275,7 +5302,7 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
5275 5302
5276 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); 5303 status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
5277 if (status) 5304 if (status)
5278 pr_warn("NFS: Got error %d from the server %s on " 5305 dprintk("NFS: Got error %d from the server %s on "
5279 "DESTROY_CLIENTID.", status, clp->cl_hostname); 5306 "DESTROY_CLIENTID.", status, clp->cl_hostname);
5280 return status; 5307 return status;
5281} 5308}
@@ -5746,8 +5773,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
5746 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);
5747 5774
5748 if (status) 5775 if (status)
5749 printk(KERN_WARNING 5776 dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
5750 "NFS: Got error %d from the server on DESTROY_SESSION. "
5751 "Session has been destroyed regardless...\n", status); 5777 "Session has been destroyed regardless...\n", status);
5752 5778
5753 dprintk("<-- nfs4_proc_destroy_session\n"); 5779 dprintk("<-- nfs4_proc_destroy_session\n");