From 6e062f4a9c9a27ea6e2e980c1b5f4c41e33aba45 Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Tue, 27 Jan 2015 00:49:29 +0100 Subject: [PATCH] 5563 Some traverse() callers do strange things Reviewed by: Andy Stormont Reviewed by: Josef 'Jeff' Sipek Approved by: Robert Mustacchi --- usr/src/uts/common/fs/lookup.c | 21 ++++---------------- usr/src/uts/common/fs/nfs/nfs4_srv.c | 15 ++++++-------- usr/src/uts/common/fs/nfs/nfs4_srv_readdir.c | 6 ++++++ 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/usr/src/uts/common/fs/lookup.c b/usr/src/uts/common/fs/lookup.c index 6819509d004e..55ffb9480583 100644 --- a/usr/src/uts/common/fs/lookup.c +++ b/usr/src/uts/common/fs/lookup.c @@ -20,6 +20,7 @@ */ /* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -217,7 +218,6 @@ lookuppnvp( cred_t *cr) /* user's credential */ { vnode_t *cvp; /* current component vp */ - vnode_t *tvp; /* addressable temp ptr */ char component[MAXNAMELEN]; /* buffer for component (incl null) */ int error; int nlink; @@ -373,7 +373,7 @@ lookuppnvp( /* * Perform a lookup in the current directory. */ - error = VOP_LOOKUP(vp, component, &tvp, pnp, lookup_flags, + error = VOP_LOOKUP(vp, component, &cvp, pnp, lookup_flags, rootvp, cr, NULL, NULL, pp); /* @@ -391,10 +391,9 @@ lookuppnvp( * directory inside NFS FS. */ if ((error == EACCES) && retry_with_kcred) - error = VOP_LOOKUP(vp, component, &tvp, pnp, lookup_flags, + error = VOP_LOOKUP(vp, component, &cvp, pnp, lookup_flags, rootvp, zone_kcred(), NULL, NULL, pp); - cvp = tvp; if (error) { cvp = NULL; /* @@ -440,20 +439,8 @@ lookuppnvp( * be atomic!) */ if (vn_mountedvfs(cvp) != NULL) { - tvp = cvp; - if ((error = traverse(&tvp)) != 0) { - /* - * It is required to assign cvp here, because - * traverse() will return a held vnode which - * may different than the vnode that was passed - * in (even in the error case). If traverse() - * changes the vnode it releases the original, - * and holds the new one. - */ - cvp = tvp; + if ((error = traverse(&cvp)) != 0) goto bad; - } - cvp = tvp; } /* diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv.c b/usr/src/uts/common/fs/nfs/nfs4_srv.c index 127d9e3f29fe..fe1a10b966f7 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_srv.c +++ b/usr/src/uts/common/fs/nfs/nfs4_srv.c @@ -18,10 +18,11 @@ * * CDDL HEADER END */ + /* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* @@ -869,7 +870,7 @@ static nfsstat4 do_rfs4_op_secinfo(struct compound_state *cs, char *nm, SECINFO4res *resp) { int error, different_export = 0; - vnode_t *dvp, *vp, *tvp; + vnode_t *dvp, *vp; struct exportinfo *exi = NULL; fid_t fid; uint_t count, i; @@ -950,14 +951,12 @@ do_rfs4_op_secinfo(struct compound_state *cs, char *nm, SECINFO4res *resp) * If it's a mountpoint, then traverse it. */ if (vn_ismntpt(vp)) { - tvp = vp; - if ((error = traverse(&tvp)) != 0) { + if ((error = traverse(&vp)) != 0) { VN_RELE(vp); return (puterrno4(error)); } /* remember that we had to traverse mountpoint */ did_traverse = TRUE; - vp = tvp; different_export = 1; } else if (vp->v_vfsp != dvp->v_vfsp) { /* @@ -2610,7 +2609,7 @@ do_rfs4_op_lookup(char *nm, struct svc_req *req, struct compound_state *cs) { int error; int different_export = 0; - vnode_t *vp, *tvp, *pre_tvp = NULL, *oldvp = NULL; + vnode_t *vp, *pre_tvp = NULL, *oldvp = NULL; struct exportinfo *exi = NULL, *pre_exi = NULL; nfsstat4 stat; fid_t fid; @@ -2708,13 +2707,11 @@ do_rfs4_op_lookup(char *nm, struct svc_req *req, struct compound_state *cs) * need pre_tvp below if checkexport4 fails */ VN_HOLD(pre_tvp); - tvp = vp; - if ((error = traverse(&tvp)) != 0) { + if ((error = traverse(&vp)) != 0) { VN_RELE(vp); VN_RELE(pre_tvp); return (puterrno4(error)); } - vp = tvp; different_export = 1; } else if (vp->v_vfsp != cs->vp->v_vfsp) { /* diff --git a/usr/src/uts/common/fs/nfs/nfs4_srv_readdir.c b/usr/src/uts/common/fs/nfs/nfs4_srv_readdir.c index 3069a9883537..276d3b4f199d 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_srv_readdir.c +++ b/usr/src/uts/common/fs/nfs/nfs4_srv_readdir.c @@ -18,6 +18,11 @@ * * CDDL HEADER END */ + +/* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + */ + /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -149,6 +154,7 @@ nfs4_readdir_getvp(vnode_t *dvp, char *d_name, vnode_t **vpp, VN_HOLD(pre_tvp); if ((error = traverse(&vp)) != 0) { + VN_RELE(vp); VN_RELE(pre_tvp); return (error); }