diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-15 20:37:23 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-15 20:37:23 -0400 |
| commit | 873b779d998fd70e17a3f2bff6a35f0e0a3b0f11 (patch) | |
| tree | f551ff314b5ca2859f53cd7201c12901699c2562 /fs/nfs/nfs4proc.c | |
| parent | 56b880e2e38da6c76c454052a93c0a92aa3586f7 (diff) | |
| parent | e216c8c771c9a77f14d7e8b4131846b038f6c145 (diff) | |
Merge tag 'nfs-for-3.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:
- Fix a couple of mount regressions due to the recent cleanups.
- Fix an Oops in the open recovery code
- Fix an rpc_pipefs upcall hang that results from some of the net
namespace work from 3.4.x (stable kernel candidate).
- Fix a couple of write and o_direct regressions that were found at
last weeks Bakeathon testing event in Ann Arbor."
* tag 'nfs-for-3.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFS: add an endian notation for sparse
NFSv4.1: integer overflow in decode_cb_sequence_args()
rpc_pipefs: allow rpc_purge_list to take a NULL waitq pointer
NFSv4 do not send an empty SETATTR compound
NFSv2: EOF incorrectly set on short read
NFS: Use the NFS_DEFAULT_VERSION for v2 and v3 mounts
NFS: fix directio refcount bug on commit
NFSv4: Fix unnecessary delegation returns in nfs4_do_open
NFSv4.1: Convert another trivial printk into a dprintk
NFS4: Fix open bug when pnfs module blacklisted
NFS: Remove incorrect BUG_ON in nfs_found_client
NFS: Map minor mismatch error to protocol not support error.
NFS: Fix a commit bug
NFS4: Set parsed mount data version to 4
NFSv4.1: Ensure we clear session state flags after a session creation
NFSv4.1: Convert a trivial printk into a dprintk
NFSv4: Fix up decode_attr_mdsthreshold
NFSv4: Fix an Oops in the open recovery code
NFSv4.1: Fix a request leak on the back channel
Diffstat (limited to 'fs/nfs/nfs4proc.c')
| -rw-r--r-- | fs/nfs/nfs4proc.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d48dbefa0e71..15fc7e4664ed 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 | */ |
| 119 | const u32 nfs4_fattr_bitmap[2] = { | 121 | const 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 | ||
| 138 | static 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 | |||
| 136 | const u32 nfs4_statfs_bitmap[2] = { | 156 | const 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"); |
