From: Andy Adamson Date: Fri, 18 May 2007 16:52:45 -0400 NFSv4: Collect SECINFO parameters for nfs_lookup WRONGSEC handling Add an exception structure to __nfs4_proc_lookup and to the lookup XDR result structure and collect the operation, directory filehandle, and name needed to call SECINFO on WRONGSEC error. NOTE: The WRONGSEC error could have (incorrectly) been on the PUTFH, but we don't care. Signed-off-by: Andy Adamson Signed-off-by: Trond Myklebust --- fs/nfs/client.c | 2 +- fs/nfs/nfs4_fs.h | 7 +++++++ fs/nfs/nfs4proc.c | 11 +++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 187e66b..1c68c28 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1177,7 +1177,7 @@ retry: if (exc->ex_clnt) rpc_shutdown_client(exc->ex_clnt); - exc->ex_clnt = rpc_clone_client(clp->cl_rpcclient); + exc->ex_clnt = rpc_clone_client(server->nfs_client->cl_rpcclient); if (IS_ERR(exc->ex_clnt)) { error = PTR_ERR(exc->ex_clnt); goto out_free; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index e63fb05..3ff47de 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -140,9 +140,16 @@ struct nfs4_state { }; +struct nfs4_secinfo_exception { + int op; + struct nfs_fh *fh; + struct qstr *name; +}; + struct nfs4_exception { long timeout; int retry; + struct nfs4_secinfo_exception ex_info; struct nfs4_secinfo_res *ex_list; struct rpc_clnt *ex_clnt; struct rpc_cred *ex_cred; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4945990..8df5c0e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1580,7 +1580,8 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh, } static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) + struct nfs_fh *fhandle, struct nfs_fattr *fattr, + struct nfs4_exception *exc) { int status; struct nfs_server *server = NFS_SERVER(dir); @@ -1606,6 +1607,11 @@ static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (status == -NFS4ERR_MOVED) status = nfs4_get_referral(dir, name, fattr, fhandle); + if (status == -NFS4ERR_WRONGSEC) { + exc->ex_info.op = OP_LOOKUP; + exc->ex_info.fh = NFS_FH(dir); + exc->ex_info.name = name; + } dprintk("NFS reply lookup: %d\n", status); return status; } @@ -1616,7 +1622,8 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh int err; do { err = nfs4_handle_exception(NFS_SERVER(dir), - _nfs4_proc_lookup(dir, name, fhandle, fattr), + _nfs4_proc_lookup(dir, name, fhandle, fattr, + &exception), &exception); } while (exception.retry); return err;