diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-17 21:52:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-19 15:09:03 -0400 |
commit | 9936781d0147e13cbc6df02f5265e0b9999ce3cf (patch) | |
tree | a24b01b576cd04f5eb6b9f61da5cfed650d50603 /fs/nfs/nfs4proc.c | |
parent | 56659e9926ef5996398924c799ecac39ca8b6223 (diff) |
NFSv4: Try to recover from getfh failures in nfs4_xdr_dec_open
Try harder to recover the open state if the server failed to return a
filehandle.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5f3689befc2..7ead63e065a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -66,6 +66,8 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp); static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags); +static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); +static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); /* Prevent leaks of NFSv4 errors into userland */ int nfs4_map_errors(int err) @@ -930,6 +932,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) if (status != 0 || !data->rpc_done) return status; + if (o_res->fh.size == 0) + _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); + if (o_arg->open_flags & O_CREAT) { update_changeattr(dir, &o_res->cinfo); nfs_post_op_update_inode(dir, o_res->dir_attr); @@ -941,7 +946,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) return status; } if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) - return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); + _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr); return 0; } |