summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-12-13 10:15:01 +0000
committertjr <tjr@FreeBSD.org>2002-12-13 10:15:01 +0000
commit99f5994bb49ce0f6ac7f141db1b8806a6dd4a164 (patch)
treed6829a6b64cab3c4fd5bcf0cfade2c79d258fadd /sys/fs
parent0d70b124724057274d505584b615ff6d73891ac7 (diff)
downloadFreeBSD-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/fs')
-rw-r--r--sys/fs/smbfs/smbfs_io.c2
-rw-r--r--sys/fs/smbfs/smbfs_node.c10
-rw-r--r--sys/fs/smbfs/smbfs_node.h2
-rw-r--r--sys/fs/smbfs/smbfs_smb.c3
-rw-r--r--sys/fs/smbfs/smbfs_subr.c2
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c5
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;
OpenPOWER on IntegriCloud