diff options
author | tjr <tjr@FreeBSD.org> | 2002-12-13 10:15:01 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-12-13 10:15:01 +0000 |
commit | 99f5994bb49ce0f6ac7f141db1b8806a6dd4a164 (patch) | |
tree | d6829a6b64cab3c4fd5bcf0cfade2c79d258fadd /sys | |
parent | 0d70b124724057274d505584b615ff6d73891ac7 (diff) | |
download | FreeBSD-src-99f5994bb49ce0f6ac7f141db1b8806a6dd4a164.zip FreeBSD-src-99f5994bb49ce0f6ac7f141db1b8806a6dd4a164.tar.gz |
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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/smbfs/smbfs_io.c | 2 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_node.c | 10 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_node.h | 2 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_smb.c | 3 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_subr.c | 2 | ||||
-rw-r--r-- | 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; |