From 11de0c59e96ba2f26e9ff4ab653cb8f800f31ef0 Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" 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(-) (limited to 'sys') diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index 21ccbab019107..9aa42240b9179 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 c94787d56b83d..7f17967d43fec 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 e65337a91ae0f..1343ff5b36c65 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 da4a871c53c1c..cd85cbd96303a 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 8012c0ba47c96..16e4bf2e9722e 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 5128cb83a9027..f1fc710c9c482 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.3