summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/lofs/lofs_subr.c
diff options
context:
space:
mode:
authorowenr <none@none>2005-08-09 09:24:51 -0700
committerowenr <none@none>2005-08-09 09:24:51 -0700
commitb431137cd272e49097db14ab8b85efbbe92a1d76 (patch)
tree2bb879865ef96cc5ef941de7427fea83960d76db /usr/src/uts/common/fs/lofs/lofs_subr.c
parent1653ff84a9a7105db4b0bc24490eabfe67950c3a (diff)
downloadillumos-gate-b431137cd272e49097db14ab8b85efbbe92a1d76.tar.gz
5034470 Fix for bug 4126922 is incomplete, still lofs stack overflow panic possible
Diffstat (limited to 'usr/src/uts/common/fs/lofs/lofs_subr.c')
-rw-r--r--usr/src/uts/common/fs/lofs/lofs_subr.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/usr/src/uts/common/fs/lofs/lofs_subr.c b/usr/src/uts/common/fs/lofs/lofs_subr.c
index 69481f7b31..0b68f4e030 100644
--- a/usr/src/uts/common/fs/lofs/lofs_subr.c
+++ b/usr/src/uts/common/fs/lofs/lofs_subr.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -243,18 +243,26 @@ ldestroy(struct loinfo *li)
* in a table hashed by vnode. If the lnode for
* this vnode is already in the table return it (ref count is
* incremented by lfind). The lnode will be flushed from the
- * table when lo_inactive calls freelonode.
+ * table when lo_inactive calls freelonode. The creation of
+ * a new lnode can be forced via the LOF_FORCE flag even if
+ * the vnode exists in the table. This is used in the creation
+ * of a terminating lnode when looping is detected. A unique
+ * lnode is required for the correct evaluation of the current
+ * working directory.
* NOTE: vp is assumed to be a held vnode.
*/
struct vnode *
-makelonode(struct vnode *vp, struct loinfo *li)
+makelonode(struct vnode *vp, struct loinfo *li, int flag)
{
lnode_t *lp, *tlp;
struct vfs *vfsp;
vnode_t *nvp;
+ lp = NULL;
TABLE_LOCK_ENTER(vp, li);
- if ((lp = lfind(vp, li)) == NULL) {
+ if (flag != LOF_FORCE)
+ lp = lfind(vp, li);
+ if ((flag == LOF_FORCE) || (lp == NULL)) {
/*
* Optimistically assume that we won't need to sleep.
*/
@@ -270,8 +278,11 @@ makelonode(struct vnode *vp, struct loinfo *li)
if (nvp == NULL) {
nvp = vn_alloc(KM_SLEEP);
}
+ lp = NULL;
TABLE_LOCK_ENTER(vp, li);
- if ((lp = lfind(vp, li)) != NULL) {
+ if (flag != LOF_FORCE)
+ lp = lfind(vp, li);
+ if (lp != NULL) {
kmem_cache_free(lnode_cache, tlp);
vn_free(nvp);
VN_RELE(vp);