version 1.23, 2010/11/30 10:43:03 |
version 1.23.8.4, 2014/05/22 11:41:00 |
|
|
* October 1992 |
* October 1992 |
*/ |
*/ |
|
|
|
#if HAVE_NBTOOL_CONFIG_H |
|
#include "nbtool_config.h" |
|
#endif |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
|
|
|
#ifdef _KERNEL |
#include <sys/systm.h> |
#include <sys/systm.h> |
|
#include <sys/mount.h> |
|
#include <sys/kauth.h> |
#include <sys/namei.h> |
#include <sys/namei.h> |
|
#include <sys/dirent.h> |
#include <sys/buf.h> |
#include <sys/buf.h> |
#include <sys/vnode.h> |
#include <sys/vnode.h> |
#include <sys/mount.h> |
#else |
#include <sys/dirent.h> |
#include <ffs/buf.h> |
#include <sys/kauth.h> |
#endif /* _KERNEL */ |
|
|
#include <fs/msdosfs/bpb.h> |
#include <fs/msdosfs/bpb.h> |
#include <fs/msdosfs/direntry.h> |
#include <fs/msdosfs/direntry.h> |
Line 65 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 74 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <fs/msdosfs/msdosfsmount.h> |
#include <fs/msdosfs/msdosfsmount.h> |
#include <fs/msdosfs/fat.h> |
#include <fs/msdosfs/fat.h> |
|
|
|
|
|
#ifdef _KERNEL |
/* |
/* |
* When we search a directory the blocks containing directory entries are |
* When we search a directory the blocks containing directory entries are |
* read and examined. The directory entries contain information that would |
* read and examined. The directory entries contain information that would |
Line 83 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 94 __KERNEL_RCSID(0, "$NetBSD$"); |
|
int |
int |
msdosfs_lookup(void *v) |
msdosfs_lookup(void *v) |
{ |
{ |
struct vop_lookup_args /* { |
struct vop_lookup_v2_args /* { |
struct vnode *a_dvp; |
struct vnode *a_dvp; |
struct vnode **a_vpp; |
struct vnode **a_vpp; |
struct componentname *a_cnp; |
struct componentname *a_cnp; |
Line 146 msdosfs_lookup(void *v) |
|
Line 157 msdosfs_lookup(void *v) |
|
* check the name cache to see if the directory/name pair |
* check the name cache to see if the directory/name pair |
* we are looking for is known already. |
* we are looking for is known already. |
*/ |
*/ |
if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) |
if (cache_lookup(vdp, cnp->cn_nameptr, cnp->cn_namelen, |
return (error); |
cnp->cn_nameiop, cnp->cn_flags, NULL, vpp)) { |
|
return *vpp == NULLVP ? ENOENT: 0; |
|
} |
|
|
/* |
/* |
* If they are going after the . or .. entry in the root directory, |
* If they are going after the . or .. entry in the root directory, |
Line 222 msdosfs_lookup(void *v) |
|
Line 235 msdosfs_lookup(void *v) |
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
0, &bp); |
0, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return (error); |
return (error); |
} |
} |
for (blkoff = 0; blkoff < blsize; |
for (blkoff = 0; blkoff < blsize; |
Line 288 msdosfs_lookup(void *v) |
|
Line 300 msdosfs_lookup(void *v) |
|
* Check for a checksum or name match |
* Check for a checksum or name match |
*/ |
*/ |
chksum_ok = (chksum == winChksum(dep->deName)); |
chksum_ok = (chksum == winChksum(dep->deName)); |
if (!chksum_ok |
if (!chksum_ok && ( |
&& (!olddos || memcmp(dosfilename, dep->deName, 11))) { |
!olddos || |
|
memcmp(&dosfilename[0],dep->deName,8) || |
|
memcmp(&dosfilename[8],dep->deExtension,3))) { |
chksum = -1; |
chksum = -1; |
continue; |
continue; |
} |
} |
|
|
* e.g. creating a file 'foo' won't invalidate a negative entry |
* e.g. creating a file 'foo' won't invalidate a negative entry |
* for 'FOO'. |
* for 'FOO'. |
*/ |
*/ |
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) |
if (nameiop != CREATE) |
cache_enter(vdp, *vpp, cnp); |
cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, |
|
cnp->cn_flags); |
#endif |
#endif |
|
|
return (ENOENT); |
return (ENOENT); |
|
|
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); |
|
VOP_UNLOCK(*vpp); |
return (0); |
return (0); |
} |
} |
|
|
|
|
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); |
|
VOP_UNLOCK(*vpp); |
return (0); |
return (0); |
} |
} |
|
|
|
|
/* |
/* |
* Insert name into cache if appropriate. |
* Insert name into cache if appropriate. |
*/ |
*/ |
if (cnp->cn_flags & MAKEENTRY) |
cache_enter(vdp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); |
cache_enter(vdp, *vpp, cnp); |
|
|
|
return (0); |
if (*vpp != vdp) |
|
VOP_UNLOCK(*vpp); |
|
|
|
return 0; |
} |
} |
|
#endif /* _KERNEL */ |
|
|
/* |
/* |
* dep - directory entry to copy into the directory |
* dep - directory entry to copy into the directory |
Line 571 createde(struct denode *dep, struct deno |
|
Line 591 createde(struct denode *dep, struct deno |
|
{ |
{ |
int error, rberror; |
int error, rberror; |
u_long dirclust, clusoffset; |
u_long dirclust, clusoffset; |
u_long fndoffset, havecnt=0, wcnt=1; |
u_long fndoffset, havecnt = 0, wcnt = 1, i; |
struct direntry *ndep; |
struct direntry *ndep; |
struct msdosfsmount *pmp = ddep->de_pmp; |
struct msdosfsmount *pmp = ddep->de_pmp; |
struct buf *bp; |
struct buf *bp; |
daddr_t bn; |
daddr_t bn; |
int blsize, i; |
int blsize; |
|
#ifdef _KERNEL |
int async = ddep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC; |
int async = ddep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC; |
|
#else |
|
#define async 0 |
|
#endif |
|
|
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n", |
printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n", |
Line 621 createde(struct denode *dep, struct deno |
|
Line 645 createde(struct denode *dep, struct deno |
|
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, de_bn2kb(pmp, bn), blsize, NOCRED, |
B_MODIFY, &bp)) != 0) { |
B_MODIFY, &bp)) != 0) { |
brelse(bp, 0); |
|
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, clusoffset); |
ndep = bptoep(pmp, bp, clusoffset); |
Line 660 createde(struct denode *dep, struct deno |
|
Line 683 createde(struct denode *dep, struct deno |
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
blsize, NOCRED, B_MODIFY, &bp); |
blsize, NOCRED, B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
goto rollback; |
goto rollback; |
} |
} |
ndep = bptoep(pmp, bp, |
ndep = bptoep(pmp, bp, |
Line 694 createde(struct denode *dep, struct deno |
|
Line 716 createde(struct denode *dep, struct deno |
|
else |
else |
diroffset = 0; |
diroffset = 0; |
} |
} |
return deget(pmp, dirclust, diroffset, depp); |
error = deget(pmp, dirclust, diroffset, depp); |
|
#ifndef MAKEFS |
|
if (error == 0) |
|
VOP_UNLOCK(DETOV(*depp)); |
|
#endif |
|
return error; |
} |
} |
|
|
return 0; |
return 0; |
Line 712 createde(struct denode *dep, struct deno |
|
Line 739 createde(struct denode *dep, struct deno |
|
goto err_norollback; |
goto err_norollback; |
if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
B_MODIFY, &bp)) != 0) { |
B_MODIFY, &bp)) != 0) { |
brelse(bp, 0); |
|
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, clusoffset); |
ndep = bptoep(pmp, bp, clusoffset); |
|
|
havecnt = ddep->de_fndcnt + 1; |
havecnt = ddep->de_fndcnt + 1; |
for(i=wcnt; i <= havecnt; i++) { |
for(i = wcnt; i <= havecnt; i++) { |
/* mark entry as deleted */ |
/* mark entry as deleted */ |
ndep->deName[0] = SLOT_DELETED; |
ndep->deName[0] = SLOT_DELETED; |
|
|
Line 741 createde(struct denode *dep, struct deno |
|
Line 767 createde(struct denode *dep, struct deno |
|
rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), |
blsize, NOCRED, B_MODIFY, &bp); |
blsize, NOCRED, B_MODIFY, &bp); |
if (rberror) { |
if (rberror) { |
brelse(bp, 0); |
|
goto err_norollback; |
goto err_norollback; |
} |
} |
ndep = bptoep(pmp, bp, fndoffset); |
ndep = bptoep(pmp, bp, fndoffset); |
Line 790 dosdirempty(struct denode *dep) |
|
Line 815 dosdirempty(struct denode *dep) |
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
0, &bp); |
0, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return (0); |
return (0); |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |
Line 944 readep(struct msdosfsmount *pmp, u_long |
|
Line 968 readep(struct msdosfsmount *pmp, u_long |
|
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, de_bn2kb(pmp, bn), blsize, NOCRED, |
0, bpp)) != 0) { |
0, bpp)) != 0) { |
brelse(*bpp, 0); |
|
*bpp = NULL; |
*bpp = NULL; |
return (error); |
return (error); |
} |
} |
Line 985 removede(struct denode *pdep, struct den |
|
Line 1008 removede(struct denode *pdep, struct den |
|
int blsize; |
int blsize; |
struct msdosfsmount *pmp = pdep->de_pmp; |
struct msdosfsmount *pmp = pdep->de_pmp; |
u_long offset = pdep->de_fndoffset; |
u_long offset = pdep->de_fndoffset; |
|
#ifdef _KERNEL |
int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC; |
int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC; |
|
#else |
|
#define async 0 |
|
#endif |
|
|
#ifdef MSDOSFS_DEBUG |
#ifdef MSDOSFS_DEBUG |
printf("removede(): filename %s, dep %p, offset %08lx\n", |
printf("removede(): filename %s, dep %p, offset %08lx\n", |
Line 1002 removede(struct denode *pdep, struct den |
|
Line 1029 removede(struct denode *pdep, struct den |
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
B_MODIFY, &bp); |
B_MODIFY, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return error; |
return error; |
} |
} |
ep = bptoep(pmp, bp, offset); |
ep = bptoep(pmp, bp, offset); |
Line 1076 uniqdosname(struct denode *dep, struct c |
|
Line 1102 uniqdosname(struct denode *dep, struct c |
|
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, |
error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, |
NOCRED, 0, &bp); |
NOCRED, 0, &bp); |
if (error) { |
if (error) { |
brelse(bp, 0); |
|
return error; |
return error; |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |
Line 1127 findwin95(struct denode *dep) |
|
Line 1152 findwin95(struct denode *dep) |
|
return win95; |
return win95; |
if (bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
if (bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, |
0, &bp)) { |
0, &bp)) { |
brelse(bp, 0); |
|
return win95; |
return win95; |
} |
} |
for (dentp = (struct direntry *)bp->b_data; |
for (dentp = (struct direntry *)bp->b_data; |