Don't forward credentials to bread, it makes nfs panic

(Of course, nfs shouldn't rely on the credentials not being referenced)
Don't give directory entry to deget, it could result in a deadlock
Use device blocks, not clusters for logical block numbers
This commit is contained in:
ws 1995-11-05 18:47:48 +00:00
parent 3ff316b75a
commit 29fff9256a
6 changed files with 69 additions and 115 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: denode.h,v 1.17 1995/10/15 15:34:19 ws Exp $ */
/* $NetBSD: denode.h,v 1.18 1995/11/05 18:47:48 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -275,7 +275,7 @@ int msdosfs_reallocblks __P((struct vop_reallocblks_args *));
*/
int createde __P((struct denode *, struct denode *, struct denode **, struct componentname *));
int deextend __P((struct denode *, u_long, struct ucred *));
int deget __P((struct msdosfsmount *, u_long, u_long, struct direntry *, struct denode **));
int deget __P((struct msdosfsmount *, u_long, u_long, struct denode **));
int detrunc __P((struct denode *, u_long, int, struct ucred *, struct proc *));
int deupdat __P((struct denode *, int));
int doscheckpath __P((struct denode *, struct denode *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_denode.c,v 1.16 1995/10/15 15:34:23 ws Exp $ */
/* $NetBSD: msdosfs_denode.c,v 1.17 1995/11/05 18:47:51 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -144,41 +144,27 @@ msdosfs_hashrem(dep)
* diroffset is relative to the beginning of the root directory,
* otherwise it is cluster relative.
* diroffset - offset past begin of cluster of denode we want
* direntptr - address of the direntry structure of interest. If direntptr is
* NULL, the block is read if necessary.
* depp - returns the address of the gotten denode.
*/
int
deget(pmp, dirclust, diroffset, direntptr, depp)
deget(pmp, dirclust, diroffset, depp)
struct msdosfsmount *pmp; /* so we know the maj/min number */
u_long dirclust; /* cluster this dir entry came from */
u_long diroffset; /* index of entry within the cluster */
struct direntry *direntptr;
struct denode **depp; /* returns the addr of the gotten denode */
{
int error;
extern int (**msdosfs_vnodeop_p)();
struct direntry *direntptr;
struct denode *ldep;
struct vnode *nvp;
struct buf *bp;
#ifdef MSDOSFS_DEBUG
printf("deget(pmp %08x, dirclust %d, diroffset %x, direntptr %x, depp %08x)\n",
pmp, dirclust, diroffset, direntptr, depp);
printf("deget(pmp %08x, dirclust %d, diroffset %x, depp %08x)\n",
pmp, dirclust, diroffset, depp);
#endif
/*
* If dir entry is given and refers to a directory, convert to
* canonical form
*/
if (direntptr && (direntptr->deAttributes & ATTR_DIRECTORY)) {
dirclust = getushort(direntptr->deStartCluster);
if (dirclust == MSDOSFSROOT)
diroffset = MSDOSFSROOT_OFS;
else
diroffset = 0;
}
/*
* See if the denode is in the denode cache. Use the location of
* the directory entry to compute the hash value. For subdir use
@ -250,16 +236,10 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
/* Jan 1, 1980 */
/* leave the other fields as garbage */
} else {
bp = NULL;
if (!direntptr) {
error = readep(pmp, dirclust, diroffset, &bp,
&direntptr);
if (error)
return (error);
}
if (error = readep(pmp, dirclust, diroffset, &bp, &direntptr))
return (error);
DE_INTERNALIZE(ldep, direntptr);
if (bp)
brelse(bp);
brelse(bp);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_fat.c,v 1.20 1995/10/15 15:34:25 ws Exp $ */
/* $NetBSD: msdosfs_fat.c,v 1.21 1995/11/05 18:47:53 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -971,11 +971,14 @@ extendfile(dep, count, bpp, ncp, flags)
bp = getblk(pmp->pm_devvp, cntobn(pmp, cn++),
pmp->pm_bpcluster, 0, 0);
else {
bp = getblk(DETOV(dep), frcn++, pmp->pm_bpcluster, 0, 0);
bp = getblk(DETOV(dep), de_cn2bn(pmp, frcn++),
pmp->pm_bpcluster, 0, 0);
/*
* Do the bmap now, as in msdosfs_write
*/
if (pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0, 0))
if (pcbmap(dep,
de_bn2cn(pmp, bp->b_lblkno),
&bp->b_blkno, 0, 0))
bp->b_blkno = -1;
if (bp->b_blkno == -1)
panic("extendfile: pcbmap");

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_lookup.c,v 1.20 1995/11/03 17:29:53 ws Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.21 1995/11/05 18:47:55 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -429,12 +429,18 @@ found:;
isadir = dep->deAttributes & ATTR_DIRECTORY;
scn = getushort(dep->deStartCluster);
/*
* Now release buf to allow deget to read the entry again.
* Reserving it here and giving it to deget could result
* in a deadlock.
*/
brelse(bp);
foundroot:;
/*
* If we entered at foundroot, then we are looking for the . or ..
* entry of the filesystems root directory. isadir and scn were
* setup before jumping here. And, bp is null. There is no buf
* header.
* setup before jumping here. And, bp is already null.
*/
/*
@ -448,11 +454,9 @@ foundroot:;
/*
* Write access to directory required to delete files.
*/
if (error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc)) {
if (bp)
brelse(bp);
if (error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc))
return (error);
}
/*
* Return pointer to current entry in dp->i_offset.
* Save directory inode pointer in ndp->ni_dvp for dirremove().
@ -460,20 +464,13 @@ foundroot:;
if (dp->de_StartCluster == scn && isadir) { /* "." */
VREF(vdp);
*vpp = vdp;
if (bp)
brelse(bp);
return (0);
}
if (error = deget(pmp, cluster, blkoff, dep, &tdp)) {
if (bp)
brelse(bp);
if (error = deget(pmp, cluster, blkoff, &tdp))
return (error);
}
*vpp = DETOV(tdp);
if (!lockparent)
VOP_UNLOCK(vdp);
if (bp)
brelse(bp);
return (0);
}
@ -485,32 +482,22 @@ foundroot:;
*/
if (nameiop == RENAME && wantparent &&
(flags & ISLASTCN)) {
if (error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc)) {
if (bp)
brelse(bp);
if (error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc))
return (error);
}
/*
* Careful about locking second inode.
* This can only occur if the target is ".".
*/
if (dp->de_StartCluster == scn && isadir) {
if (bp)
brelse(bp);
if (dp->de_StartCluster == scn && isadir)
return (EISDIR);
}
error = deget(pmp, cluster, blkoff, dep, &tdp);
if (error) {
if (bp)
brelse(bp);
if (error = deget(pmp, cluster, blkoff, &tdp))
return (error);
}
*vpp = DETOV(tdp);
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
if (bp)
brelse(bp);
return (0);
}
@ -536,17 +523,13 @@ foundroot:;
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp); /* race to get the inode */
if (error = deget(pmp, cluster, blkoff, dep, &tdp)) {
if (error = deget(pmp, cluster, blkoff, &tdp)) {
VOP_LOCK(pdp);
if (bp)
brelse(bp);
return (error);
}
if (lockparent && (flags & ISLASTCN) &&
(error = VOP_LOCK(pdp))) {
vput(DETOV(tdp));
if (bp)
brelse(bp);
return (error);
}
*vpp = DETOV(tdp);
@ -554,17 +537,12 @@ foundroot:;
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
if (error = deget(pmp, cluster, blkoff, dep, &tdp)) {
if (bp)
brelse(bp);
if (error = deget(pmp, cluster, blkoff, &tdp))
return (error);
}
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
*vpp = DETOV(tdp);
}
if (bp)
brelse(bp);
/*
* Insert name into cache if appropriate.
@ -640,14 +618,6 @@ createde(dep, ddep, depp, cnp)
DE_EXTERNALIZE(ndep, dep);
/*
* If they want us to return with the denode gotten.
*/
if (depp) {
if (error = deget(pmp, dirclust, diroffset, ndep, depp))
return error;
}
/*
* Now write the Win95 long name
*/
@ -659,20 +629,17 @@ createde(dep, ddep, depp, cnp)
while (--ddep->de_fndcnt >= 0) {
if (!(ddep->de_fndoffset & pmp->pm_crbomask)) {
if (error = bwrite(bp)) {
vput(DETOV(*depp));
if (error = bwrite(bp))
return error;
}
ddep->de_fndoffset -= sizeof(struct direntry);
if (error = pcbmap(ddep,
de_cluster(pmp, ddep->de_fndoffset),
&bn, &dirclust, &blsize)) {
vput(DETOV(*depp));
&bn, &dirclust, &blsize))
return error;
}
if (error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) {
brelse(bp);
vput(DETOV(*depp));
return error;
}
ndep = bptoep(pmp, bp, ddep->de_fndoffset);
@ -685,10 +652,15 @@ createde(dep, ddep, depp, cnp)
}
}
if (error = bwrite(bp)) {
vput(DETOV(*depp)); /* free the vnode we got on error */
if (error = bwrite(bp))
return error;
}
/*
* If they want us to return with the denode gotten.
*/
if (depp)
return deget(pmp, dirclust, diroffset, depp);
return 0;
}
@ -799,15 +771,14 @@ doscheckpath(source, target)
for (;;) {
if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) {
error = ENOTDIR;
goto out;
break;
}
pmp = dep->de_pmp;
scn = dep->de_StartCluster;
if (error = bread(pmp->pm_devvp, cntobn(pmp, scn),
pmp->pm_bpcluster, NOCRED, &bp)) {
brelse(bp);
pmp->pm_bpcluster, NOCRED, &bp))
break;
}
ep = (struct direntry *) bp->b_data + 1;
if ((ep->deAttributes & ATTR_DIRECTORY) == 0 ||
bcmp(ep->deName, ".. ", 11) != 0) {
@ -822,11 +793,10 @@ doscheckpath(source, target)
if (scn == MSDOSFSROOT)
break;
vput(DETOV(dep));
/* NOTE: deget() clears dep on error */
error = deget(pmp, scn, 0, ep, &dep);
brelse(bp);
bp = NULL;
if (error)
/* NOTE: deget() clears dep on error */
if (error = deget(pmp, scn, 0, &dep))
break;
}
out:;

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vfsops.c,v 1.34 1995/10/30 19:06:20 ws Exp $ */
/* $NetBSD: msdosfs_vfsops.c,v 1.35 1995/11/05 18:47:59 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -575,7 +575,7 @@ msdosfs_root(mp, vpp)
printf("msdosfs_root(); mp %08x, pmp %08x, ndep %08x, vp %08x\n",
mp, pmp, ndep, DETOV(ndep));
#endif
if (error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, NULL, &ndep))
if (error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, &ndep))
return (error);
*vpp = DETOV(ndep);
return (0);
@ -701,8 +701,7 @@ msdosfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
np = vfs_export_lookup(mp, &pmp->pm_export, nam);
if (np == NULL)
return (EACCES);
error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs,
NULL, &dep);
error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs, &dep);
if (error) {
*vpp = NULLVP;
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vnops.c,v 1.39 1995/11/03 19:36:41 ws Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.40 1995/11/05 18:48:02 ws Exp $ */
/*-
* Copyright (C) 1994, 1995 Wolfgang Solfrank.
@ -435,13 +435,13 @@ msdosfs_read(ap)
} else {
rablock = lbn + 1;
if (vp->v_lastr + 1 == lbn &&
rablock * pmp->pm_bpcluster < dep->de_FileSize) {
error = breada(vp, lbn, pmp->pm_bpcluster,
rablock, pmp->pm_bpcluster, NOCRED, &bp);
} else {
error = bread(vp, lbn, pmp->pm_bpcluster, NOCRED,
&bp);
}
de_cn2off(pmp, rablock) < dep->de_FileSize)
error = breada(vp, de_cn2bn(pmp, lbn),
pmp->pm_bpcluster, de_cn2bn(pmp, rablock),
pmp->pm_bpcluster, NOCRED, &bp);
else
error = bread(vp, de_cn2bn(pmp, lbn),
pmp->pm_bpcluster, NOCRED, &bp);
vp->v_lastr = lbn;
}
n = min(n, pmp->pm_bpcluster - bp->b_resid);
@ -576,8 +576,9 @@ msdosfs_write(ap)
* for the fat table. (see msdosfs_strategy)
*/
if (bp->b_blkno == bp->b_lblkno) {
if (error = pcbmap(dep, bp->b_lblkno,
&bp->b_blkno, 0, 0))
if (error = pcbmap(dep,
de_bn2cn(pmp, bp->b_lblkno),
&bp->b_blkno, 0, 0))
bp->b_blkno = -1;
}
if (bp->b_blkno == -1) {
@ -590,7 +591,7 @@ msdosfs_write(ap)
/*
* The block we need to write into exists, so read it in.
*/
if (error = bread(thisvp, bn, pmp->pm_bpcluster, cred, &bp)) {
if (error = bread(thisvp, bn, pmp->pm_bpcluster, NOCRED, &bp)) {
brelse(bp);
break;
}
@ -1729,7 +1730,8 @@ msdosfs_strategy(ap)
* don't allow files with holes, so we shouldn't ever see this.
*/
if (bp->b_blkno == bp->b_lblkno) {
if (error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0, 0))
if (error = pcbmap(dep, de_bn2cn(dep->de_pmp, bp->b_lblkno),
&bp->b_blkno, 0, 0))
bp->b_blkno = -1;
if (bp->b_blkno == -1)
clrbuf(bp);