finish updating to new vnode interface, from ws.
This commit is contained in:
parent
fc5405fc33
commit
fb6819f643
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: denode.h,v 1.5 1994/07/16 21:33:17 cgd Exp $ */
|
||||
/* $NetBSD: denode.h,v 1.6 1994/07/18 21:38:08 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -132,14 +162,10 @@ struct denode {
|
|||
/*
|
||||
* Values for the de_flag field of the denode.
|
||||
*/
|
||||
#define DELOCKED 0x0001 /* directory entry is locked */
|
||||
#define DEWANT 0x0002 /* someone wants this de */
|
||||
#define DERENAME 0x0004 /* de is being renamed */
|
||||
#define DEUPD 0x0008 /* file has been modified */
|
||||
#define DESHLOCK 0x0010 /* file has shared lock */
|
||||
#define DEEXLOCK 0x0020 /* file has exclusive lock */
|
||||
#define DELWAIT 0x0040 /* someone waiting on file lock */
|
||||
#define DEMOD 0x0080 /* denode wants to be written back to disk */
|
||||
#define DE_LOCKED 0x0001 /* directory entry is locked */
|
||||
#define DE_WANT 0x0002 /* someone wants this de */
|
||||
#define DE_UPD 0x0004 /* file has been modified */
|
||||
#define DE_MOD 0x0080 /* denode wants to be written back to disk */
|
||||
|
||||
/*
|
||||
* Transfer directory entries between internal and external form.
|
||||
|
@ -165,23 +191,20 @@ struct denode {
|
|||
#define de_forw de_chain[0]
|
||||
#define de_back de_chain[1]
|
||||
|
||||
#if defined(KERNEL)
|
||||
#ifdef KERNEL
|
||||
|
||||
#define VTODE(vp) ((struct denode *)(vp)->v_data)
|
||||
#define DETOV(de) ((de)->de_vnode)
|
||||
|
||||
#define DELOCK(de) delock(de)
|
||||
#define DEUNLOCK(de) deunlock(de)
|
||||
|
||||
#define DEUPDAT(dep, t, waitfor) \
|
||||
if (dep->de_flag & DEUPD) \
|
||||
#define DE_UPDAT(dep, t, waitfor) \
|
||||
if (dep->de_flag & DE_UPD) \
|
||||
(void) deupdat(dep, t, waitfor);
|
||||
|
||||
#define DETIMES(dep, t) \
|
||||
if (dep->de_flag & DEUPD) { \
|
||||
(dep)->de_flag |= DEMOD; \
|
||||
#define DE_TIMES(dep, t) \
|
||||
if (dep->de_flag & DE_UPD) { \
|
||||
(dep)->de_flag |= DE_MOD; \
|
||||
unix2dostime(t, &dep->de_Date, &dep->de_Time); \
|
||||
(dep)->de_flag &= ~DEUPD; \
|
||||
(dep)->de_flag &= ~DE_UPD; \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -239,11 +262,4 @@ int msdosfs_reallocblks __P((struct vop_reallocblks_args *));
|
|||
* Internal service routine prototypes.
|
||||
*/
|
||||
int deget __P((struct msdosfsmount * pmp, u_long dirclust, u_long diroffset, struct direntry * direntptr, struct denode ** depp));
|
||||
|
||||
static void deput __P((struct denode *dep));
|
||||
static __inline void deput(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
vput(DETOV(dep));
|
||||
}
|
||||
#endif /* defined(KERNEL) */
|
||||
#endif /* KERNEL */
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: direntry.h,v 1.5 1994/07/16 21:33:19 cgd Exp $ */
|
||||
/* $NetBSD: direntry.h,v 1.6 1994/07/18 21:38:10 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -64,9 +94,9 @@ struct direntry {
|
|||
#define DD_YEAR_MASK 0xFE00 /* year - 1980 */
|
||||
#define DD_YEAR_SHIFT 9
|
||||
|
||||
#if defined(KERNEL)
|
||||
#ifdef KERNEL
|
||||
void unix2dostime __P((struct timespec * tsp, u_short * ddp, u_short * dtp));
|
||||
void dos2unixtime __P((u_short dd, u_short dt, struct timespec * tsp));
|
||||
int dos2unixfn __P((u_char dn[11], u_char * un));
|
||||
void unix2dosfn __P((u_char * un, u_char dn[11], int unlen));
|
||||
#endif /* defined(KERNEL) */
|
||||
#endif /* KERNEL */
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: fat.h,v 1.2 1994/06/29 06:35:33 cgd Exp $ */
|
||||
/* $NetBSD: fat.h,v 1.3 1994/07/18 21:38:11 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -42,6 +72,7 @@
|
|||
|
||||
#define MSDOSFSEOF(cn) (((cn) & 0xfff8) == 0xfff8)
|
||||
|
||||
#ifdef KERNEL
|
||||
/*
|
||||
* These are the values for the function argument to the function
|
||||
* fatentry().
|
||||
|
@ -50,10 +81,15 @@
|
|||
#define FAT_SET 0x0002 /* set a fat entry */
|
||||
#define FAT_GET_AND_SET (FAT_GET | FAT_SET)
|
||||
|
||||
#if defined(KERNEL)
|
||||
int pcbmap __P((struct denode * dep, u_long findcn, daddr_t * bnp, u_long * cnp));
|
||||
int clusterfree __P((struct msdosfsmount * pmp, u_long cn, u_long * oldcnp));
|
||||
int clusteralloc __P((struct msdosfsmount * pmp, u_long * retcluster, u_long fillwith));
|
||||
int fatentry __P((int function, struct msdosfsmount * pmp, u_long cluster, u_long * oldcontents, u_long newcontents));
|
||||
int freeclusterchain __P((struct msdosfsmount * pmp, u_long startchain));
|
||||
#endif /* defined(KERNEL) */
|
||||
/*
|
||||
* Flags to extendfile:
|
||||
*/
|
||||
#define DE_CLEAR 1 /* Zero out the blocks allocated */
|
||||
|
||||
int pcbmap __P((struct denode *dep, u_long findcn, daddr_t *bnp, u_long *cnp));
|
||||
int clusterfree __P((struct msdosfsmount *pmp, u_long cn, u_long *oldcnp));
|
||||
int clusteralloc __P((struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, u_long *got));
|
||||
int fatentry __P((int function, struct msdosfsmount *pmp, u_long cluster, u_long *oldcontents, u_long newcontents));
|
||||
int freeclusterchain __P((struct msdosfsmount *pmp, u_long startchain));
|
||||
int extendfile __P((struct denode *dep, u_long count, struct buf **bpp, u_long *ncp, int flags));
|
||||
#endif /* KERNEL */
|
||||
|
|
|
@ -1,14 +1,44 @@
|
|||
/* $NetBSD: msdosfs_denode.c,v 1.6 1994/07/16 21:33:20 cgd Exp $ */
|
||||
/* $NetBSD: msdosfs_denode.c,v 1.7 1994/07/18 21:38:12 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
* You can do anything you want with this software, just don't say you wrote
|
||||
* it, and don't reoove this notice.
|
||||
* it, and don't remove this notice.
|
||||
*
|
||||
* This software is provided "as is".
|
||||
*
|
||||
* The authop supplies this software to be publicly redistributed on the
|
||||
* The author supplies this software to be publicly redistributed on the
|
||||
* understanding that the author is not responsible for the correct
|
||||
* functioning of this software in any circumstances and is not liable for
|
||||
* any damages caused by this software.
|
||||
|
@ -58,8 +88,8 @@ msdosfs_hashget(dev, dirclust, diroff)
|
|||
|| dev != dep->de_dev
|
||||
|| dep->de_refcnt == 0)
|
||||
continue;
|
||||
if (dep->de_flag & DELOCKED) {
|
||||
dep->de_flag |= DEWANT;
|
||||
if (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANT;
|
||||
sleep((caddr_t)dep, PINOD);
|
||||
break;
|
||||
}
|
||||
|
@ -82,13 +112,13 @@ msdosfs_hashins(dep)
|
|||
dep->de_next = deq;
|
||||
dep->de_prev = depp;
|
||||
*depp = dep;
|
||||
if (dep->de_flag & DELOCKED)
|
||||
if (dep->de_flag & DE_LOCKED)
|
||||
panic("msdosfs_hashins: already locked");
|
||||
if (curproc)
|
||||
dep->de_lockholder = curproc->p_pid;
|
||||
else
|
||||
dep->de_lockholder = -1;
|
||||
dep->de_flag |= DELOCKED;
|
||||
dep->de_flag |= DE_LOCKED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -135,10 +165,10 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
|
|||
struct vnode *nvp;
|
||||
struct buf *bp;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("deget(pmp %08x, dirclust %d, diroffset %x, direntptr %x, depp %08x)\n",
|
||||
pmp, dirclust, diroffset, direntptr, depp);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If dir entry is given and refers to a directory, convert to
|
||||
|
@ -284,9 +314,9 @@ deupdat(dep, tp, waitfor)
|
|||
struct timespec ts;
|
||||
struct vnode *vp = DETOV(dep);
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("deupdat(): dep %08x\n", dep);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the update bit is off, or this denode is from a readonly
|
||||
|
@ -295,7 +325,7 @@ deupdat(dep, tp, waitfor)
|
|||
* directory entries that describe a directory do not ever get
|
||||
* updated. This is the way dos treats them.
|
||||
*/
|
||||
if ((dep->de_flag & DEUPD) == 0 ||
|
||||
if ((dep->de_flag & DE_UPD) == 0 ||
|
||||
vp->v_mount->mnt_flag & MNT_RDONLY ||
|
||||
dep->de_Attributes & ATTR_DIRECTORY ||
|
||||
dep->de_refcnt <= 0)
|
||||
|
@ -313,7 +343,7 @@ deupdat(dep, tp, waitfor)
|
|||
*/
|
||||
TIMEVAL_TO_TIMESPEC(&time, &ts);
|
||||
unix2dostime(&ts, &dep->de_Date, &dep->de_Time);
|
||||
dep->de_flag &= ~DEUPD;
|
||||
dep->de_flag &= ~DE_UPD;
|
||||
|
||||
/*
|
||||
* Copy the directory entry out of the denode into the cluster it
|
||||
|
@ -356,9 +386,9 @@ detrunc(dep, length, flags, cred, p)
|
|||
struct buf *bp;
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("detrunc(): file %s, length %d, flags %d\n", dep->de_Name, length, flags);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disallow attempts to truncate the root directory since it is of
|
||||
|
@ -376,14 +406,8 @@ detrunc(dep, length, flags, cred, p)
|
|||
|
||||
vnode_pager_setsize(DETOV(dep), length);
|
||||
|
||||
if (dep->de_FileSize <= length) {
|
||||
dep->de_flag |= DEUPD;
|
||||
error = deupdat(dep, &time, 1);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("detrunc(): file is shorter return point, errno %d\n", error);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
return error;
|
||||
}
|
||||
if (dep->de_FileSize < length)
|
||||
return deextend(dep, length, cred);
|
||||
|
||||
/*
|
||||
* If the desired length is 0 then remember the starting cluster of
|
||||
|
@ -399,12 +423,10 @@ detrunc(dep, length, flags, cred, p)
|
|||
dep->de_StartCluster = 0;
|
||||
eofentry = ~0;
|
||||
} else {
|
||||
error = pcbmap(dep, (length - 1) >> pmp->pm_cnshift,
|
||||
0, &eofentry);
|
||||
if (error) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
if (error = pcbmap(dep, de_clcount(pmp, length) - 1, 0, &eofentry)) {
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("detrunc(): pcbmap fails %d\n", error);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
@ -426,14 +448,14 @@ detrunc(dep, length, flags, cred, p)
|
|||
error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
|
||||
NOCRED, &bp);
|
||||
} else {
|
||||
bn = (length - 1) >> pmp->pm_cnshift;
|
||||
bn = de_blk(pmp, length);
|
||||
error = bread(DETOV(dep), bn, pmp->pm_bpcluster,
|
||||
NOCRED, &bp);
|
||||
}
|
||||
if (error) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("detrunc(): bread fails %d\n", error);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
vnode_pager_uncache(DETOV(dep)); /* what's this for? */
|
||||
|
@ -452,14 +474,14 @@ detrunc(dep, length, flags, cred, p)
|
|||
* we free the trailing clusters.
|
||||
*/
|
||||
dep->de_FileSize = length;
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
vflags = (length > 0 ? V_SAVE : 0) | V_SAVEMETA;
|
||||
vinvalbuf(DETOV(dep), vflags, cred, p, 0, 0);
|
||||
allerror = deupdat(dep, &time, MNT_WAIT);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
allerror = deupdat(dep, &time, 1);
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("detrunc(): allerror %d, eofentry %d\n",
|
||||
allerror, eofentry);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we need to break the cluster chain for the file then do it
|
||||
|
@ -469,9 +491,9 @@ detrunc(dep, length, flags, cred, p)
|
|||
error = fatentry(FAT_GET_AND_SET, pmp, eofentry,
|
||||
&chaintofree, CLUST_EOFE);
|
||||
if (error) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("detrunc(): fatentry errors %d\n", error);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
fc_setcache(dep, FC_LASTFC, (length - 1) >> pmp->pm_cnshift,
|
||||
|
@ -498,9 +520,8 @@ deextend(dep, length, cred)
|
|||
struct ucred *cred;
|
||||
{
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
off_t foff;
|
||||
u_long count;
|
||||
int error;
|
||||
struct buf *bp;
|
||||
|
||||
/*
|
||||
* The root of a DOS filesystem cannot be extended.
|
||||
|
@ -521,20 +542,22 @@ deextend(dep, length, cred)
|
|||
panic("deextend: file too large");
|
||||
|
||||
/*
|
||||
* Compute the offset of the first byte after the last block in the
|
||||
* file.
|
||||
* Compute the number of clusters to allocate.
|
||||
*/
|
||||
foff = (dep->de_FileSize + (pmp->pm_bpcluster - 1)) & ~pmp->pm_crbomask;
|
||||
while (foff < length) {
|
||||
if (error = extendfile(dep, &bp, 0))
|
||||
count = de_clcount(pmp, length) - de_clcount(pmp, dep->de_FileSize);
|
||||
if (count > 0) {
|
||||
if (count > pmp->pm_freeclustercount)
|
||||
return ENOSPC;
|
||||
if (error = extendfile(dep, count, NULL, NULL, DE_CLEAR)) {
|
||||
/* truncate the added clusters away again */
|
||||
(void) detrunc(dep, dep->de_FileSize, 0, cred, NULL);
|
||||
return error;
|
||||
dep->de_flag |= DEUPD;
|
||||
bdwrite(bp);
|
||||
foff += pmp->pm_bpcluster;
|
||||
dep->de_FileSize += pmp->pm_bpcluster;
|
||||
}
|
||||
}
|
||||
|
||||
dep->de_flag |= DE_UPD;
|
||||
dep->de_FileSize = length;
|
||||
return deupdat(dep, &time);
|
||||
return deupdat(dep, &time, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -544,7 +567,6 @@ deextend(dep, length, cred)
|
|||
reinsert(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
union dehead *deh;
|
||||
|
||||
/*
|
||||
|
@ -572,10 +594,10 @@ msdosfs_reclaim(ap)
|
|||
int i;
|
||||
extern int prtactive;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_reclaim(): dep %08x, file %s, refcnt %d\n",
|
||||
dep, dep->de_Name, dep->de_refcnt);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("msdosfs_reclaim(): pushing active", vp);
|
||||
|
@ -613,9 +635,9 @@ msdosfs_inactive(ap)
|
|||
int error = 0;
|
||||
extern int prtactive;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_inactive(): dep %08x, de_Name[0] %x\n", dep, dep->de_Name[0]);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("msdosfs_inactive(): pushing active", vp);
|
||||
|
@ -635,63 +657,29 @@ msdosfs_inactive(ap)
|
|||
* filesystem, then truncate the file, and mark the directory slot
|
||||
* as empty. (This may not be necessary for the dos filesystem.)
|
||||
*/
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_inactive(): dep %08x, refcnt %d, mntflag %x, MNT_RDONLY %x\n",
|
||||
dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
DELOCK(dep);
|
||||
#endif
|
||||
VOP_LOCK(vp);
|
||||
if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
|
||||
error = detrunc(dep, (u_long) 0, 0, NOCRED, NULL);
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
dep->de_Name[0] = SLOT_DELETED;
|
||||
}
|
||||
DEUPDAT(dep, &time, 0);
|
||||
DEUNLOCK(dep);
|
||||
DE_UPDAT(dep, &time, 0);
|
||||
VOP_UNLOCK(vp);
|
||||
dep->de_flag = 0;
|
||||
|
||||
/*
|
||||
* If we are done with the denode, then reclaim it so that it can
|
||||
* be reused now.
|
||||
*/
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n", vp->v_usecount,
|
||||
dep->de_Name[0]);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
if (vp->v_usecount == 0 && dep->de_Name[0] == SLOT_DELETED)
|
||||
vgone(vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
delock(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
while (dep->de_flag & DELOCKED) {
|
||||
dep->de_flag |= DEWANT;
|
||||
if (dep->de_lockholder == curproc->p_pid)
|
||||
panic("delock: locking against myself");
|
||||
dep->de_lockwaiter = curproc->p_pid;
|
||||
(void) sleep((caddr_t) dep, PINOD);
|
||||
}
|
||||
dep->de_lockwaiter = 0;
|
||||
dep->de_lockholder = curproc->p_pid;
|
||||
dep->de_flag |= DELOCKED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
deunlock(dep)
|
||||
struct denode *dep;
|
||||
{
|
||||
if ((dep->de_flag & DELOCKED) == 0)
|
||||
vprint("deunlock: found unlocked denode", DETOV(dep));
|
||||
dep->de_lockholder = 0;
|
||||
dep->de_flag &= ~DELOCKED;
|
||||
if (dep->de_flag & DEWANT) {
|
||||
dep->de_flag &= ~DEWANT;
|
||||
wakeup((caddr_t) dep);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: msdosfs_fat.c,v 1.7 1994/07/16 21:33:21 cgd Exp $ */
|
||||
/* $NetBSD: msdosfs_fat.c,v 1.8 1994/07/18 21:38:14 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -53,7 +83,6 @@ int fc_largedistance; /* off by more than LMMAX */
|
|||
/* Byte offset in FAT on filesystem pmp, cluster cn */
|
||||
#define FATOFS(pmp, cn) (FAT12(pmp) ? (cn) * 3 / 2 : (cn) * 2)
|
||||
|
||||
|
||||
static void
|
||||
fatblock(pmp, ofs, bnp, sizep, bop)
|
||||
struct msdosfsmount *pmp;
|
||||
|
@ -261,15 +290,14 @@ fc_purge(dep, frcn)
|
|||
}
|
||||
|
||||
/*
|
||||
* Once the first fat is updated the other copies of the fat must also be
|
||||
* updated. This function does this.
|
||||
* Update all copies of the fat. The first copy is updated last.
|
||||
*
|
||||
* pmp - msdosfsmount structure for filesystem to update
|
||||
* bp - addr of modified fat block
|
||||
* fatbn - block number relative to begin of filesystem of the modified fat block.
|
||||
*/
|
||||
void
|
||||
updateotherfats(pmp, bp, fatbn)
|
||||
updatefats(pmp, bp, fatbn)
|
||||
struct msdosfsmount *pmp;
|
||||
struct buf *bp;
|
||||
u_long fatbn;
|
||||
|
@ -277,10 +305,10 @@ updateotherfats(pmp, bp, fatbn)
|
|||
int i;
|
||||
struct buf *bpn;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("updateotherfats(pmp %08x, bp %08x, fatbn %d)\n",
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("updatefats(pmp %08x, bp %08x, fatbn %d)\n",
|
||||
pmp, bp, fatbn);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now copy the block(s) of the modified fat to the other copies of
|
||||
|
@ -302,6 +330,13 @@ updateotherfats(pmp, bp, fatbn)
|
|||
else
|
||||
bdwrite(bpn);
|
||||
}
|
||||
/*
|
||||
* Write out the first fat last.
|
||||
*/
|
||||
if (pmp->pm_waitonfat)
|
||||
bwrite(bp);
|
||||
else
|
||||
bdwrite(bp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,10 +363,9 @@ usemap_alloc(pmp, cn)
|
|||
struct msdosfsmount *pmp;
|
||||
u_long cn;
|
||||
{
|
||||
pmp->pm_inusemap[cn / 8] |= 1 << (cn % 8);
|
||||
pmp->pm_inusemap[cn / N_INUSEBITS]
|
||||
|= 1 << (cn % N_INUSEBITS);
|
||||
pmp->pm_freeclustercount--;
|
||||
/* This assumes that the lowest available cluster was allocated */
|
||||
pmp->pm_lookhere = cn + 1;
|
||||
}
|
||||
|
||||
extern __inline void
|
||||
|
@ -340,9 +374,7 @@ usemap_free(pmp, cn)
|
|||
u_long cn;
|
||||
{
|
||||
pmp->pm_freeclustercount++;
|
||||
pmp->pm_inusemap[cn / 8] &= ~(1 << (cn % 8));
|
||||
if (pmp->pm_lookhere > cn)
|
||||
pmp->pm_lookhere = cn;
|
||||
pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -432,7 +464,9 @@ fatentry(function, pmp, cn, oldcontents, newcontents)
|
|||
|
||||
byteoffset = FATOFS(pmp, cn);
|
||||
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
|
||||
error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
|
||||
if (error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp))
|
||||
return error;
|
||||
|
||||
if (function & FAT_GET) {
|
||||
readcn = getushort(&bp->b_data[bo]);
|
||||
if (FAT12(pmp)) {
|
||||
|
@ -458,14 +492,7 @@ fatentry(function, pmp, cn, oldcontents, newcontents)
|
|||
putushort(&bp->b_data[bo], readcn);
|
||||
} else
|
||||
putushort(&bp->b_data[bo], newcontents);
|
||||
updateotherfats(pmp, bp, bn);
|
||||
/*
|
||||
* Write out the first fat last.
|
||||
*/
|
||||
if (pmp->pm_waitonfat)
|
||||
bwrite(bp);
|
||||
else
|
||||
bdwrite(bp);
|
||||
updatefats(pmp, bp, bn);
|
||||
bp = NULL;
|
||||
pmp->pm_fmod = 1;
|
||||
}
|
||||
|
@ -475,49 +502,253 @@ fatentry(function, pmp, cn, oldcontents, newcontents)
|
|||
}
|
||||
|
||||
/*
|
||||
* Allocate a free cluster.
|
||||
* Update a contiguous cluster chain
|
||||
*
|
||||
* pmp -
|
||||
* retcluster - put the allocated cluster's number here.
|
||||
* fillwith - put this value into the fat entry for the
|
||||
* allocated cluster.
|
||||
* pmp - mount point
|
||||
* start - first cluster of chain
|
||||
* count - number of clusters in chain
|
||||
* fillwith - what to write into fat entry of last cluster
|
||||
*/
|
||||
int
|
||||
clusteralloc(pmp, retcluster, fillwith)
|
||||
static int
|
||||
fatchain(pmp, start, count, fillwith)
|
||||
struct msdosfsmount *pmp;
|
||||
u_long *retcluster;
|
||||
u_long start;
|
||||
u_long count;
|
||||
u_long fillwith;
|
||||
{
|
||||
int error;
|
||||
u_long cn;
|
||||
u_long idx, max_idx, bit, map;
|
||||
|
||||
max_idx = pmp->pm_maxcluster / 8;
|
||||
for (idx = pmp->pm_lookhere / 8; idx <= max_idx; idx++) {
|
||||
map = pmp->pm_inusemap[idx];
|
||||
if (map != 0xff) {
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
if ((map & (1 << bit)) == 0) {
|
||||
cn = idx * 8 + bit;
|
||||
goto found_one;
|
||||
u_long bn, bo, bsize, byteoffset, readcn, newc;
|
||||
struct buf *bp;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("fatchain(pmp %08x, start %d, count %d, fillwith %d)\n",
|
||||
pmp, start, count, fillwith);
|
||||
#endif
|
||||
/*
|
||||
* Be sure the clusters are in the filesystem.
|
||||
*/
|
||||
if (start < CLUST_FIRST || start + count - 1 > pmp->pm_maxcluster)
|
||||
return EINVAL;
|
||||
|
||||
while (count > 0) {
|
||||
byteoffset = FATOFS(pmp, start);
|
||||
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
|
||||
if (error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp))
|
||||
return error;
|
||||
while (count > 0) {
|
||||
start++;
|
||||
newc = --count > 0 ? start : fillwith;
|
||||
if (FAT12(pmp)) {
|
||||
readcn = getushort(&bp->b_data[bo]);
|
||||
if (start & 1) {
|
||||
readcn &= 0xf000;
|
||||
readcn |= newc & 0xfff;
|
||||
} else {
|
||||
readcn &= 0x000f;
|
||||
readcn |= newc << 4;
|
||||
}
|
||||
putushort(&bp->b_data[bo], readcn);
|
||||
bo++;
|
||||
if (!(start & 1))
|
||||
bo++;
|
||||
} else {
|
||||
putushort(&bp->b_data[bo], newc);
|
||||
bo += 2;
|
||||
}
|
||||
if (bo >= bsize)
|
||||
break;
|
||||
}
|
||||
updatefats(pmp, bp, bn);
|
||||
}
|
||||
return ENOSPC;
|
||||
pmp->pm_fmod = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
found_one:;
|
||||
error = fatentry(FAT_SET, pmp, cn, 0, fillwith);
|
||||
if (error == 0) {
|
||||
usemap_alloc(pmp, cn);
|
||||
*retcluster = cn;
|
||||
/*
|
||||
* Check the length of a free cluster chain starting at start.
|
||||
*
|
||||
* pmp - mount point
|
||||
* start - start of chain
|
||||
* count - maximum interesting length
|
||||
*/
|
||||
int
|
||||
chainlength(pmp, start, count)
|
||||
struct msdosfsmount *pmp;
|
||||
u_long start;
|
||||
u_long count;
|
||||
{
|
||||
u_long idx, max_idx;
|
||||
u_int map;
|
||||
u_long len;
|
||||
|
||||
max_idx = (pmp->pm_maxcluster - 1) / N_INUSEBITS;
|
||||
idx = start / N_INUSEBITS;
|
||||
start %= N_INUSEBITS;
|
||||
map = pmp->pm_inusemap[idx];
|
||||
map &= ~((1 << start) - 1);
|
||||
if (map) {
|
||||
len = ffs(map) - 1 - start;
|
||||
return len > count ? count : len;
|
||||
}
|
||||
len = N_INUSEBITS - start;
|
||||
if (len >= count)
|
||||
return count;
|
||||
while (++idx <= max_idx) {
|
||||
if (len >= count)
|
||||
break;
|
||||
if (map = pmp->pm_inusemap[idx]) {
|
||||
len += ffs(map) - 1;
|
||||
break;
|
||||
}
|
||||
len += N_INUSEBITS;
|
||||
}
|
||||
return len > count ? count : len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate contigous free clusters.
|
||||
*
|
||||
* pmp - mount point.
|
||||
* start - start of cluster chain.
|
||||
* count - number of clusters to allocate.
|
||||
* fillwith - put this value into the fat entry for the
|
||||
* last allocated cluster.
|
||||
* retcluster - put the first allocated cluster's number here.
|
||||
* got - how many clusters were actually allocated.
|
||||
*/
|
||||
int
|
||||
chainalloc(pmp, start, count, fillwith, retcluster, got)
|
||||
struct msdosfsmount *pmp;
|
||||
u_long start;
|
||||
u_long count;
|
||||
u_long fillwith;
|
||||
u_long *retcluster;
|
||||
u_long *got;
|
||||
{
|
||||
int error;
|
||||
|
||||
error = fatchain(pmp, start, count, fillwith);
|
||||
if (error == 0) {
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("clusteralloc(): allocated cluster chain at %d (%d clusters)\n",
|
||||
start, count);
|
||||
#endif
|
||||
if (retcluster)
|
||||
*retcluster = start;
|
||||
if (got)
|
||||
*got = count;
|
||||
while (count-- > 0)
|
||||
usemap_alloc(pmp, start++);
|
||||
}
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("clusteralloc(): allocated cluster %d\n", cn);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate contiguous free clusters.
|
||||
*
|
||||
* pmp - mount point.
|
||||
* start - preferred start of cluster chain.
|
||||
* count - number of clusters requested.
|
||||
* fillwith - put this value into the fat entry for the
|
||||
* last allocated cluster.
|
||||
* retcluster - put the first allocated cluster's number here.
|
||||
* got - how many clusters were actually allocated.
|
||||
*/
|
||||
int
|
||||
clusteralloc(pmp, start, count, fillwith, retcluster, got)
|
||||
struct msdosfsmount *pmp;
|
||||
u_long start;
|
||||
u_long count;
|
||||
u_long fillwith;
|
||||
u_long *retcluster;
|
||||
u_long *got;
|
||||
{
|
||||
int error;
|
||||
u_long idx, max_idx;
|
||||
u_long len, newst, foundcn, foundl, cn, l;
|
||||
u_int map;
|
||||
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("clusteralloc(): find %d clusters\n",count);
|
||||
#endif
|
||||
if (start) {
|
||||
if ((len = chainlength(pmp, start, count)) >= count)
|
||||
return chainalloc(pmp, start, count, fillwith, retcluster, got);
|
||||
} else {
|
||||
/*
|
||||
* This is a new file, initialize start
|
||||
*/
|
||||
struct timeval tv;
|
||||
|
||||
microtime(&tv);
|
||||
start = (tv.tv_usec >> 10)|tv.tv_usec;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start at a (pseudo) random place to maximize cluster runs
|
||||
* under multiple writers.
|
||||
*/
|
||||
foundcn = newst = (start * 1103515245 + 12345) % (pmp->pm_maxcluster - 1);
|
||||
foundl = 0;
|
||||
|
||||
max_idx = (pmp->pm_maxcluster - 1) / N_INUSEBITS;
|
||||
idx = newst / N_INUSEBITS;
|
||||
map = pmp->pm_inusemap[idx];
|
||||
map |= (1 << (newst % N_INUSEBITS)) - 1;
|
||||
while (1) {
|
||||
if (map != (u_int)-1) {
|
||||
cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
|
||||
if ((l = chainlength(pmp, cn, count)) >= count)
|
||||
return chainalloc(pmp, cn, count, fillwith, retcluster, got);
|
||||
if (l > foundl) {
|
||||
foundcn = cn;
|
||||
foundl = l;
|
||||
}
|
||||
cn += l + 1;
|
||||
if (cn > pmp->pm_maxcluster)
|
||||
break;
|
||||
idx = cn / N_INUSEBITS;
|
||||
map = pmp->pm_inusemap[idx];
|
||||
map |= (1 << (cn % N_INUSEBITS)) - 1;
|
||||
continue;
|
||||
}
|
||||
if (++idx > max_idx)
|
||||
break;
|
||||
map = pmp->pm_inusemap[idx];
|
||||
}
|
||||
for (idx = 0;;) {
|
||||
map = pmp->pm_inusemap[idx];
|
||||
if (map != (u_int)-1) {
|
||||
cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
|
||||
if ((l = chainlength(pmp, cn, count)) >= count)
|
||||
return chainalloc(pmp, cn, count, fillwith, retcluster, got);
|
||||
if (l > foundl) {
|
||||
foundcn = cn;
|
||||
foundl = l;
|
||||
}
|
||||
cn += l + 1;
|
||||
if (cn >= newst)
|
||||
break;
|
||||
idx = cn / N_INUSEBITS;
|
||||
map = pmp->pm_inusemap[idx];
|
||||
map |= (1 << (cn % N_INUSEBITS)) - 1;
|
||||
continue;
|
||||
}
|
||||
if (++idx * N_INUSEBITS >= newst)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!foundl)
|
||||
return ENOSPC;
|
||||
|
||||
if (len)
|
||||
return chainalloc(pmp, start, len, fillwith, retcluster, got);
|
||||
else
|
||||
return chainalloc(pmp, foundcn, foundl, fillwith, retcluster, got);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free a chain of clusters.
|
||||
*
|
||||
|
@ -527,22 +758,48 @@ found_one:;
|
|||
* freed.
|
||||
*/
|
||||
int
|
||||
freeclusterchain(pmp, startcluster)
|
||||
freeclusterchain(pmp, cluster)
|
||||
struct msdosfsmount *pmp;
|
||||
u_long startcluster;
|
||||
u_long cluster;
|
||||
{
|
||||
u_long nextcluster;
|
||||
int error = 0;
|
||||
|
||||
while (startcluster >= CLUST_FIRST && startcluster <= pmp->pm_maxcluster) {
|
||||
error = clusterfree(pmp, startcluster, &nextcluster);
|
||||
if (error) {
|
||||
printf("freeclusterchain(): free failed, cluster %d\n",
|
||||
startcluster);
|
||||
break;
|
||||
struct buf *bp = NULL;
|
||||
u_long bn, bo, bsize, byteoffset;
|
||||
u_long readcn, lbn = -1;
|
||||
|
||||
while (cluster >= CLUST_FIRST && cluster <= pmp->pm_maxcluster) {
|
||||
byteoffset = FATOFS(pmp, cluster);
|
||||
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
|
||||
if (lbn != bn) {
|
||||
if (bp)
|
||||
updatefats(pmp, bp, bn);
|
||||
if (error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp))
|
||||
return error;
|
||||
lbn = bn;
|
||||
}
|
||||
usemap_free(pmp, cluster);
|
||||
readcn = getushort(&bp->b_data[bo]);
|
||||
if (FAT12(pmp)) {
|
||||
if (cluster & 1) {
|
||||
cluster = readcn >> 4;
|
||||
readcn &= 0x000f;
|
||||
readcn |= MSDOSFSFREE << 4;
|
||||
} else {
|
||||
cluster = readcn;
|
||||
readcn &= 0xf000;
|
||||
readcn |= MSDOSFSFREE & 0xfff;
|
||||
}
|
||||
putushort(&bp->b_data[bo], readcn);
|
||||
cluster &= 0x0fff;
|
||||
if ((cluster&0x0ff0) == 0x0ff0)
|
||||
cluster |= 0xf000;
|
||||
} else {
|
||||
cluster = readcn;
|
||||
putushort(&bp->b_data[bo], MSDOSFSFREE);
|
||||
}
|
||||
startcluster = nextcluster;
|
||||
}
|
||||
if (bp)
|
||||
updatefats(pmp, bp, bn);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -564,8 +821,8 @@ fillinusemap(pmp)
|
|||
* Mark all clusters in use, we mark the free ones in the fat scan
|
||||
* loop further down.
|
||||
*/
|
||||
for (cn = 0; cn < (pmp->pm_maxcluster >> 3) + 1; cn++)
|
||||
pmp->pm_inusemap[cn] = 0xff;
|
||||
for (cn = 0; cn < (pmp->pm_maxcluster + N_INUSEBITS - 1) / N_INUSEBITS; cn++)
|
||||
pmp->pm_inusemap[cn] = (u_int)-1;
|
||||
|
||||
/*
|
||||
* Figure how many free clusters are in the filesystem by ripping
|
||||
|
@ -573,7 +830,6 @@ fillinusemap(pmp)
|
|||
* zero. These represent free clusters.
|
||||
*/
|
||||
pmp->pm_freeclustercount = 0;
|
||||
pmp->pm_lookhere = pmp->pm_maxcluster + 1;
|
||||
for (cn = CLUST_FIRST; cn <= pmp->pm_maxcluster; cn++) {
|
||||
byteoffset = FATOFS(pmp, cn);
|
||||
bo = byteoffset % pmp->pm_fatblocksize;
|
||||
|
@ -603,27 +859,32 @@ fillinusemap(pmp)
|
|||
/*
|
||||
* Allocate a new cluster and chain it onto the end of the file.
|
||||
*
|
||||
* dep - the file to extend
|
||||
* bpp - where to return the address of the buf header for the new
|
||||
* file block
|
||||
* ncp - where to put cluster number of the newly allocated file block
|
||||
* If this pointer is 0, do not return the cluster number.
|
||||
*
|
||||
* NOTE: This function is not responsible for turning on the DEUPD bit of the
|
||||
* dep - the file to extend
|
||||
* count - number of clusters to allocate
|
||||
* bpp - where to return the address of the buf header for the first new
|
||||
* file block
|
||||
* ncp - where to put cluster number of the first newly allocated cluster
|
||||
* If this pointer is 0, do not return the cluster number.
|
||||
* flags - see fat.h
|
||||
*
|
||||
* NOTE: This function is not responsible for turning on the DE_UPD bit of the
|
||||
* de_flag field of the denode and it does not change the de_FileSize
|
||||
* field. This is left for the caller to do.
|
||||
*/
|
||||
int
|
||||
extendfile(dep, bpp, ncp)
|
||||
extendfile(dep, count, bpp, ncp, flags)
|
||||
struct denode *dep;
|
||||
u_long count;
|
||||
struct buf **bpp;
|
||||
u_int *ncp;
|
||||
u_long *ncp;
|
||||
int flags;
|
||||
{
|
||||
int error = 0;
|
||||
u_long frcn;
|
||||
u_long cn;
|
||||
u_long cn, got;
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
|
||||
struct buf *bp;
|
||||
|
||||
/*
|
||||
* Don't try to extend the root directory
|
||||
*/
|
||||
|
@ -646,52 +907,83 @@ extendfile(dep, bpp, ncp)
|
|||
return error;
|
||||
error = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate another cluster and chain onto the end of the file. If
|
||||
* the file is empty we make de_StartCluster point to the new
|
||||
* block. Note that de_StartCluster being 0 is sufficient to be
|
||||
* sure the file is empty since we exclude attempts to extend the
|
||||
* root directory above, and the root dir is the only file with a
|
||||
* startcluster of 0 that has blocks allocated (sort of).
|
||||
*/
|
||||
if (error = clusteralloc(pmp, &cn, CLUST_EOFE))
|
||||
return error;
|
||||
if (dep->de_StartCluster == 0) {
|
||||
dep->de_StartCluster = cn;
|
||||
frcn = 0;
|
||||
} else {
|
||||
error = fatentry(FAT_SET, pmp, dep->de_fc[FC_LASTFC].fc_fsrcn,
|
||||
0, cn);
|
||||
if (error) {
|
||||
clusterfree(pmp, cn, NULL);
|
||||
|
||||
while (count > 0) {
|
||||
/*
|
||||
* Allocate a new cluster chain and cat onto the end of the file.
|
||||
* If the file is empty we make de_StartCluster point to the new
|
||||
* block. Note that de_StartCluster being 0 is sufficient to be
|
||||
* sure the file is empty since we exclude attempts to extend the
|
||||
* root directory above, and the root dir is the only file with a
|
||||
* startcluster of 0 that has blocks allocated (sort of).
|
||||
*/
|
||||
if (dep->de_StartCluster == 0)
|
||||
cn = 0;
|
||||
else
|
||||
cn = dep->de_fc[FC_LASTFC].fc_fsrcn + 1;
|
||||
if (error = clusteralloc(pmp, cn, count, CLUST_EOFE, &cn, &got))
|
||||
return error;
|
||||
|
||||
count -= got;
|
||||
|
||||
/*
|
||||
* Give them the filesystem relative cluster number if they want
|
||||
* it.
|
||||
*/
|
||||
if (ncp) {
|
||||
*ncp = cn;
|
||||
ncp = NULL;
|
||||
}
|
||||
|
||||
if (dep->de_StartCluster == 0) {
|
||||
dep->de_StartCluster = cn;
|
||||
frcn = 0;
|
||||
} else {
|
||||
error = fatentry(FAT_SET, pmp, dep->de_fc[FC_LASTFC].fc_fsrcn,
|
||||
0, cn);
|
||||
if (error) {
|
||||
clusterfree(pmp, cn, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
frcn = dep->de_fc[FC_LASTFC].fc_frcn + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the "last cluster of the file" entry in the denode's fat
|
||||
* cache.
|
||||
*/
|
||||
fc_setcache(dep, FC_LASTFC, frcn + got - 1, cn + got - 1);
|
||||
|
||||
if (flags & DE_CLEAR) {
|
||||
while (got-- > 0) {
|
||||
/*
|
||||
* Get the buf header for the new block of the file.
|
||||
*/
|
||||
if (dep->de_Attributes & ATTR_DIRECTORY)
|
||||
bp = getblk(pmp->pm_devvp, cntobn(pmp, cn++),
|
||||
pmp->pm_bpcluster, 0, 0);
|
||||
else {
|
||||
bp = getblk(DETOV(dep), frcn++, pmp->pm_bpcluster, 0, 0);
|
||||
/*
|
||||
* Do the bmap now, as in msdosfs_write
|
||||
*/
|
||||
if (pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0))
|
||||
bp->b_blkno = -1;
|
||||
if (bp->b_blkno == -1)
|
||||
panic("extendfile: pcbmap");
|
||||
}
|
||||
clrbuf(bp);
|
||||
if (bpp) {
|
||||
*bpp = bp;
|
||||
bpp = NULL;
|
||||
} else {
|
||||
bp->b_flags |= B_AGE;
|
||||
bawrite(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frcn = dep->de_fc[FC_LASTFC].fc_frcn + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the "last cluster of the file" entry in the denode's fat
|
||||
* cache.
|
||||
*/
|
||||
fc_setcache(dep, FC_LASTFC, frcn, cn);
|
||||
|
||||
/*
|
||||
* Get the buf header for the new block of the file.
|
||||
*/
|
||||
if (dep->de_Attributes & ATTR_DIRECTORY)
|
||||
*bpp = getblk(pmp->pm_devvp, cntobn(pmp, cn),
|
||||
pmp->pm_bpcluster, 0, 0);
|
||||
else
|
||||
*bpp = getblk(DETOV(dep), frcn, pmp->pm_bpcluster, 0, 0);
|
||||
clrbuf(*bpp);
|
||||
|
||||
/*
|
||||
* Give them the filesystem relative cluster number if they want
|
||||
* it.
|
||||
*/
|
||||
if (ncp)
|
||||
*ncp = cn;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: msdosfs_lookup.c,v 1.11 1994/07/16 21:33:23 cgd Exp $ */
|
||||
/* $NetBSD: msdosfs_lookup.c,v 1.12 1994/07/18 21:38:16 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -80,18 +110,18 @@ msdosfs_lookup(ap)
|
|||
int flags = cnp->cn_flags;
|
||||
int nameiop = cnp->cn_nameiop;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
dp = VTODE(vdp);
|
||||
pmp = dp->de_pmp;
|
||||
*vpp = NULL;
|
||||
lockparent = flags & LOCKPARENT;
|
||||
wantparent = flags & (LOCKPARENT | WANTPARENT);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): vdp %08x, dp %08x, Attr %02x\n",
|
||||
vdp, dp, dp->de_Attributes);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Be sure vdp is a directory. Since dos filesystems don't have
|
||||
|
@ -130,9 +160,10 @@ msdosfs_lookup(ap)
|
|||
|
||||
if (!error) {
|
||||
if (vpid == vdp->v_id) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("msdosfs_lookup(): cache hit, vnode %08x, file %s\n", vdp, dp->de_Name);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): cache hit, vnode %08x, file %s\n",
|
||||
vdp, dp->de_Name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
vput(vdp);
|
||||
|
@ -156,9 +187,9 @@ msdosfs_lookup(ap)
|
|||
(cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) {
|
||||
isadir = ATTR_DIRECTORY;
|
||||
scn = MSDOSFSROOT;
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): looking for . or .. in root directory\n");
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
cluster = MSDOSFSROOT;
|
||||
diroff = MSDOSFSROOT_OFS;
|
||||
goto foundroot;
|
||||
|
@ -176,10 +207,10 @@ msdosfs_lookup(ap)
|
|||
|
||||
unix2dosfn((u_char *) cnp->cn_nameptr, dosfilename, cnp->cn_namelen);
|
||||
dosfilename[11] = 0;
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): dos version of filename %s, length %d\n",
|
||||
dosfilename, cnp->cn_namelen);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
/*
|
||||
* Search the directory pointed at by vdp for the name pointed at
|
||||
* by cnp->cn_nameptr.
|
||||
|
@ -234,9 +265,10 @@ msdosfs_lookup(ap)
|
|||
*/
|
||||
if ((dep->deAttributes & ATTR_VOLUME) == 0 &&
|
||||
bcmp(dosfilename, dep->deName, 11) == 0) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("msdosfs_lookup(): match diroff %d, rootreloff %d\n", diroff, rootreloff);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): match diroff %d, rootreloff %d\n",
|
||||
diroff, rootreloff);
|
||||
#endif
|
||||
/*
|
||||
* Remember where this directory
|
||||
* entry came from for whoever did
|
||||
|
@ -271,25 +303,25 @@ notfound:;
|
|||
* that's ok if we are creating or renaming and are at the end of
|
||||
* the pathname and the directory hasn't been removed.
|
||||
*/
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): op %d, refcnt %d, slotstatus %d\n",
|
||||
nameiop, dp->de_refcnt, slotstatus);
|
||||
printf(" slotoffset %d, slotcluster %d\n",
|
||||
slotoffset, slotcluster);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
if ((nameiop == CREATE || nameiop == RENAME) &&
|
||||
(flags & ISLASTCN) && dp->de_refcnt != 0) {
|
||||
if (slotstatus == NONE) {
|
||||
dp->de_fndoffset = (u_long)-1;
|
||||
dp->de_fndclust = (u_long)-1;
|
||||
} else {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_lookup(): saving empty slot location\n");
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
dp->de_fndoffset = slotoffset;
|
||||
dp->de_fndclust = slotcluster;
|
||||
}
|
||||
/* dp->de_flag |= DEUPD; /* never update dos directories */
|
||||
/* dp->de_flag |= DE_UPD; /* never update dos directories */
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
if (!lockparent)/* leave searched dir locked? */
|
||||
VOP_UNLOCK(vdp);
|
||||
|
@ -432,9 +464,9 @@ createde(dep, ddep, depp)
|
|||
struct msdosfsmount *pmp = ddep->de_pmp;
|
||||
struct buf *bp;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("createde(dep %08x, ddep %08x, depp %08x)\n", dep, ddep, depp);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If no space left in the directory then allocate another cluster
|
||||
|
@ -445,7 +477,7 @@ createde(dep, ddep, depp)
|
|||
* case.
|
||||
*/
|
||||
if (ddep->de_fndclust == (u_long)-1) {
|
||||
if (error = extendfile(ddep, &bp, &dirclust))
|
||||
if (error = extendfile(ddep, 1, &bp, &dirclust, DE_CLEAR))
|
||||
return error;
|
||||
ndep = (struct direntry *) bp->b_data;
|
||||
/*
|
||||
|
@ -482,7 +514,7 @@ createde(dep, ddep, depp)
|
|||
return error;
|
||||
}
|
||||
if (error = bwrite(bp)) {
|
||||
deput(*depp); /* free the vnode we got on error */
|
||||
vput(DETOV(*depp)); /* free the vnode we got on error */
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
|
@ -524,15 +556,11 @@ removede(pdep,dep)
|
|||
struct msdosfsmount *pmp = pdep->de_pmp;
|
||||
int error;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
/*
|
||||
* printf("removede(): filename %s\n", dep->de_Name);
|
||||
* printf("removede(): dep %08x, ndpcluster %d, ndpoffset %d\n",
|
||||
* dep,
|
||||
* pdep->de_fndclust,
|
||||
* pdep->de_fndoffset);
|
||||
*/
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("removede(): filename %s\n", dep->de_Name);
|
||||
printf("removede(): dep %08x, ndpcluster %d, ndpoffset %d\n",
|
||||
dep, pdep->de_fndclust, pdep->de_fndoffset);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read the directory block containing the directory entry we are
|
||||
|
@ -596,10 +624,10 @@ dosdirempty(dep)
|
|||
if (bcmp(dentp->deName, ". ", 11) &&
|
||||
bcmp(dentp->deName, ".. ", 11)) {
|
||||
brelse(bp);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("dosdirempty(): entry %d found %02x, %02x\n", dei, dentp->deName[0],
|
||||
dentp->deName[1]);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("dosdirempty(): entry %d found %02x, %02x\n",
|
||||
dei, dentp->deName[0], dentp->deName[1]);
|
||||
#endif
|
||||
return 0; /* not empty */
|
||||
}
|
||||
}
|
||||
|
@ -673,7 +701,7 @@ doscheckpath(source, target)
|
|||
}
|
||||
if (scn == MSDOSFSROOT)
|
||||
break;
|
||||
deput(dep);
|
||||
vput(DETOV(dep));
|
||||
/* NOTE: deget() clears dep on error */
|
||||
error = deget(pmp, scn, 0, ep, &dep);
|
||||
brelse(bp);
|
||||
|
@ -687,7 +715,7 @@ out: ;
|
|||
if (error == ENOTDIR)
|
||||
printf("doscheckpath(): .. not a directory?\n");
|
||||
if (dep != NULL)
|
||||
deput(dep);
|
||||
vput(DETOV(dep));
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: msdosfs_vfsops.c,v 1.16 1994/07/16 21:33:24 cgd Exp $ */
|
||||
/* $NetBSD: msdosfs_vfsops.c,v 1.17 1994/07/18 21:38:18 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -195,9 +225,9 @@ msdosfs_mount(mp, path, data, ndp, p)
|
|||
pmp->pm_uid = args.uid;
|
||||
pmp->pm_mask = args.mask;
|
||||
(void) msdosfs_statfs(mp, &mp->mnt_stat, p);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_mount(): mp %x, pmp %x, inusemap %x\n", mp, pmp, pmp->pm_inusemap);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -239,14 +269,14 @@ mountmsdosfs(devvp, mp, p)
|
|||
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD | FWRITE, FSCRED, p))
|
||||
return error;
|
||||
needclose = 1;
|
||||
#if defined(HDSUPPORT)
|
||||
#ifdef HDSUPPORT
|
||||
/*
|
||||
* Put this in when we support reading dos filesystems from
|
||||
* partitioned harddisks.
|
||||
*/
|
||||
if (VOP_IOCTL(devvp, DIOCGPART, &msdosfspart, FREAD, NOCRED, p) == 0) {
|
||||
}
|
||||
#endif /* defined(HDSUPPORT) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read the boot sector of the filesystem, and then check the boot
|
||||
|
@ -375,8 +405,10 @@ mountmsdosfs(devvp, mp, p)
|
|||
* Allocate memory for the bitmap of allocated clusters, and then
|
||||
* fill it in.
|
||||
*/
|
||||
pmp->pm_inusemap = malloc((pmp->pm_maxcluster >> 3) + 1,
|
||||
M_MSDOSFSFAT, M_WAITOK);
|
||||
pmp->pm_inusemap = malloc(((pmp->pm_maxcluster + N_INUSEBITS - 1)
|
||||
/ N_INUSEBITS)
|
||||
* sizeof(*pmp->pm_inusemap),
|
||||
M_MSDOSFSFAT, M_WAITOK);
|
||||
|
||||
/*
|
||||
* fillinusemap() needs pm_devvp.
|
||||
|
@ -409,7 +441,7 @@ mountmsdosfs(devvp, mp, p)
|
|||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_MSDOS);
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
#if defined(QUOTA)
|
||||
#ifdef QUOTA
|
||||
/*
|
||||
* If we ever do quotas for DOS filesystems this would be a place
|
||||
* to fill in the info in the msdosfsmount structure. You dolt,
|
||||
|
@ -417,7 +449,7 @@ mountmsdosfs(devvp, mp, p)
|
|||
* owners on dos filesystems. of course there is some empty space
|
||||
* in the directory entry where we could put uid's and gid's.
|
||||
*/
|
||||
#endif /* defined(QUOTA) */
|
||||
#endif
|
||||
devvp->v_specflags |= SI_MOUNTEDON;
|
||||
|
||||
return 0;
|
||||
|
@ -470,12 +502,12 @@ msdosfs_unmount(mp, mntflags, p)
|
|||
return EINVAL;
|
||||
flags |= FORCECLOSE;
|
||||
}
|
||||
#if defined(QUOTA)
|
||||
#endif /* defined(QUOTA) */
|
||||
#ifdef QUOTA
|
||||
#endif
|
||||
if (error = vflush(mp, NULLVP, flags))
|
||||
return error;
|
||||
pmp->pm_devvp->v_specflags &= ~SI_MOUNTEDON;
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_umount(): just before calling VOP_CLOSE()\n");
|
||||
printf("flag %08x, usecount %d, writecount %d, holdcnt %d\n",
|
||||
vp->v_flag, vp->v_usecount, vp->v_writecount, vp->v_holdcnt);
|
||||
|
@ -487,7 +519,7 @@ msdosfs_unmount(mp, mntflags, p)
|
|||
vp->v_cleanblkhd, vp->v_dirtyblkhd, vp->v_numoutput, vp->v_type);
|
||||
printf("union %08x, tag %d, data[0] %08x, data[1] %08x\n",
|
||||
vp->v_socket, vp->v_tag, vp->v_data[0], vp->v_data[1]);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
error = VOP_CLOSE(pmp->pm_devvp, pmp->pm_ronly ? FREAD : FREAD | FWRITE,
|
||||
NOCRED, p);
|
||||
vrele(pmp->pm_devvp);
|
||||
|
@ -508,10 +540,10 @@ msdosfs_root(mp, vpp)
|
|||
int error;
|
||||
|
||||
error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, NULL, &ndep);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_root(); mp %08x, pmp %08x, ndep %08x, vp %08x\n",
|
||||
mp, pmp, ndep, DETOV(ndep));
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
if (error == 0)
|
||||
*vpp = DETOV(ndep);
|
||||
return error;
|
||||
|
@ -525,10 +557,10 @@ msdosfs_quotactl(mp, cmds, uid, arg, p)
|
|||
caddr_t arg;
|
||||
struct proc *p;
|
||||
{
|
||||
#if defined(QUOTA)
|
||||
#ifdef QUOTA
|
||||
#else
|
||||
return EOPNOTSUPP;
|
||||
#endif /* defined(QUOTA) */
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -608,7 +640,7 @@ loop:
|
|||
if (VOP_ISLOCKED(vp)) /* file is busy */
|
||||
continue;
|
||||
dep = VTODE(vp);
|
||||
if ((dep->de_flag & DEUPD) == 0 &&
|
||||
if ((dep->de_flag & DE_UPD) == 0 &&
|
||||
vp->v_dirtyblkhd.lh_first == NULL)
|
||||
continue;
|
||||
if (vget(vp, 1)) /* not there anymore? */
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: msdosfs_vnops.c,v 1.15 1994/07/16 21:33:27 cgd Exp $ */
|
||||
/* $NetBSD: msdosfs_vnops.c,v 1.16 1994/07/18 21:38:20 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -76,9 +106,9 @@ msdosfs_create(ap)
|
|||
struct timespec ts;
|
||||
int error;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_create(cnp %08x, vap %08x\n", cnp, ap->a_vap);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a directory entry for the file, then call createde() to
|
||||
|
@ -86,7 +116,7 @@ msdosfs_create(ap)
|
|||
* use the absence of the owner write bit to make the file
|
||||
* readonly.
|
||||
*/
|
||||
#ifdef DIAGNOSITC
|
||||
#ifdef DIAGNOSTIC
|
||||
if ((cnp->cn_flags & SAVENAME) == 0)
|
||||
panic("msdosfs_create: no name");
|
||||
#endif
|
||||
|
@ -106,7 +136,7 @@ msdosfs_create(ap)
|
|||
} else {
|
||||
free(cnp->cn_pnbuf, M_NAMEI);
|
||||
}
|
||||
deput(pdep); /* release parent dir */
|
||||
vput(ap->a_dvp); /* release parent dir */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -134,7 +164,7 @@ msdosfs_mknod(ap)
|
|||
default:
|
||||
error = EINVAL;
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
deput(pdep);
|
||||
vput(ap->a_dvp);
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
|
@ -165,13 +195,71 @@ msdosfs_close(ap)
|
|||
struct denode *dep = VTODE(vp);
|
||||
struct timespec ts;
|
||||
|
||||
if (vp->v_usecount > 1 && !(dep->de_flag & DELOCKED)) {
|
||||
if (vp->v_usecount > 1 && !(dep->de_flag & DE_LOCKED)) {
|
||||
TIMEVAL_TO_TIMESPEC(&time, &ts);
|
||||
DETIMES(dep, &ts);
|
||||
DE_TIMES(dep, &ts);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will go into sys/kern/vfs_subr.c one day!
|
||||
*
|
||||
* Do the usual access checking.
|
||||
* file_node, uid and gid are from the vnode in question,
|
||||
* while acc_mode and cred are from the VOP_ACCESS parameter list.
|
||||
*/
|
||||
static
|
||||
vaccess(file_mode, uid, gid, acc_mode, cred)
|
||||
mode_t file_mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t acc_mode;
|
||||
struct ucred *cred;
|
||||
{
|
||||
mode_t mask;
|
||||
int i;
|
||||
register gid_t *gp;
|
||||
|
||||
/* User id 0 always gets access. */
|
||||
if (cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
|
||||
/* Otherwise, check the owner. */
|
||||
if (cred->cr_uid == uid) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXUSR;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRUSR;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWUSR;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check the groups. */
|
||||
for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
|
||||
if (gid == *gp) {
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXGRP;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IRGRP;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWGRP;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
/* Otherwise, check everyone else. */
|
||||
if (acc_mode & VEXEC)
|
||||
mask |= S_IXOTH;
|
||||
if (acc_mode & VREAD)
|
||||
mask |= S_IROTH;
|
||||
if (acc_mode & VWRITE)
|
||||
mask |= S_IWOTH;
|
||||
return (file_mode & mask) == mask ? 0 : EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
msdosfs_access(ap)
|
||||
struct vop_access_args /* {
|
||||
|
@ -181,28 +269,15 @@ msdosfs_access(ap)
|
|||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
int dosmode;
|
||||
mode_t dosmode;
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
|
||||
/*
|
||||
* Root gets to do anything. Even execute a file without the x-bit
|
||||
* on? But, for dos filesystems every file is executable. I may
|
||||
* regret this.
|
||||
*/
|
||||
if (ap->a_cred->cr_uid == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* mode is filled with a combination of VREAD, VWRITE, and/or VEXEC
|
||||
* bits turned on. In an octal number these are the Y in 0Y00.
|
||||
*
|
||||
* Since the dos filesystem doesn't have the concept of file ownership
|
||||
* we just give everybody read and execute access and write access
|
||||
* if the readonly bit is off.
|
||||
*/
|
||||
dosmode = VEXEC | VREAD |
|
||||
((dep->de_Attributes & ATTR_READONLY) ? 0 : VWRITE);
|
||||
return ((dosmode & ap->a_mode) != 0) ? 0 : EACCES;
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
|
||||
dosmode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
|
||||
dosmode &= pmp->pm_mask;
|
||||
|
||||
return vaccess(dosmode, pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -220,7 +295,7 @@ msdosfs_getattr(ap)
|
|||
struct timespec ts;
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&time, &ts);
|
||||
DETIMES(dep, &ts);
|
||||
DE_TIMES(dep, &ts);
|
||||
vap->va_fsid = dep->de_dev;
|
||||
/*
|
||||
* The following computation of the fileid must be the same as that
|
||||
|
@ -236,7 +311,8 @@ msdosfs_getattr(ap)
|
|||
cn = (cn << 16) | (dep->de_diroffset & 0xffff);
|
||||
}
|
||||
vap->va_fileid = cn;
|
||||
vap->va_mode = (dep->de_Attributes & ATTR_READONLY) ? 0555 : 0777;
|
||||
vap->va_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
|
||||
((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
|
||||
vap->va_mode &= dep->de_pmp->pm_mask;
|
||||
if (dep->de_Attributes & ATTR_DIRECTORY)
|
||||
vap->va_mode |= S_IFDIR;
|
||||
|
@ -275,10 +351,10 @@ msdosfs_setattr(ap)
|
|||
struct vattr *vap = ap->a_vap;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n",
|
||||
ap->a_vp, vap, cred, ap->a_p);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
if ((vap->va_type != VNON) ||
|
||||
(vap->va_nlink != VNOVAL) ||
|
||||
(vap->va_fsid != VNOVAL) ||
|
||||
|
@ -288,17 +364,16 @@ msdosfs_setattr(ap)
|
|||
(vap->va_bytes != VNOVAL) ||
|
||||
(vap->va_gen != VNOVAL) ||
|
||||
(vap->va_uid != VNOVAL) ||
|
||||
(vap->va_gid != VNOVAL) ||
|
||||
(vap->va_atime.ts_sec != VNOVAL)) {
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
(vap->va_gid != VNOVAL)) {
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_setattr(): returning EINVAL\n");
|
||||
printf(" va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n",
|
||||
vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
|
||||
printf(" va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n",
|
||||
vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
|
||||
printf(" va_uid %x, va_gid %x, va_atime.ts_sec %x\n",
|
||||
vap->va_uid, vap->va_gid, vap->va_atime.ts_sec);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
printf(" va_uid %x, va_gid %x\n",
|
||||
vap->va_uid, vap->va_gid);
|
||||
#endif
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
@ -309,7 +384,7 @@ msdosfs_setattr(ap)
|
|||
return error;
|
||||
}
|
||||
if (vap->va_mtime.ts_sec != VNOVAL) {
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
if (error = deupdat(dep, &vap->va_mtime, 1))
|
||||
return error;
|
||||
}
|
||||
|
@ -325,7 +400,7 @@ msdosfs_setattr(ap)
|
|||
dep->de_Attributes &= ~ATTR_READONLY;
|
||||
else
|
||||
dep->de_Attributes |= ATTR_READONLY;
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
}
|
||||
|
||||
if (vap->va_flags != VNOVAL) {
|
||||
|
@ -337,7 +412,7 @@ msdosfs_setattr(ap)
|
|||
dep->de_flag &= 0xffff0000;
|
||||
dep->de_flag |= (vap->va_flags & 0xffff);
|
||||
}
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
@ -448,10 +523,8 @@ msdosfs_write(ap)
|
|||
int resid;
|
||||
int osize;
|
||||
int error;
|
||||
u_long cluster;
|
||||
u_long nextcluster;
|
||||
u_long lastcluster;
|
||||
daddr_t bn;
|
||||
u_long count;
|
||||
daddr_t bn, lastcn;
|
||||
struct buf *bp;
|
||||
int ioflag = ap->a_ioflag;
|
||||
struct uio *uio = ap->a_uio;
|
||||
|
@ -462,12 +535,12 @@ msdosfs_write(ap)
|
|||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_write(vp %08x, uio %08x, ioflag %08x, cred %08x\n",
|
||||
vp, uio, ioflag, cred);
|
||||
printf("msdosfs_write(): diroff %d, dirclust %d, startcluster %d\n",
|
||||
dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
switch (vp->v_type) {
|
||||
case VREG:
|
||||
|
@ -532,31 +605,65 @@ msdosfs_write(ap)
|
|||
resid = uio->uio_resid;
|
||||
osize = dep->de_FileSize;
|
||||
|
||||
|
||||
/*
|
||||
* If we write beyond the end of the file, extend it to its ultimate
|
||||
* size ahead of the time to hopefully get a contiguous area.
|
||||
*/
|
||||
if (uio->uio_offset + resid > osize) {
|
||||
count = de_clcount(pmp, uio->uio_offset + resid) - de_clcount(pmp, osize);
|
||||
if ((error = extendfile(dep, count, NULL, NULL, 0))
|
||||
&& (error != ENOSPC || (ioflag & IO_UNIT)))
|
||||
goto errexit;
|
||||
lastcn = dep->de_fc[FC_LASTFC].fc_frcn;
|
||||
} else
|
||||
lastcn = de_clcount(pmp, osize) - 1;
|
||||
|
||||
do {
|
||||
bn = uio->uio_offset >> pmp->pm_cnshift;
|
||||
/*
|
||||
* If we are appending to the file and we are on a cluster
|
||||
* boundary, then allocate a new cluster and chain it onto
|
||||
* the file.
|
||||
*/
|
||||
if (uio->uio_offset == dep->de_FileSize &&
|
||||
(uio->uio_offset & pmp->pm_crbomask) == 0) {
|
||||
if (error = extendfile(dep, &bp, 0))
|
||||
bn = de_blk(pmp, uio->uio_offset);
|
||||
if (isadir) {
|
||||
if (error = pcbmap(dep, bn, &bn, 0))
|
||||
break;
|
||||
} else if (bn > lastcn) {
|
||||
error = ENOSPC;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((uio->uio_offset & pmp->pm_crbomask) == 0
|
||||
&& (de_blk(pmp, uio->uio_offset + uio->uio_resid) > de_blk(pmp, uio->uio_offset)
|
||||
|| uio->uio_offset + uio->uio_resid >= dep->de_FileSize)) {
|
||||
/*
|
||||
* If either the whole cluster gets written,
|
||||
* or we write the cluster from its start beyond EOF,
|
||||
* then no need to read data from disk.
|
||||
*/
|
||||
bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0);
|
||||
clrbuf(bp);
|
||||
/*
|
||||
* Do the bmap now, since pcbmap needs buffers
|
||||
* for the fat table. (see msdosfs_strategy)
|
||||
*/
|
||||
if (!isadir) {
|
||||
if (bp->b_blkno == bp->b_lblkno) {
|
||||
if (error = pcbmap(dep, bp->b_lblkno,
|
||||
&bp->b_blkno, 0))
|
||||
bp->b_blkno = -1;
|
||||
}
|
||||
if (bp->b_blkno == -1) {
|
||||
brelse(bp);
|
||||
if (!error)
|
||||
error = EIO; /* XXX */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The block we need to write into exists, so just
|
||||
* read it in.
|
||||
* The block we need to write into exists, so read it in.
|
||||
*/
|
||||
if (isadir) {
|
||||
error = pcbmap(dep, bn, &bn, 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
error = bread(thisvp, bn, pmp->pm_bpcluster, cred, &bp);
|
||||
if (error)
|
||||
return error;
|
||||
if (error = bread(thisvp, bn, pmp->pm_bpcluster, cred, &bp))
|
||||
break;
|
||||
}
|
||||
|
||||
croffset = uio->uio_offset & pmp->pm_crbomask;
|
||||
n = min(uio->uio_resid, pmp->pm_bpcluster - croffset);
|
||||
if (uio->uio_offset + n > dep->de_FileSize) {
|
||||
|
@ -588,20 +695,28 @@ msdosfs_write(ap)
|
|||
bawrite(bp);
|
||||
} else
|
||||
bdwrite(bp);
|
||||
dep->de_flag |= DEUPD;
|
||||
dep->de_flag |= DE_UPD;
|
||||
} while (error == 0 && uio->uio_resid > 0);
|
||||
|
||||
/*
|
||||
* If the write failed and they want us to, truncate the file back
|
||||
* to the size it was before the write was attempted.
|
||||
*/
|
||||
if (error && (ioflag & IO_UNIT)) {
|
||||
detrunc(dep, osize, ioflag & IO_SYNC, NOCRED, NULL);
|
||||
uio->uio_offset -= resid - uio->uio_resid;
|
||||
uio->uio_resid = resid;
|
||||
errexit:
|
||||
if (error) {
|
||||
if (ioflag & IO_UNIT) {
|
||||
detrunc(dep, osize, ioflag & IO_SYNC, NOCRED, NULL);
|
||||
uio->uio_offset -= resid - uio->uio_resid;
|
||||
uio->uio_resid = resid;
|
||||
} else {
|
||||
detrunc(dep, dep->de_FileSize, ioflag & IO_SYNC, NOCRED, NULL);
|
||||
if (uio->uio_resid != resid)
|
||||
error = 0;
|
||||
}
|
||||
} else {
|
||||
if (ioflag & IO_UNIT)
|
||||
error = deupdat(dep, &time, 1);
|
||||
}
|
||||
if (!error && (ioflag & IO_UNIT))
|
||||
error = deupdat(dep, &time, 1);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -700,15 +815,15 @@ msdosfs_remove(ap)
|
|||
struct denode *ddep = VTODE(ap->a_dvp);
|
||||
|
||||
error = removede(ddep,dep);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_remove(), dep %08x, v_usecount %d\n", dep, ap->a_vp->v_usecount);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
if (ddep == dep)
|
||||
vrele(DETOV(dep));
|
||||
vrele(ap->a_vp);
|
||||
else
|
||||
deput(dep); /* causes msdosfs_inactive() to be called
|
||||
vput(ap->a_vp); /* causes msdosfs_inactive() to be called
|
||||
* via vrele() */
|
||||
deput(ddep);
|
||||
vput(ap->a_dvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -876,10 +991,10 @@ msdosfs_rename(ap)
|
|||
newparent = 1;
|
||||
if (sourceisadirectory && newparent) {
|
||||
if (tdep) {
|
||||
deput(tdep);
|
||||
vput(ap->a_tvp);
|
||||
tdep = NULL;
|
||||
}
|
||||
/* doscheckpath() deput()'s tddep */
|
||||
/* doscheckpath() vput()'s tddep */
|
||||
error = doscheckpath(fdep, tddep);
|
||||
tddep = NULL;
|
||||
if (error) {
|
||||
|
@ -920,7 +1035,7 @@ msdosfs_rename(ap)
|
|||
if (error = removede(tddep,tdep)) {
|
||||
goto bad;
|
||||
}
|
||||
deput(tdep);
|
||||
vput(ap->a_tvp);
|
||||
tdep = NULL;
|
||||
|
||||
/*
|
||||
|
@ -937,17 +1052,17 @@ msdosfs_rename(ap)
|
|||
*/
|
||||
if (newparent == 0) {
|
||||
/* tddep and fddep point to the same denode here */
|
||||
DELOCK(fdep); /* fddep is already locked */
|
||||
VOP_LOCK(ap->a_fvp); /* ap->a_fdvp is already locked */
|
||||
if (error = readep(fddep->de_pmp,
|
||||
fddep->de_fndclust,
|
||||
fddep->de_fndoffset,
|
||||
&bp, &ep)) {
|
||||
DEUNLOCK(fdep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, ep->deName, 11);
|
||||
if (error = bwrite(bp)) {
|
||||
DEUNLOCK(fdep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
goto bad;
|
||||
}
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
|
@ -969,7 +1084,7 @@ msdosfs_rename(ap)
|
|||
* will also insure that the directory entry on disk has a
|
||||
* filesize of zero.
|
||||
*/
|
||||
DELOCK(fdep);
|
||||
VOP_LOCK(ap->a_fvp);
|
||||
bcopy(toname, fdep->de_Name, 11); /* update denode */
|
||||
if (fdep->de_Attributes & ATTR_DIRECTORY) {
|
||||
dirsize = fdep->de_FileSize;
|
||||
|
@ -981,28 +1096,28 @@ msdosfs_rename(ap)
|
|||
}
|
||||
if (error) {
|
||||
/* should put back filename */
|
||||
DEUNLOCK(fdep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
goto bad;
|
||||
}
|
||||
DELOCK(fddep);
|
||||
VOP_LOCK(ap->a_fdvp);
|
||||
if (error = readep(fddep->de_pmp,
|
||||
fddep->de_fndclust,
|
||||
fddep->de_fndoffset,
|
||||
&bp, &ep)) {
|
||||
DEUNLOCK(fdep);
|
||||
DEUNLOCK(fddep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
VOP_UNLOCK(ap->a_fdvp);
|
||||
goto bad;
|
||||
}
|
||||
ep->deName[0] = SLOT_DELETED;
|
||||
if (error = bwrite(bp)) {
|
||||
DEUNLOCK(fdep);
|
||||
DEUNLOCK(fddep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
VOP_UNLOCK(ap->a_fdvp);
|
||||
goto bad;
|
||||
}
|
||||
fdep->de_dirclust = tddep->de_fndclust;
|
||||
fdep->de_diroffset = tddep->de_fndoffset;
|
||||
reinsert(fdep);
|
||||
DEUNLOCK(fddep);
|
||||
VOP_UNLOCK(ap->a_fdvp);
|
||||
}
|
||||
/* fdep is still locked here */
|
||||
|
||||
|
@ -1022,20 +1137,19 @@ msdosfs_rename(ap)
|
|||
NOCRED, &bp);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
DEUNLOCK(fdep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
goto bad;
|
||||
}
|
||||
dotdotp = (struct direntry *) bp->b_data + 1;
|
||||
putushort(dotdotp->deStartCluster, tddep->de_StartCluster);
|
||||
error = bwrite(bp);
|
||||
DEUNLOCK(fdep);
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
if (error) {
|
||||
/* should really panic here, fs is corrupt */
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
DEUNLOCK(fdep);
|
||||
}
|
||||
} else
|
||||
VOP_UNLOCK(ap->a_fvp);
|
||||
bad: ;
|
||||
vrele(DETOV(fdep));
|
||||
vrele(DETOV(fddep));
|
||||
|
@ -1079,7 +1193,6 @@ msdosfs_mkdir(ap)
|
|||
u_long newcluster;
|
||||
struct denode *pdep;
|
||||
struct denode *ndep;
|
||||
struct vnode *pvp;
|
||||
struct direntry *denp;
|
||||
struct denode ndirent;
|
||||
struct msdosfsmount *pmp;
|
||||
|
@ -1087,8 +1200,7 @@ msdosfs_mkdir(ap)
|
|||
struct timespec ts;
|
||||
u_short dDate, dTime;
|
||||
|
||||
pvp = ap->a_dvp;
|
||||
pdep = VTODE(pvp);
|
||||
pdep = VTODE(ap->a_dvp);
|
||||
|
||||
/*
|
||||
* If this is the root directory and there is no space left we
|
||||
|
@ -1097,7 +1209,7 @@ msdosfs_mkdir(ap)
|
|||
*/
|
||||
if (pdep->de_StartCluster == MSDOSFSROOT && pdep->de_fndclust == (u_long)-1) {
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
deput(pdep);
|
||||
vput(ap->a_dvp);
|
||||
return ENOSPC;
|
||||
}
|
||||
|
||||
|
@ -1106,9 +1218,9 @@ msdosfs_mkdir(ap)
|
|||
/*
|
||||
* Allocate a cluster to hold the about to be created directory.
|
||||
*/
|
||||
if (error = clusteralloc(pmp, &newcluster, CLUST_EOFE)) {
|
||||
if (error = clusteralloc(pmp, 0, 1, CLUST_EOFE, &newcluster, NULL)) {
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
deput(pdep);
|
||||
vput(ap->a_dvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1135,7 +1247,7 @@ msdosfs_mkdir(ap)
|
|||
if (error = bwrite(bp)) {
|
||||
clusterfree(pmp, newcluster, NULL);
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
deput(pdep);
|
||||
vput(ap->a_dvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1160,10 +1272,10 @@ msdosfs_mkdir(ap)
|
|||
*ap->a_vpp = DETOV(ndep);
|
||||
}
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
printf("msdosfs_mkdir(): deput(%08x), vnode %08x\n", pdep, DETOV(pdep));
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
deput(pdep);
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_mkdir(): vput(%08x)\n", ap->a_dvp);
|
||||
#endif
|
||||
vput(ap->a_dvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1186,8 +1298,8 @@ msdosfs_rmdir(ap)
|
|||
* Don't let "rmdir ." go thru.
|
||||
*/
|
||||
if (ddep == dep) {
|
||||
vrele(DETOV(dep));
|
||||
deput(dep);
|
||||
vrele(ap->a_vp);
|
||||
vput(ap->a_vp);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1203,7 +1315,7 @@ msdosfs_rmdir(ap)
|
|||
* Delete the entry from the directory. For dos filesystems this
|
||||
* gets rid of the directory entry on disk, the in memory copy
|
||||
* still exists but the de_refcnt is <= 0. This prevents it from
|
||||
* being found by deget(). When the deput() on dep is done we give
|
||||
* being found by deget(). When the vput() on dep is done we give
|
||||
* up access and eventually msdosfs_reclaim() will be called which
|
||||
* will remove it from the denode cache.
|
||||
*/
|
||||
|
@ -1216,7 +1328,7 @@ msdosfs_rmdir(ap)
|
|||
* the name cache and let go of the parent directory denode.
|
||||
*/
|
||||
cache_purge(DETOV(ddep));
|
||||
deput(ddep);
|
||||
vput(ap->a_dvp);
|
||||
ap->a_dvp = NULL;
|
||||
|
||||
/*
|
||||
|
@ -1227,8 +1339,8 @@ msdosfs_rmdir(ap)
|
|||
|
||||
out: ;
|
||||
if (ap->a_dvp)
|
||||
deput(ddep);
|
||||
deput(dep);
|
||||
vput(ap->a_dvp);
|
||||
vput(ap->a_vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1248,7 +1360,7 @@ msdosfs_symlink(ap)
|
|||
struct denode *pdep = VTODE(ap->a_dvp);
|
||||
|
||||
free(ap->a_cnp->cn_pnbuf, M_NAMEI);
|
||||
deput(pdep);
|
||||
vput(ap->a_dvp);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1311,10 +1423,10 @@ msdosfs_readdir(ap)
|
|||
int i = 0;
|
||||
struct uio *uio = ap->a_uio;
|
||||
|
||||
#if defined(MSDOSFSDEBUG)
|
||||
#ifdef MSDOSFS_DEBUG
|
||||
printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n",
|
||||
ap->a_vp, uio, ap->a_cred, ap->a_eofflag);
|
||||
#endif /* defined(MSDOSFSDEBUG) */
|
||||
#endif
|
||||
|
||||
if (!ap->a_cookies)
|
||||
ap->a_ncookies = 1;
|
||||
|
@ -1565,7 +1677,16 @@ msdosfs_lock(ap)
|
|||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
|
||||
DELOCK(dep);
|
||||
while (dep->de_flag & DE_LOCKED) {
|
||||
dep->de_flag |= DE_WANT;
|
||||
if (dep->de_lockholder == curproc->p_pid)
|
||||
panic("msdosfs_lock: locking against myself");
|
||||
dep->de_lockwaiter = curproc->p_pid;
|
||||
(void) sleep((caddr_t) dep, PINOD);
|
||||
}
|
||||
dep->de_lockwaiter = 0;
|
||||
dep->de_lockholder = curproc->p_pid;
|
||||
dep->de_flag |= DE_LOCKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1577,9 +1698,14 @@ msdosfs_unlock(ap)
|
|||
{
|
||||
struct denode *dep = VTODE(ap->a_vp);
|
||||
|
||||
if (!(dep->de_flag & DELOCKED))
|
||||
if (!(dep->de_flag & DE_LOCKED))
|
||||
panic("msdosfs_unlock: denode not locked");
|
||||
DEUNLOCK(dep);
|
||||
dep->de_lockholder = 0;
|
||||
dep->de_flag &= ~DE_LOCKED;
|
||||
if (dep->de_flag & DE_WANT) {
|
||||
dep->de_flag &= ~DE_WANT;
|
||||
wakeup((caddr_t) dep);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1589,7 +1715,7 @@ msdosfs_islocked(ap)
|
|||
struct vnode *a_vp;
|
||||
} */ *ap;
|
||||
{
|
||||
return VTODE(ap->a_vp)->de_flag & DELOCKED ? 1 : 0;
|
||||
return VTODE(ap->a_vp)->de_flag & DE_LOCKED ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1646,7 +1772,7 @@ msdosfs_strategy(ap)
|
|||
struct denode *dep = VTODE(bp->b_vp);
|
||||
struct msdosfsmount *pmp = dep->de_pmp;
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
|
||||
panic("msdosfs_strategy: spec");
|
||||
|
@ -1658,16 +1784,16 @@ msdosfs_strategy(ap)
|
|||
*/
|
||||
if (bp->b_blkno == bp->b_lblkno) {
|
||||
if (error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0))
|
||||
return error;
|
||||
if ((long) bp->b_blkno == -1)
|
||||
bp->b_blkno = -1;
|
||||
if (bp->b_blkno == -1)
|
||||
clrbuf(bp);
|
||||
}
|
||||
if ((long) bp->b_blkno == -1) {
|
||||
if (bp->b_blkno == -1) {
|
||||
biodone(bp);
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
#ifdef DIAGNOSTIC
|
||||
#endif /* defined(DIAGNOSTIC) */
|
||||
#endif
|
||||
/*
|
||||
* Read/write the block from/to the disk that contains the desired
|
||||
* file block.
|
||||
|
@ -1690,7 +1816,7 @@ msdosfs_print(ap)
|
|||
dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
|
||||
printf(" dev %d, %d, %s\n",
|
||||
major(dep->de_dev), minor(dep->de_dev),
|
||||
dep->de_flag & DELOCKED ? "(LOCKED)" : "");
|
||||
dep->de_flag & DE_LOCKED ? "(LOCKED)" : "");
|
||||
if (dep->de_lockholder) {
|
||||
printf(" owner pid %d", dep->de_lockholder);
|
||||
if (dep->de_lockwaiter)
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
/* $NetBSD: msdosfsmount.h,v 1.5 1994/07/16 21:33:29 cgd Exp $ */
|
||||
/* $NetBSD: msdosfsmount.h,v 1.6 1994/07/18 21:38:22 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1994 Wolfgang Solfrank.
|
||||
* Copyright (C) 1994 TooLs GmbH.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Written by Paul Popelka (paulp@uts.amdahl.com)
|
||||
*
|
||||
|
@ -35,7 +65,6 @@ struct msdosfsmount {
|
|||
u_long pm_nmbrofclusters; /* # of clusters in filesystem */
|
||||
u_long pm_maxcluster; /* maximum cluster number */
|
||||
u_long pm_freeclustercount; /* number of free clusters */
|
||||
u_long pm_lookhere; /* start free cluster search here */
|
||||
u_long pm_bnshift; /* shift file offset right this amount to get a block number */
|
||||
u_long pm_brbomask; /* and a file offset with this mask to get block rel offset */
|
||||
u_long pm_cnshift; /* shift file offset right this amount to get a cluster number */
|
||||
|
@ -46,12 +75,15 @@ struct msdosfsmount {
|
|||
u_long pm_fatblocksize; /* size of fat blocks in bytes */
|
||||
u_long pm_fatblocksec; /* size of fat blocks in sectors */
|
||||
u_long pm_fatsize; /* size of fat in bytes */
|
||||
u_char *pm_inusemap; /* ptr to bitmap of in-use clusters */
|
||||
u_int *pm_inusemap; /* ptr to bitmap of in-use clusters */
|
||||
char pm_ronly; /* read only if non-zero */
|
||||
char pm_waitonfat; /* wait for writes of the fat to complt, when 0 use bdwrite, else use bwrite */
|
||||
struct netexport pm_export; /* export information */
|
||||
};
|
||||
|
||||
/* Number of bits in one pm_inusemap item: */
|
||||
#define N_INUSEBITS (8 * sizeof(u_int))
|
||||
|
||||
/*
|
||||
* How to compute pm_cnshift and pm_crbomask.
|
||||
*
|
||||
|
@ -122,6 +154,18 @@ struct msdosfsmount {
|
|||
+ (dirofs) % (pmp)->pm_depclust)
|
||||
|
||||
|
||||
/*
|
||||
* Convert filesize to block number
|
||||
*/
|
||||
#define de_blk(pmp, off) \
|
||||
((off) >> (pmp)->pm_cnshift)
|
||||
|
||||
/*
|
||||
* Clusters required to hold size bytes
|
||||
*/
|
||||
#define de_clcount(pmp, size) \
|
||||
(((size) + (pmp)->pm_bpcluster - 1) >> (pmp)->pm_cnshift)
|
||||
|
||||
/*
|
||||
* Prototypes for MSDOSFS virtual filesystem operations
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue