version 1.5.2.5, 2007/12/07 17:31:57 |
version 1.6, 2005/09/14 15:07:22 |
Line 57 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 57 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/vnode.h> |
#include <sys/vnode.h> |
#include <sys/mount.h> |
#include <sys/mount.h> |
#include <sys/dirent.h> |
#include <sys/dirent.h> |
#include <sys/kauth.h> |
|
|
|
#include <fs/msdosfs/bpb.h> |
#include <fs/msdosfs/bpb.h> |
#include <fs/msdosfs/direntry.h> |
#include <fs/msdosfs/direntry.h> |
Line 94 msdosfs_lookup(v) |
|
Line 93 msdosfs_lookup(v) |
|
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
daddr_t bn; |
daddr_t bn; |
int error; |
int error; |
|
int lockparent; |
|
int wantparent; |
int slotcount; |
int slotcount; |
int slotoffset = 0; |
int slotoffset = 0; |
int frcn; |
int frcn; |
Line 116 msdosfs_lookup(v) |
|
Line 117 msdosfs_lookup(v) |
|
int chksum = -1, chksum_ok; |
int chksum = -1, chksum_ok; |
int olddos = 1; |
int olddos = 1; |
|
|
|
cnp->cn_flags &= ~PDIRUNLOCK; /* XXX why this ?? */ |
flags = cnp->cn_flags; |
flags = cnp->cn_flags; |
|
|
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
Line 125 msdosfs_lookup(v) |
|
Line 127 msdosfs_lookup(v) |
|
dp = VTODE(vdp); |
dp = VTODE(vdp); |
pmp = dp->de_pmp; |
pmp = dp->de_pmp; |
*vpp = NULL; |
*vpp = NULL; |
|
lockparent = flags & LOCKPARENT; |
|
wantparent = flags & (LOCKPARENT | WANTPARENT); |
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n", |
printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n", |
vdp, dp, dp->de_Attributes); |
vdp, dp, dp->de_Attributes); |
Line 133 msdosfs_lookup(v) |
|
Line 137 msdosfs_lookup(v) |
|
/* |
/* |
* Check accessiblity of directory. |
* Check accessiblity of directory. |
*/ |
*/ |
if ((error = VOP_ACCESS(vdp, VEXEC, cnp->cn_cred)) != 0) |
if ((error = VOP_ACCESS(vdp, VEXEC, cnp->cn_cred, cnp->cn_proc)) != 0) |
return (error); |
return (error); |
|
|
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) && |
if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) && |
Line 155 msdosfs_lookup(v) |
|
Line 159 msdosfs_lookup(v) |
|
* they won't find it. DOS filesystems don't have them in the root |
* they won't find it. DOS filesystems don't have them in the root |
* directory. So, we fake it. deget() is in on this scam too. |
* directory. So, we fake it. deget() is in on this scam too. |
*/ |
*/ |
if ((vdp->v_vflag & VV_ROOT) && cnp->cn_nameptr[0] == '.' && |
if ((vdp->v_flag & VROOT) && cnp->cn_nameptr[0] == '.' && |
(cnp->cn_namelen == 1 || |
(cnp->cn_namelen == 1 || |
(cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) { |
(cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) { |
isadir = ATTR_DIRECTORY; |
isadir = ATTR_DIRECTORY; |
Line 220 msdosfs_lookup(v) |
|
Line 224 msdosfs_lookup(v) |
|
break; |
break; |
return (error); |
return (error); |
} |
} |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp); |
&bp); |
|
if (error) { |
if (error) { |
brelse(bp, 0); |
brelse(bp); |
return (error); |
return (error); |
} |
} |
for (blkoff = 0; blkoff < blsize; |
for (blkoff = 0; blkoff < blsize; |
blkoff += sizeof(struct direntry), |
blkoff += sizeof(struct direntry), |
diroff += sizeof(struct direntry)) { |
diroff += sizeof(struct direntry)) { |
dep = (struct direntry *)((char *)bp->b_data + blkoff); |
dep = (struct direntry *)(bp->b_data + blkoff); |
/* |
/* |
* If the slot is empty and we are still looking |
* If the slot is empty and we are still looking |
* for an empty then remember this one. If the |
* for an empty then remember this one. If the |
Line 251 msdosfs_lookup(v) |
|
Line 254 msdosfs_lookup(v) |
|
slotoffset = diroff; |
slotoffset = diroff; |
} |
} |
if (dep->deName[0] == SLOT_EMPTY) { |
if (dep->deName[0] == SLOT_EMPTY) { |
brelse(bp, 0); |
brelse(bp); |
goto notfound; |
goto notfound; |
} |
} |
} else { |
} else { |
Line 327 msdosfs_lookup(v) |
|
Line 330 msdosfs_lookup(v) |
|
* Release the buffer holding the directory cluster just |
* Release the buffer holding the directory cluster just |
* searched. |
* searched. |
*/ |
*/ |
brelse(bp, 0); |
brelse(bp); |
} /* for (frcn = 0; ; frcn++) */ |
} /* for (frcn = 0; ; frcn++) */ |
|
|
notfound: |
notfound: |
|
|
* Access for write is interpreted as allowing |
* Access for write is interpreted as allowing |
* creation of files in the directory. |
* creation of files in the directory. |
*/ |
*/ |
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred); |
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc); |
if (error) |
if (error) |
return (error); |
return (error); |
|
|
|
|
* information cannot be used. |
* information cannot be used. |
*/ |
*/ |
cnp->cn_flags |= SAVENAME; |
cnp->cn_flags |= SAVENAME; |
|
if (!lockparent) |
|
VOP_UNLOCK(vdp, 0); |
return (EJUSTRETURN); |
return (EJUSTRETURN); |
} |
} |
|
|
|
|
* cache doesn't understand peculiarities such as case insensitivity |
* cache doesn't understand peculiarities such as case insensitivity |
* and 8.3 filenames. Hence, it may not invalidate all negative |
* and 8.3 filenames. Hence, it may not invalidate all negative |
* entries if a file with this name is later created. |
* entries if a file with this name is later created. |
* e.g. creating a file 'foo' won't invalidate a negative entry |
|
* for 'FOO'. |
|
*/ |
*/ |
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) |
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) |
cache_enter(vdp, *vpp, cnp); |
cache_enter(vdp, *vpp, cnp); |
|
|
* Reserving it here and giving it to deget could result |
* Reserving it here and giving it to deget could result |
* in a deadlock. |
* in a deadlock. |
*/ |
*/ |
brelse(bp, 0); |
brelse(bp); |
|
|
foundroot: |
foundroot: |
/* |
/* |
|
|
/* |
/* |
* If deleting, and at end of pathname, return |
* If deleting, and at end of pathname, return |
* parameters which can be used to remove file. |
* parameters which can be used to remove file. |
* Lock the inode, being careful with ".". |
* If the wantparent flag isn't set, we return only |
|
* the directory (in ndp->ni_dvp), otherwise we go |
|
* on and lock the inode, being careful with ".". |
*/ |
*/ |
if (nameiop == DELETE && (flags & ISLASTCN)) { |
if (nameiop == DELETE && (flags & ISLASTCN)) { |
/* |
/* |
|
|
/* |
/* |
* Write access to directory required to delete files. |
* Write access to directory required to delete files. |
*/ |
*/ |
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred); |
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc); |
if (error) |
if (error) |
return (error); |
return (error); |
|
|
|
|
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) |
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) |
return (error); |
return (error); |
*vpp = DETOV(tdp); |
*vpp = DETOV(tdp); |
|
if (!lockparent) { |
|
VOP_UNLOCK(vdp, 0); |
|
cnp->cn_flags |= PDIRUNLOCK; |
|
} |
return (0); |
return (0); |
} |
} |
|
|
|
|
* Must get inode of directory entry to verify it's a |
* Must get inode of directory entry to verify it's a |
* regular file, or empty directory. |
* regular file, or empty directory. |
*/ |
*/ |
if (nameiop == RENAME && (flags & ISLASTCN)) { |
if (nameiop == RENAME && wantparent && |
|
(flags & ISLASTCN)) { |
|
|
if (vdp->v_mount->mnt_flag & MNT_RDONLY) |
if (vdp->v_mount->mnt_flag & MNT_RDONLY) |
return (EROFS); |
return (EROFS); |
|
|
if (blkoff == MSDOSFSROOT_OFS) |
if (blkoff == MSDOSFSROOT_OFS) |
return EROFS; /* really? XXX */ |
return EROFS; /* really? XXX */ |
|
|
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred); |
error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc); |
if (error) |
if (error) |
return (error); |
return (error); |
|
|
|
|
return (error); |
return (error); |
*vpp = DETOV(tdp); |
*vpp = DETOV(tdp); |
cnp->cn_flags |= SAVENAME; |
cnp->cn_flags |= SAVENAME; |
|
if (!lockparent) { |
|
VOP_UNLOCK(vdp, 0); |
|
cnp->cn_flags |= PDIRUNLOCK; |
|
} |
return (0); |
return (0); |
} |
} |
|
|
|
|
pdp = vdp; |
pdp = vdp; |
if (flags & ISDOTDOT) { |
if (flags & ISDOTDOT) { |
VOP_UNLOCK(pdp, 0); /* race to get the inode */ |
VOP_UNLOCK(pdp, 0); /* race to get the inode */ |
error = deget(pmp, cluster, blkoff, &tdp); |
cnp->cn_flags |= PDIRUNLOCK; |
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); |
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) { |
if (error) { |
if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY) == 0) |
return error; |
cnp->cn_flags &= ~PDIRUNLOCK; |
|
return (error); |
|
} |
|
if (lockparent && (flags & ISLASTCN)) { |
|
if ((error = vn_lock(pdp, LK_EXCLUSIVE))) { |
|
vput(DETOV(tdp)); |
|
return (error); |
|
} |
|
cnp->cn_flags &= ~PDIRUNLOCK; |
} |
} |
*vpp = DETOV(tdp); |
*vpp = DETOV(tdp); |
} else if (dp->de_StartCluster == scn && isadir) { |
} else if (dp->de_StartCluster == scn && isadir) { |
|
|
} else { |
} else { |
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) |
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0) |
return (error); |
return (error); |
|
if (!lockparent || !(flags & ISLASTCN)) { |
|
VOP_UNLOCK(pdp, 0); |
|
cnp->cn_flags |= PDIRUNLOCK; |
|
} |
*vpp = DETOV(tdp); |
*vpp = DETOV(tdp); |
} |
} |
|
|
Line 606 createde(dep, ddep, depp, cnp) |
|
Line 632 createde(dep, ddep, depp, cnp) |
|
- ddep->de_FileSize; |
- ddep->de_FileSize; |
dirclust = de_clcount(pmp, needlen); |
dirclust = de_clcount(pmp, needlen); |
if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) { |
if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) { |
(void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED); |
(void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED, NULL); |
goto err_norollback; |
goto err_norollback; |
} |
} |
|
|
Line 628 createde(dep, ddep, depp, cnp) |
|
Line 654 createde(dep, ddep, depp, cnp) |
|
clusoffset = ddep->de_fndoffset; |
clusoffset = ddep->de_fndoffset; |
if (dirclust != MSDOSFSROOT) |
if (dirclust != MSDOSFSROOT) |
clusoffset &= pmp->pm_crbomask; |
clusoffset &= pmp->pm_crbomask; |
if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) { |
&bp)) != 0) { |
brelse(bp); |
brelse(bp, 0); |
|
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, clusoffset); |
ndep = bptoep(pmp, bp, clusoffset); |
Line 666 createde(dep, ddep, depp, cnp) |
|
Line 691 createde(dep, ddep, depp, cnp) |
|
if (error) |
if (error) |
goto rollback; |
goto rollback; |
|
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
error = bread(pmp->pm_devvp, bn, blsize, |
blsize, NOCRED, &bp); |
NOCRED, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
brelse(bp); |
goto rollback; |
goto rollback; |
} |
} |
ndep = bptoep(pmp, bp, |
ndep = bptoep(pmp, bp, |
Line 719 createde(dep, ddep, depp, cnp) |
|
Line 744 createde(dep, ddep, depp, cnp) |
|
&bn, NULL, &blsize); |
&bn, NULL, &blsize); |
if (rberror) |
if (rberror) |
goto err_norollback; |
goto err_norollback; |
if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if ((rberror = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) { |
&bp)) != 0) { |
brelse(bp); |
brelse(bp, 0); |
|
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, clusoffset); |
ndep = bptoep(pmp, bp, clusoffset); |
Line 747 createde(dep, ddep, depp, cnp) |
|
Line 771 createde(dep, ddep, depp, cnp) |
|
if (rberror) |
if (rberror) |
goto err_norollback; |
goto err_norollback; |
|
|
rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
rberror = bread(pmp->pm_devvp, bn, blsize, |
blsize, NOCRED, &bp); |
NOCRED, &bp); |
if (rberror) { |
if (rberror) { |
brelse(bp, 0); |
brelse(bp); |
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, fndoffset); |
ndep = bptoep(pmp, bp, fndoffset); |
Line 797 dosdirempty(dep) |
|
Line 821 dosdirempty(dep) |
|
return (1); /* it's empty */ |
return (1); /* it's empty */ |
return (0); |
return (0); |
} |
} |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp); |
&bp); |
|
if (error) { |
if (error) { |
brelse(bp, 0); |
brelse(bp); |
return (0); |
return (0); |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |
(char *)dentp < (char *)bp->b_data + blsize; |
(char *)dentp < bp->b_data + blsize; |
dentp++) { |
dentp++) { |
if (dentp->deName[0] != SLOT_DELETED && |
if (dentp->deName[0] != SLOT_DELETED && |
(dentp->deAttributes & ATTR_VOLUME) == 0) { |
(dentp->deAttributes & ATTR_VOLUME) == 0) { |
Line 816 dosdirempty(dep) |
|
Line 839 dosdirempty(dep) |
|
* is empty. |
* is empty. |
*/ |
*/ |
if (dentp->deName[0] == SLOT_EMPTY) { |
if (dentp->deName[0] == SLOT_EMPTY) { |
brelse(bp, 0); |
brelse(bp); |
return (1); |
return (1); |
} |
} |
/* |
/* |
Line 825 dosdirempty(dep) |
|
Line 848 dosdirempty(dep) |
|
*/ |
*/ |
if (memcmp(dentp->deName, ". ", 11) && |
if (memcmp(dentp->deName, ". ", 11) && |
memcmp(dentp->deName, ".. ", 11)) { |
memcmp(dentp->deName, ".. ", 11)) { |
brelse(bp, 0); |
brelse(bp); |
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
printf("dosdirempty(): found %.11s, %d, %d\n", |
printf("dosdirempty(): found %.11s, %d, %d\n", |
dentp->deName, dentp->deName[0], |
dentp->deName, dentp->deName[0], |
Line 835 dosdirempty(dep) |
|
Line 858 dosdirempty(dep) |
|
} |
} |
} |
} |
} |
} |
brelse(bp, 0); |
brelse(bp); |
} |
} |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
Line 891 doscheckpath(source, target) |
|
Line 914 doscheckpath(source, target) |
|
break; |
break; |
} |
} |
scn = dep->de_StartCluster; |
scn = dep->de_StartCluster; |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, cntobn(pmp, scn)), |
error = bread(pmp->pm_devvp, cntobn(pmp, scn), |
pmp->pm_bpcluster, NOCRED, &bp); |
pmp->pm_bpcluster, NOCRED, &bp); |
if (error) |
if (error) |
break; |
break; |
Line 921 doscheckpath(source, target) |
|
Line 944 doscheckpath(source, target) |
|
} |
} |
|
|
vput(DETOV(dep)); |
vput(DETOV(dep)); |
brelse(bp, 0); |
brelse(bp); |
bp = NULL; |
bp = NULL; |
/* NOTE: deget() clears dep on error */ |
/* NOTE: deget() clears dep on error */ |
if ((error = deget(pmp, scn, 0, &dep)) != 0) |
if ((error = deget(pmp, scn, 0, &dep)) != 0) |
Line 929 doscheckpath(source, target) |
|
Line 952 doscheckpath(source, target) |
|
} |
} |
out: |
out: |
if (bp) |
if (bp) |
brelse(bp, 0); |
brelse(bp); |
if (error == ENOTDIR) |
if (error == ENOTDIR) |
printf("doscheckpath(): .. not a directory?\n"); |
printf("doscheckpath(): .. not a directory?\n"); |
if (dep != NULL) |
if (dep != NULL) |
Line 958 readep(pmp, dirclust, diroffset, bpp, ep |
|
Line 981 readep(pmp, dirclust, diroffset, bpp, ep |
|
&& de_blk(pmp, diroffset + blsize) > pmp->pm_rootdirsize) |
&& de_blk(pmp, diroffset + blsize) > pmp->pm_rootdirsize) |
blsize = de_bn2off(pmp, pmp->pm_rootdirsize) & pmp->pm_crbomask; |
blsize = de_bn2off(pmp, pmp->pm_rootdirsize) & pmp->pm_crbomask; |
bn = detobn(pmp, dirclust, diroffset); |
bn = detobn(pmp, dirclust, diroffset); |
if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, bpp)) != 0) { |
bpp)) != 0) { |
brelse(*bpp); |
brelse(*bpp, 0); |
|
*bpp = NULL; |
*bpp = NULL; |
return (error); |
return (error); |
} |
} |
Line 1018 removede(pdep, dep) |
|
Line 1040 removede(pdep, dep) |
|
error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize); |
error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize); |
if (error) |
if (error) |
return error; |
return error; |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp); |
&bp); |
|
if (error) { |
if (error) { |
brelse(bp, 0); |
brelse(bp); |
return error; |
return error; |
} |
} |
ep = bptoep(pmp, bp, offset); |
ep = bptoep(pmp, bp, offset); |
Line 1032 removede(pdep, dep) |
|
Line 1053 removede(pdep, dep) |
|
*/ |
*/ |
if (ep->deAttributes != ATTR_WIN95 |
if (ep->deAttributes != ATTR_WIN95 |
&& offset != pdep->de_fndoffset) { |
&& offset != pdep->de_fndoffset) { |
brelse(bp, 0); |
brelse(bp); |
break; |
break; |
} |
} |
offset += sizeof(struct direntry); |
offset += sizeof(struct direntry); |
Line 1095 uniqdosname(dep, cnp, cp) |
|
Line 1116 uniqdosname(dep, cnp, cp) |
|
return 0; |
return 0; |
return error; |
return error; |
} |
} |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, |
error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp); |
NOCRED, &bp); |
|
if (error) { |
if (error) { |
brelse(bp, 0); |
brelse(bp); |
return error; |
return error; |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |
(char *)dentp < (char *)bp->b_data + blsize; |
(char *)dentp < bp->b_data + blsize; |
dentp++) { |
dentp++) { |
if (dentp->deName[0] == SLOT_EMPTY) { |
if (dentp->deName[0] == SLOT_EMPTY) { |
/* |
/* |
* Last used entry and not found |
* Last used entry and not found |
*/ |
*/ |
brelse(bp, 0); |
brelse(bp); |
return 0; |
return 0; |
} |
} |
/* |
/* |
Line 1121 uniqdosname(dep, cnp, cp) |
|
Line 1141 uniqdosname(dep, cnp, cp) |
|
break; |
break; |
} |
} |
} |
} |
brelse(bp, 0); |
brelse(bp); |
} |
} |
} |
} |
} |
} |
|
|
for (cn = 0;; cn++) { |
for (cn = 0;; cn++) { |
if (pcbmap(dep, cn, &bn, 0, &blsize)) |
if (pcbmap(dep, cn, &bn, 0, &blsize)) |
return 0; |
return 0; |
if (bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if (bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) { |
&bp)) { |
brelse(bp); |
brelse(bp, 0); |
|
return 0; |
return 0; |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |
(char *)dentp < (char *)bp->b_data + blsize; |
(char *)dentp < bp->b_data + blsize; |
dentp++) { |
dentp++) { |
if (dentp->deName[0] == SLOT_EMPTY) { |
if (dentp->deName[0] == SLOT_EMPTY) { |
/* |
/* |
* Last used entry and not found |
* Last used entry and not found |
*/ |
*/ |
brelse(bp, 0); |
brelse(bp); |
return 0; |
return 0; |
} |
} |
if (dentp->deName[0] == SLOT_DELETED) { |
if (dentp->deName[0] == SLOT_DELETED) { |
|
|
continue; |
continue; |
} |
} |
if (dentp->deAttributes == ATTR_WIN95) { |
if (dentp->deAttributes == ATTR_WIN95) { |
brelse(bp, 0); |
brelse(bp); |
return 1; |
return 1; |
} |
} |
} |
} |
brelse(bp, 0); |
brelse(bp); |
} |
} |
} |
} |