From 99f5994bb49ce0f6ac7f141db1b8806a6dd4a164 Mon Sep 17 00:00:00 2001 From: tjr Date: Fri, 13 Dec 2002 10:15:01 +0000 Subject: Store a reference to the parent directory's vnode in struct smbnode, not to the parent's smbnode, which may be freed during the lifetime of the child if the mount is forcibly unmounted. umount -f should now work properly (ie. not panic) on smbfs mounts. --- sys/fs/smbfs/smbfs_io.c | 2 +- sys/fs/smbfs/smbfs_node.c | 10 +++++----- sys/fs/smbfs/smbfs_node.h | 2 +- sys/fs/smbfs/smbfs_smb.c | 3 ++- sys/fs/smbfs/smbfs_subr.c | 2 +- sys/fs/smbfs/smbfs_vnops.c | 5 +++-- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index 21ccbab..9aa4224 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -101,7 +101,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) bzero((caddr_t)&de, DE_SIZE); de.d_reclen = DE_SIZE; de.d_fileno = (offset == 0) ? np->n_ino : - (np->n_parent ? np->n_parent->n_ino : 2); + (np->n_parent ? VTOSMB(np->n_parent)->n_ino : 2); if (de.d_fileno == 0) de.d_fileno = 0x7ffffffd + offset; de.d_namlen = offset + 1; diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c index c94787d..7f17967 100644 --- a/sys/fs/smbfs/smbfs_node.c +++ b/sys/fs/smbfs/smbfs_node.c @@ -180,7 +180,7 @@ smbfs_node_alloc(struct mount *mp, struct vnode *dvp, if (nmlen == 2 && bcmp(name, "..", 2) == 0) { if (dvp == NULL) return EINVAL; - vp = VTOSMB(dvp)->n_parent->n_vnode; + vp = VTOSMB(VTOSMB(dvp)->n_parent)->n_vnode; error = vget(vp, LK_EXCLUSIVE, td); if (error == 0) *vpp = vp; @@ -201,7 +201,7 @@ loop: nhpp = SMBFS_NOHASH(smp, hashval); LIST_FOREACH(np, nhpp, n_hash) { vp = SMBTOV(np); - if (np->n_parent != dnp || + if (np->n_parent != dvp || np->n_nmlen != nmlen || bcmp(name, np->n_name, nmlen) != 0) continue; VI_LOCK(vp); @@ -236,7 +236,7 @@ loop: if (dvp) { ASSERT_VOP_LOCKED(dvp, "smbfs_node_alloc"); - np->n_parent = dnp; + np->n_parent = dvp; if (/*vp->v_type == VDIR &&*/ (dvp->v_vflag & VV_ROOT) == 0) { vref(dvp); np->n_flag |= NREFPARENT; @@ -249,7 +249,7 @@ loop: smbfs_hash_lock(smp, td); LIST_FOREACH(np2, nhpp, n_hash) { - if (np2->n_parent != dnp || + if (np2->n_parent != dvp || np2->n_nmlen != nmlen || bcmp(name, np2->n_name, nmlen) != 0) continue; vput(vp); @@ -303,7 +303,7 @@ smbfs_reclaim(ap) smbfs_hash_lock(smp, td); dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ? - np->n_parent->n_vnode : NULL; + np->n_parent : NULL; if (np->n_hash.le_prev) LIST_REMOVE(np, n_hash); diff --git a/sys/fs/smbfs/smbfs_node.h b/sys/fs/smbfs/smbfs_node.h index e65337a..1343ff5 100644 --- a/sys/fs/smbfs/smbfs_node.h +++ b/sys/fs/smbfs/smbfs_node.h @@ -51,7 +51,7 @@ struct smbnode { struct lock n_lock; /* smbnode lock. (mbf) */ #endif int n_flag; - struct smbnode * n_parent; + struct vnode * n_parent; struct vnode * n_vnode; struct smbmount * n_mount; time_t n_attrage; /* attributes cache time */ diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c index da4a871..cd85cbd 100644 --- a/sys/fs/smbfs/smbfs_smb.c +++ b/sys/fs/smbfs/smbfs_smb.c @@ -1485,7 +1485,8 @@ smbfs_smb_lookup(struct smbnode *dnp, const char *name, int nmlen, error = smbfs_smb_lookup(dnp, NULL, 0, fap, scred); return error; } else if (nmlen == 2 && name[0] == '.' && name[1] == '.') { - error = smbfs_smb_lookup(dnp->n_parent, NULL, 0, fap, scred); + error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap, + scred); printf("%s: knows NOTHING about '..'\n", __func__); return error; } diff --git a/sys/fs/smbfs/smbfs_subr.c b/sys/fs/smbfs/smbfs_subr.c index 8012c0b..16e4bf2 100644 --- a/sys/fs/smbfs/smbfs_subr.c +++ b/sys/fs/smbfs/smbfs_subr.c @@ -270,7 +270,7 @@ smb_fphelp(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *np, return ENAMETOOLONG; } *npp++ = np; - np = np->n_parent; + np = VTOSMB(np->n_parent); } /* if (i == 0) return smb_put_dmem(mbp, vcp, "\\", 2, caseopt);*/ diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c index 5128cb8..f1fc710 100644 --- a/sys/fs/smbfs/smbfs_vnops.c +++ b/sys/fs/smbfs/smbfs_vnops.c @@ -846,7 +846,7 @@ int smbfs_print (ap) return (0); } printf("name = %s, parent = %p, opencount = %d\n", np->n_name, - np->n_parent ? SMBTOV(np->n_parent) : NULL, np->n_opencount); + np->n_parent ? np->n_parent : NULL, np->n_opencount); return (0); } @@ -1236,7 +1236,8 @@ smbfs_lookup(ap) smb_makescred(&scred, td, cnp->cn_cred); fap = &fattr; if (flags & ISDOTDOT) { - error = smbfs_smb_lookup(dnp->n_parent, NULL, 0, fap, &scred); + error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap, + &scred); SMBVDEBUG("result of dotdot lookup: %d\n", error); } else { fap = &fattr; -- cgit v1.1