summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-05-25 08:14:14 +0000
committerru <ru@FreeBSD.org>2001-05-25 08:14:14 +0000
commit8094d979ca0adb982d9e0c5482a2825da1b38e11 (patch)
tree09c650cd510113b8d6d68446ef7b4dba2f8e6e81
parent0c045c5d540f08a8fe263cda4d97745b7a4b5a33 (diff)
downloadFreeBSD-src-8094d979ca0adb982d9e0c5482a2825da1b38e11.zip
FreeBSD-src-8094d979ca0adb982d9e0c5482a2825da1b38e11.tar.gz
- sys/msdosfs moved to sys/fs/msdosfs
- msdos.ko renamed to msdosfs.ko - /usr/include/msdosfs moved to /usr/include/fs/msdosfs
-rw-r--r--contrib/amd/include/am_defs.h6
-rw-r--r--etc/mtree/BSD.include.dist4
-rw-r--r--include/Makefile7
-rw-r--r--sbin/mount_msdos/mount_msdos.c2
-rw-r--r--sbin/mount_msdosfs/mount_msdosfs.c2
-rw-r--r--sbin/mountd/mountd.c2
-rw-r--r--share/man/man7/hier.74
-rw-r--r--sys/boot/forth/loader.conf2
-rw-r--r--sys/conf/files12
-rw-r--r--sys/fs/msdosfs/msdosfs_conv.c2
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c10
-rw-r--r--sys/fs/msdosfs/msdosfs_fat.c10
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c10
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c12
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c10
-rw-r--r--sys/kern/Make.tags.inc4
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/msdos/Makefile15
-rw-r--r--sys/modules/msdosfs/Makefile4
-rw-r--r--sys/msdosfs/bootsect.h113
-rw-r--r--sys/msdosfs/bpb.h215
-rw-r--r--sys/msdosfs/denode.h285
-rw-r--r--sys/msdosfs/direntry.h143
-rw-r--r--sys/msdosfs/fat.h108
-rw-r--r--sys/msdosfs/msdosfs_conv.c1041
-rw-r--r--sys/msdosfs/msdosfs_denode.c724
-rw-r--r--sys/msdosfs/msdosfs_fat.c1102
-rw-r--r--sys/msdosfs/msdosfs_lookup.c1100
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c964
-rw-r--r--sys/msdosfs/msdosfs_vnops.c1905
-rw-r--r--sys/msdosfs/msdosfsmount.h245
-rw-r--r--usr.bin/fstat/msdosfs.c10
-rw-r--r--usr.sbin/amd/include/config.h5
-rw-r--r--usr.sbin/mountd/mountd.c2
-rw-r--r--usr.sbin/sade/install.c2
-rw-r--r--usr.sbin/sysinstall/dos.c2
-rw-r--r--usr.sbin/sysinstall/floppy.c2
-rw-r--r--usr.sbin/sysinstall/install.c2
38 files changed, 69 insertions, 8021 deletions
diff --git a/contrib/amd/include/am_defs.h b/contrib/amd/include/am_defs.h
index 36c695e..203dcad 100644
--- a/contrib/amd/include/am_defs.h
+++ b/contrib/amd/include/am_defs.h
@@ -743,7 +743,11 @@ struct sockaddr_dl;
*/
#ifdef HAVE_MSDOSFS_MSDOSFSMOUNT_H
# include <msdosfs/msdosfsmount.h>
-#endif /* HAVE_MSDOSFS_MSDOSFSMOUNT_H */
+#else /* not HAVE_MSDOSFS_MSDOSFSMOUNT_H */
+# ifdef HAVE_FS_MSDOSFS_MSDOSFSMOUNT_H
+# include <fs/msdosfs/msdosfsmount.h>
+# endif /* HAVE_FS_MSDOSFS_MSDOSFSMOUNT_H */
+#endif /* not HAVE_MSDOSFS_MSDOSFSMOUNT_H */
/*
* Actions to take if <sys/fs/tmp.h> exists.
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index 05a2ed1..7028770 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -24,6 +24,8 @@
..
fifofs
..
+ msdosfs
+ ..
nullfs
..
portalfs
@@ -49,8 +51,6 @@
..
machine
..
- msdosfs
- ..
net
..
netatalk
diff --git a/include/Makefile b/include/Makefile
index 4f2b4fb..4b68b53 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -39,15 +39,16 @@ SFILES= soundcard.h joystick.h
LFILES= aio.h errno.h fcntl.h inttypes.h linker_set.h poll.h syslog.h \
termios.h ucontext.h
-LDIRS= cam msdosfs net netatalk netatm netgraph netinet netinet6 \
+LDIRS= cam net netatalk netatm netgraph netinet netinet6 \
netipx netkey netnatm netncp netns netsmb nfs ntfs nwfs pccard posix4 \
sys vm
LNOHEADERDIRS= fs isofs ufs dev
LSUBDIRS= cam/scsi dev/ppbus dev/usb dev/wi \
- fs/fdescfs fs/fifofs fs/nullfs fs/portalfs fs/procfs fs/smbfs \
- fs/umapfs fs/unionfs isofs/cd9660 ufs/ffs ufs/mfs ufs/ufs
+ fs/fdescfs fs/fifofs fs/msdosfs fs/nullfs fs/portalfs \
+ fs/procfs fs/smbfs fs/umapfs fs/unionfs isofs/cd9660 \
+ ufs/ffs ufs/mfs ufs/ufs
# For SHARED=symlinks, cam is a symlink, so cam/scsi is taken care of
LSYMSUBDIRS= ${LSUBDIRS:Ncam/scsi}
diff --git a/sbin/mount_msdos/mount_msdos.c b/sbin/mount_msdos/mount_msdos.c
index 8265826..a758d3d 100644
--- a/sbin/mount_msdos/mount_msdos.c
+++ b/sbin/mount_msdos/mount_msdos.c
@@ -39,7 +39,7 @@ static const char rcsid[] =
#include <sys/mount.h>
#include <sys/stat.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#include <ctype.h>
#include <err.h>
diff --git a/sbin/mount_msdosfs/mount_msdosfs.c b/sbin/mount_msdosfs/mount_msdosfs.c
index 8265826..a758d3d 100644
--- a/sbin/mount_msdosfs/mount_msdosfs.c
+++ b/sbin/mount_msdosfs/mount_msdosfs.c
@@ -39,7 +39,7 @@ static const char rcsid[] =
#include <sys/mount.h>
#include <sys/stat.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#include <ctype.h>
#include <err.h>
diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c
index cab8bc0..2d198e6 100644
--- a/sbin/mountd/mountd.c
+++ b/sbin/mountd/mountd.c
@@ -63,7 +63,7 @@ static const char rcsid[] =
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <ufs/ufs/ufsmount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#include <ntfs/ntfsmount.h>
#include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */
diff --git a/share/man/man7/hier.7 b/share/man/man7/hier.7
index 5d0d627..5197b80 100644
--- a/share/man/man7/hier.7
+++ b/share/man/man7/hier.7
@@ -179,6 +179,8 @@ per-process file descriptors file system
.It Pa fifofs/
.St -p1003.1
FIFOs file system
+.It Pa msdosfs/
+MS-DOS file system
.It Pa nullfs/
loopback file system
.It Pa portalfs/
@@ -211,8 +213,6 @@ see
.Xr kerberos 1
.It Pa machine/
machine-specific C include files
-.It Pa msdosfs/
-MS-DOS file system
.It Pa net/
misc network C include files
.It Pa netatalk/
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index 65a8c10..bedc201 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -89,7 +89,7 @@ cd9660_load="NO" # ISO 9660 filesystem
coda_load="NO" # CODA filesystem
fdescfs_load="NO" # Filedescriptors filesystem
mfs_load="NO" # Memory filesystem
-msdos_load="NO" # FAT-12/16/32
+msdosfs_load="NO" # FAT-12/16/32
nfs_load="NO" # NFS
ntfs_load="NO" # NTFS
nullfs_load="NO" # Null filesystem
diff --git a/sys/conf/files b/sys/conf/files
index 9d11055..ec8ae7b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -598,6 +598,12 @@ fs/hpfs/hpfs_lookup.c optional hpfs
fs/hpfs/hpfs_subr.c optional hpfs
fs/hpfs/hpfs_vfsops.c optional hpfs
fs/hpfs/hpfs_vnops.c optional hpfs
+fs/msdosfs/msdosfs_conv.c optional msdosfs
+fs/msdosfs/msdosfs_denode.c optional msdosfs
+fs/msdosfs/msdosfs_fat.c optional msdosfs
+fs/msdosfs/msdosfs_lookup.c optional msdosfs
+fs/msdosfs/msdosfs_vfsops.c optional msdosfs
+fs/msdosfs/msdosfs_vnops.c optional msdosfs
fs/nullfs/null_subr.c optional nullfs
fs/nullfs/null_vfsops.c optional nullfs
fs/nullfs/null_vnops.c optional nullfs
@@ -833,12 +839,6 @@ libkern/strtol.c standard
libkern/strtoq.c standard
libkern/strtoul.c standard
libkern/strtouq.c standard
-msdosfs/msdosfs_conv.c optional msdosfs
-msdosfs/msdosfs_denode.c optional msdosfs
-msdosfs/msdosfs_fat.c optional msdosfs
-msdosfs/msdosfs_lookup.c optional msdosfs
-msdosfs/msdosfs_vfsops.c optional msdosfs
-msdosfs/msdosfs_vnops.c optional msdosfs
net/bpf.c standard
net/bpf_filter.c optional bpf
bpf.h standard \
diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c
index 8c43f93..1cfe6a4 100644
--- a/sys/fs/msdosfs/msdosfs_conv.c
+++ b/sys/fs/msdosfs/msdosfs_conv.c
@@ -61,7 +61,7 @@
/*
* MSDOSFS include files.
*/
-#include <msdosfs/direntry.h>
+#include <fs/msdosfs/direntry.h>
/*
* Total number of days that have passed for each month in a regular year.
diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
index dbdf554..bf176bd 100644
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -61,11 +61,11 @@
#include <vm/vm.h>
#include <vm/vm_extern.h>
-#include <msdosfs/bpb.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/fat.h>
static MALLOC_DEFINE(M_MSDOSFSNODE, "MSDOSFS node", "MSDOSFS vnode private part");
diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
index 38abc16..828edb70 100644
--- a/sys/fs/msdosfs/msdosfs_fat.c
+++ b/sys/fs/msdosfs/msdosfs_fat.c
@@ -61,11 +61,11 @@
/*
* msdosfs include files.
*/
-#include <msdosfs/bpb.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/fat.h>
/*
* Fat cache stats.
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 776559d..987ac3b 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -56,11 +56,11 @@
#include <sys/vnode.h>
#include <sys/mount.h>
-#include <msdosfs/bpb.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/fat.h>
/*
* When we search a directory the blocks containing directory entries are
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index abaeb7f..962632a 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -63,12 +63,12 @@
#include <sys/stat.h> /* defines ALLPERMS */
#include <sys/mutex.h>
-#include <msdosfs/bpb.h>
-#include <msdosfs/bootsect.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/bootsect.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/fat.h>
#define MSDOSFS_DFLTBSIZE 4096
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index b942d30..29a59ec 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -70,11 +70,11 @@
#include <machine/mutex.h>
-#include <msdosfs/bpb.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/fat.h>
#define DOS_FILESIZE_MAX 0xffffffff
diff --git a/sys/kern/Make.tags.inc b/sys/kern/Make.tags.inc
index 59dd7a7..35ec2ed 100644
--- a/sys/kern/Make.tags.inc
+++ b/sys/kern/Make.tags.inc
@@ -31,6 +31,7 @@ COMM= ${SYS}/conf/*.[ch] \
${SYS}/fs/deadfs/*.[ch] \
${SYS}/fs/fdescfs/*.[ch] \
${SYS}/fs/fifofs/*.[ch] \
+ ${SYS}/fs/msdosfs/*.[ch] \
${SYS}/fs/nullfs/*.[ch] \
${SYS}/fs/portalfs/*.[ch] \
${SYS}/fs/procfs/*.[ch] \
@@ -39,7 +40,6 @@ COMM= ${SYS}/conf/*.[ch] \
${SYS}/fs/unionfs/*.[ch] \
${SYS}/isofs/cd9660/*.[ch] \
${SYS}/kern/*.[ch] \
- ${SYS}/msdosfs/*.[ch] \
${SYS}/net/*.[ch] \
${SYS}/netatalk/*.[ch] \
${SYS}/netatm/*.[ch] \
@@ -59,7 +59,6 @@ COMM= ${SYS}/conf/*.[ch] \
COMMDIR1= ${SYS}/conf \
${SYS}/kern \
- ${SYS}/msdosfs \
${SYS}/net \
${SYS}/netatalk \
${SYS}/netatm \
@@ -95,6 +94,7 @@ COMMDIR2= ${SYS}/dev/advansys \
${SYS}/fs/devfs \
${SYS}/fs/fdescfs \
${SYS}/fs/fifofs \
+ ${SYS}/fs/msdosfs \
${SYS}/fs/nullfs \
${SYS}/fs/portalfs \
${SYS}/fs/procfs \
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 86a0065..d0753a5 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -9,7 +9,7 @@ _random= random
SUBDIR= 3dfx accf_data accf_http agp aha amr an aue \
cam ccd cd9660 coda cue dc de dgm digi ed fdescfs fxp if_disc if_ef \
if_ppp if_sl if_tap if_tun ip6fw ipfilter ipfw ispfw joy kue \
- libmchain linux lnc md mfs mii mlx msdos ncp netgraph nfs nge ntfs \
+ libmchain linux lnc md mfs mii mlx msdosfs ncp netgraph nfs nge ntfs \
nullfs nwfs pcn portalfs procfs ${_random} \
rl rp sf sis sk sn snp sound sppp ste sym syscons sysvipc ti tl twe \
tx udbp ugen uhid ukbd ulpt umapfs umass umodem ums unionfs urio usb \
diff --git a/sys/modules/msdos/Makefile b/sys/modules/msdos/Makefile
deleted file mode 100644
index fb3b2f8..0000000
--- a/sys/modules/msdos/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../msdosfs
-
-KMOD= msdos
-SRCS= vnode_if.h \
- msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c msdosfs_lookup.c \
- msdosfs_vfsops.c msdosfs_vnops.c
-NOMAN=
-
-.if ${MACHINE} == "pc98"
-CFLAGS+= -DPC98
-.endif
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/msdosfs/Makefile b/sys/modules/msdosfs/Makefile
index fb3b2f8..62a9ba9 100644
--- a/sys/modules/msdosfs/Makefile
+++ b/sys/modules/msdosfs/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../msdosfs
+.PATH: ${.CURDIR}/../../fs/msdosfs
-KMOD= msdos
+KMOD= msdosfs
SRCS= vnode_if.h \
msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c msdosfs_lookup.c \
msdosfs_vfsops.c msdosfs_vnops.c
diff --git a/sys/msdosfs/bootsect.h b/sys/msdosfs/bootsect.h
deleted file mode 100644
index c3e3d68..0000000
--- a/sys/msdosfs/bootsect.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: bootsect.h,v 1.9 1997/11/17 15:36:17 ws Exp $ */
-
-/*
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * Format of a boot sector. This is the first sector on a DOS floppy disk
- * or the fist sector of a partition on a hard disk. But, it is not the
- * first sector of a partitioned hard disk.
- */
-struct bootsector33 {
- u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
- int8_t bsOemName[8]; /* OEM name and version */
- int8_t bsBPB[19]; /* BIOS parameter block */
- int8_t bsDriveNumber; /* drive number (0x80) */
- int8_t bsBootCode[479]; /* pad so struct is 512b */
- u_int8_t bsBootSectSig0;
- u_int8_t bsBootSectSig1;
-#define BOOTSIG0 0x55
-#define BOOTSIG1 0xaa
-};
-
-struct extboot {
- int8_t exDriveNumber; /* drive number (0x80) */
- int8_t exReserved1; /* reserved */
- int8_t exBootSignature; /* ext. boot signature (0x29) */
-#define EXBOOTSIG 0x29
- int8_t exVolumeID[4]; /* volume ID number */
- int8_t exVolumeLabel[11]; /* volume label */
- int8_t exFileSysType[8]; /* fs type (FAT12 or FAT16) */
-};
-
-struct bootsector50 {
- u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
- int8_t bsOemName[8]; /* OEM name and version */
- int8_t bsBPB[25]; /* BIOS parameter block */
- int8_t bsExt[26]; /* Bootsector Extension */
- int8_t bsBootCode[448]; /* pad so structure is 512b */
- u_int8_t bsBootSectSig0;
- u_int8_t bsBootSectSig1;
-#define BOOTSIG0 0x55
-#define BOOTSIG1 0xaa
-};
-
-struct bootsector710 {
- u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
- int8_t bsOEMName[8]; /* OEM name and version */
- int8_t bsPBP[53]; /* BIOS parameter block */
- int8_t bsExt[26]; /* Bootsector Extension */
- int8_t bsBootCode[418]; /* pad so structure is 512b */
- u_int8_t bsBootSectSig2; /* 2 & 3 are only defined for FAT32? */
- u_int8_t bsBootSectSig3;
- u_int8_t bsBootSectSig0;
- u_int8_t bsBootSectSig1;
-#define BOOTSIG0 0x55
-#define BOOTSIG1 0xaa
-#define BOOTSIG2 0
-#define BOOTSIG3 0
-};
-#ifdef atari
-/*
- * The boot sector on a gemdos fs is a little bit different from the msdos fs
- * format. Currently there is no need to declare a separate structure, the
- * bootsector33 struct will do.
- */
-#if 0
-struct bootsec_atari {
- u_int8_t bsBranch[2]; /* branch inst if auto-boot */
- int8_t bsFiller[6]; /* anything or nothing */
- int8_t bsSerial[3]; /* serial no. for mediachange */
- int8_t bsBPB[19]; /* BIOS parameter block */
- int8_t bsBootCode[482]; /* pad so struct is 512b */
-};
-#endif
-#endif /* atari */
-
-union bootsector {
- struct bootsector33 bs33;
- struct bootsector50 bs50;
- struct bootsector710 bs710;
-};
-
-#if 0
-/*
- * Shorthand for fields in the bpb.
- */
-#define bsBytesPerSec bsBPB.bpbBytesPerSec
-#define bsSectPerClust bsBPB.bpbSectPerClust
-#define bsResSectors bsBPB.bpbResSectors
-#define bsFATS bsBPB.bpbFATS
-#define bsRootDirEnts bsBPB.bpbRootDirEnts
-#define bsSectors bsBPB.bpbSectors
-#define bsMedia bsBPB.bpbMedia
-#define bsFATsecs bsBPB.bpbFATsecs
-#define bsSectPerTrack bsBPB.bpbSectPerTrack
-#define bsHeads bsBPB.bpbHeads
-#define bsHiddenSecs bsBPB.bpbHiddenSecs
-#define bsHugeSectors bsBPB.bpbHugeSectors
-#endif
diff --git a/sys/msdosfs/bpb.h b/sys/msdosfs/bpb.h
deleted file mode 100644
index 42c941b..0000000
--- a/sys/msdosfs/bpb.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: bpb.h,v 1.7 1997/11/17 15:36:24 ws Exp $ */
-
-/*
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * BIOS Parameter Block (BPB) for DOS 3.3
- */
-struct bpb33 {
- u_int16_t bpbBytesPerSec; /* bytes per sector */
- u_int8_t bpbSecPerClust; /* sectors per cluster */
- u_int16_t bpbResSectors; /* number of reserved sectors */
- u_int8_t bpbFATs; /* number of FATs */
- u_int16_t bpbRootDirEnts; /* number of root directory entries */
- u_int16_t bpbSectors; /* total number of sectors */
- u_int8_t bpbMedia; /* media descriptor */
- u_int16_t bpbFATsecs; /* number of sectors per FAT */
- u_int16_t bpbSecPerTrack; /* sectors per track */
- u_int16_t bpbHeads; /* number of heads */
- u_int16_t bpbHiddenSecs; /* number of hidden sectors */
-};
-
-/*
- * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
- * and bpbHugeSectors is not in the 3.3 bpb.
- */
-struct bpb50 {
- u_int16_t bpbBytesPerSec; /* bytes per sector */
- u_int8_t bpbSecPerClust; /* sectors per cluster */
- u_int16_t bpbResSectors; /* number of reserved sectors */
- u_int8_t bpbFATs; /* number of FATs */
- u_int16_t bpbRootDirEnts; /* number of root directory entries */
- u_int16_t bpbSectors; /* total number of sectors */
- u_int8_t bpbMedia; /* media descriptor */
- u_int16_t bpbFATsecs; /* number of sectors per FAT */
- u_int16_t bpbSecPerTrack; /* sectors per track */
- u_int16_t bpbHeads; /* number of heads */
- u_int32_t bpbHiddenSecs; /* # of hidden sectors */
- u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
-};
-
-/*
- * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
- */
-struct bpb710 {
- u_int16_t bpbBytesPerSec; /* bytes per sector */
- u_int8_t bpbSecPerClust; /* sectors per cluster */
- u_int16_t bpbResSectors; /* number of reserved sectors */
- u_int8_t bpbFATs; /* number of FATs */
- u_int16_t bpbRootDirEnts; /* number of root directory entries */
- u_int16_t bpbSectors; /* total number of sectors */
- u_int8_t bpbMedia; /* media descriptor */
- u_int16_t bpbFATsecs; /* number of sectors per FAT */
- u_int16_t bpbSecPerTrack; /* sectors per track */
- u_int16_t bpbHeads; /* number of heads */
- u_int32_t bpbHiddenSecs; /* # of hidden sectors */
- u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
- u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */
- u_int16_t bpbExtFlags; /* extended flags: */
-#define FATNUM 0xf /* mask for numbering active FAT */
-#define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */
- u_int16_t bpbFSVers; /* filesystem version */
-#define FSVERS 0 /* currently only 0 is understood */
- u_int32_t bpbRootClust; /* start cluster for root directory */
- u_int16_t bpbFSInfo; /* filesystem info structure sector */
- u_int16_t bpbBackup; /* backup boot sector */
- /* There is a 12 byte filler here, but we ignore it */
-};
-
-#ifdef atari
-/*
- * BPB for gemdos filesystems. Atari leaves the obsolete stuff undefined.
- * Currently there is no need for a separate BPB structure.
- */
-#if 0
-struct bpb_a {
- u_int16_t bpbBytesPerSec; /* bytes per sector */
- u_int8_t bpbSecPerClust; /* sectors per cluster */
- u_int16_t bpbResSectors; /* number of reserved sectors */
- u_int8_t bpbFATs; /* number of FATs */
- u_int16_t bpbRootDirEnts; /* number of root directory entries */
- u_int16_t bpbSectors; /* total number of sectors */
- u_int8_t bpbUseless1; /* meaningless on gemdos fs */
- u_int16_t bpbFATsecs; /* number of sectors per FAT */
- u_int16_t bpbUseless2; /* meaningless for harddisk fs */
- u_int16_t bpbUseless3; /* meaningless for harddisk fs */
- u_int16_t bpbHiddenSecs; /* the TOS-BIOS ignores this */
-};
-#endif
-#endif /* atari */
-
-/*
- * The following structures represent how the bpb's look on disk. shorts
- * and longs are just character arrays of the appropriate length. This is
- * because the compiler forces shorts and longs to align on word or
- * halfword boundaries.
- *
- * XXX The little-endian code here assumes that the processor can access
- * 16-bit and 32-bit quantities on byte boundaries. If this is not true,
- * use the macros for the big-endian case.
- */
-
-#include <machine/endian.h>
-
-#ifdef __i386__
-#define UNLALIGNED_ACCESS
-#endif
-
-#if (BYTE_ORDER == LITTLE_ENDIAN) && defined(UNALIGNED_ACCESS)
-#define getushort(x) *((u_int16_t *)(x))
-#define getulong(x) *((u_int32_t *)(x))
-#define putushort(p, v) (*((u_int16_t *)(p)) = (v))
-#define putulong(p, v) (*((u_int32_t *)(p)) = (v))
-#else
-#define getushort(x) (((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8))
-#define getulong(x) (((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8) \
- + (((u_int8_t *)(x))[2] << 16) \
- + (((u_int8_t *)(x))[3] << 24))
-#define putushort(p, v) (((u_int8_t *)(p))[0] = (v), \
- ((u_int8_t *)(p))[1] = (v) >> 8)
-#define putulong(p, v) (((u_int8_t *)(p))[0] = (v), \
- ((u_int8_t *)(p))[1] = (v) >> 8, \
- ((u_int8_t *)(p))[2] = (v) >> 16,\
- ((u_int8_t *)(p))[3] = (v) >> 24)
-#endif
-
-/*
- * BIOS Parameter Block (BPB) for DOS 3.3
- */
-struct byte_bpb33 {
- int8_t bpbBytesPerSec[2]; /* bytes per sector */
- int8_t bpbSecPerClust; /* sectors per cluster */
- int8_t bpbResSectors[2]; /* number of reserved sectors */
- int8_t bpbFATs; /* number of FATs */
- int8_t bpbRootDirEnts[2]; /* number of root directory entries */
- int8_t bpbSectors[2]; /* total number of sectors */
- int8_t bpbMedia; /* media descriptor */
- int8_t bpbFATsecs[2]; /* number of sectors per FAT */
- int8_t bpbSecPerTrack[2]; /* sectors per track */
- int8_t bpbHeads[2]; /* number of heads */
- int8_t bpbHiddenSecs[2]; /* number of hidden sectors */
-};
-
-/*
- * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3,
- * and bpbHugeSectors is not in the 3.3 bpb.
- */
-struct byte_bpb50 {
- int8_t bpbBytesPerSec[2]; /* bytes per sector */
- int8_t bpbSecPerClust; /* sectors per cluster */
- int8_t bpbResSectors[2]; /* number of reserved sectors */
- int8_t bpbFATs; /* number of FATs */
- int8_t bpbRootDirEnts[2]; /* number of root directory entries */
- int8_t bpbSectors[2]; /* total number of sectors */
- int8_t bpbMedia; /* media descriptor */
- int8_t bpbFATsecs[2]; /* number of sectors per FAT */
- int8_t bpbSecPerTrack[2]; /* sectors per track */
- int8_t bpbHeads[2]; /* number of heads */
- int8_t bpbHiddenSecs[4]; /* number of hidden sectors */
- int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
-};
-
-/*
- * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
- */
-struct byte_bpb710 {
- u_int8_t bpbBytesPerSec[2]; /* bytes per sector */
- u_int8_t bpbSecPerClust; /* sectors per cluster */
- u_int8_t bpbResSectors[2]; /* number of reserved sectors */
- u_int8_t bpbFATs; /* number of FATs */
- u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */
- u_int8_t bpbSectors[2]; /* total number of sectors */
- u_int8_t bpbMedia; /* media descriptor */
- u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */
- u_int8_t bpbSecPerTrack[2]; /* sectors per track */
- u_int8_t bpbHeads[2]; /* number of heads */
- u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */
- u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
- u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */
- u_int8_t bpbExtFlags[2]; /* extended flags: */
- u_int8_t bpbFSVers[2]; /* filesystem version */
- u_int8_t bpbRootClust[4]; /* start cluster for root directory */
- u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */
- u_int8_t bpbBackup[2]; /* backup boot sector */
- /* There is a 12 byte filler here, but we ignore it */
-};
-
-/*
- * FAT32 FSInfo block.
- */
-struct fsinfo {
- u_int8_t fsisig1[4];
- u_int8_t fsifill1[480];
- u_int8_t fsisig2[4];
- u_int8_t fsinfree[4];
- u_int8_t fsinxtfree[4];
- u_int8_t fsifill2[12];
- u_int8_t fsisig3[4];
- u_int8_t fsifill3[508];
- u_int8_t fsisig4[4];
-};
diff --git a/sys/msdosfs/denode.h b/sys/msdosfs/denode.h
deleted file mode 100644
index f7ba83b..0000000
--- a/sys/msdosfs/denode.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: denode.h,v 1.25 1997/11/17 15:36:28 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * This is the pc filesystem specific portion of the vnode structure.
- *
- * To describe a file uniquely the de_dirclust, de_diroffset, and
- * de_StartCluster fields are used.
- *
- * de_dirclust contains the cluster number of the directory cluster
- * containing the entry for a file or directory.
- * de_diroffset is the index into the cluster for the entry describing
- * a file or directory.
- * de_StartCluster is the number of the first cluster of the file or directory.
- *
- * Now to describe the quirks of the pc filesystem.
- * - Clusters 0 and 1 are reserved.
- * - The first allocatable cluster is 2.
- * - The root directory is of fixed size and all blocks that make it up
- * are contiguous.
- * - Cluster 0 refers to the root directory when it is found in the
- * startcluster field of a directory entry that points to another directory.
- * - Cluster 0 implies a 0 length file when found in the start cluster field
- * of a directory entry that points to a file.
- * - You can't use the cluster number 0 to derive the address of the root
- * directory.
- * - Multiple directory entries can point to a directory. The entry in the
- * parent directory points to a child directory. Any directories in the
- * child directory contain a ".." entry that points back to the parent.
- * The child directory itself contains a "." entry that points to itself.
- * - The root directory does not contain a "." or ".." entry.
- * - Directory entries for directories are never changed once they are created
- * (except when removed). The size stays 0, and the last modification time
- * is never changed. This is because so many directory entries can point to
- * the physical clusters that make up a directory. It would lead to an
- * update nightmare.
- * - The length field in a directory entry pointing to a directory contains 0
- * (always). The only way to find the end of a directory is to follow the
- * cluster chain until the "last cluster" marker is found.
- *
- * My extensions to make this house of cards work. These apply only to the in
- * memory copy of the directory entry.
- * - A reference count for each denode will be kept since dos doesn't keep such
- * things.
- */
-
-/*
- * Internal pseudo-offset for (nonexistent) directory entry for the root
- * dir in the root dir
- */
-#define MSDOSFSROOT_OFS 0x1fffffff
-
-/*
- * The fat cache structure. fc_fsrcn is the filesystem relative cluster
- * number that corresponds to the file relative cluster number in this
- * structure (fc_frcn).
- */
-struct fatcache {
- u_long fc_frcn; /* file relative cluster number */
- u_long fc_fsrcn; /* filesystem relative cluster number */
-};
-
-/*
- * The fat entry cache as it stands helps make extending files a "quick"
- * operation by avoiding having to scan the fat to discover the last
- * cluster of the file. The cache also helps sequential reads by
- * remembering the last cluster read from the file. This also prevents us
- * from having to rescan the fat to find the next cluster to read. This
- * cache is probably pretty worthless if a file is opened by multiple
- * processes.
- */
-#define FC_SIZE 2 /* number of entries in the cache */
-#define FC_LASTMAP 0 /* entry the last call to pcbmap() resolved
- * to */
-#define FC_LASTFC 1 /* entry for the last cluster in the file */
-
-#define FCE_EMPTY 0xffffffff /* doesn't represent an actual cluster # */
-
-/*
- * Set a slot in the fat cache.
- */
-#define fc_setcache(dep, slot, frcn, fsrcn) \
- (dep)->de_fc[slot].fc_frcn = frcn; \
- (dep)->de_fc[slot].fc_fsrcn = fsrcn;
-
-/*
- * This is the in memory variant of a dos directory entry. It is usually
- * contained within a vnode.
- */
-struct denode {
- struct denode *de_next; /* Hash chain forward */
- struct denode **de_prev; /* Hash chain back */
- struct vnode *de_vnode; /* addr of vnode we are part of */
- struct vnode *de_devvp; /* vnode of blk dev we live on */
- u_long de_flag; /* flag bits */
- dev_t de_dev; /* device where direntry lives */
- u_long de_dirclust; /* cluster of the directory file containing this entry */
- u_long de_diroffset; /* offset of this entry in the directory cluster */
- u_long de_fndoffset; /* offset of found dir entry */
- int de_fndcnt; /* number of slots before de_fndoffset */
- long de_refcnt; /* reference count */
- struct msdosfsmount *de_pmp; /* addr of our mount struct */
- u_char de_Name[12]; /* name, from DOS directory entry */
- u_char de_Attributes; /* attributes, from directory entry */
- u_char de_LowerCase; /* NT VFAT lower case flags */
- u_char de_CHun; /* Hundredth of second of CTime*/
- u_short de_CTime; /* creation time */
- u_short de_CDate; /* creation date */
- u_short de_ADate; /* access date */
- u_short de_MTime; /* modification time */
- u_short de_MDate; /* modification date */
- u_long de_StartCluster; /* starting cluster of file */
- u_long de_FileSize; /* size of file in bytes */
- struct fatcache de_fc[FC_SIZE]; /* fat cache */
- u_quad_t de_modrev; /* Revision level for lease. */
-};
-
-/*
- * Values for the de_flag field of the denode.
- */
-#define DE_UPDATE 0x0004 /* Modification time update request */
-#define DE_CREATE 0x0008 /* Creation time update */
-#define DE_ACCESS 0x0010 /* Access time update */
-#define DE_MODIFIED 0x0020 /* Denode has been modified */
-#define DE_RENAME 0x0040 /* Denode is in the process of being renamed */
-
-
-/*
- * Transfer directory entries between internal and external form.
- * dep is a struct denode * (internal form),
- * dp is a struct direntry * (external form).
- */
-#define DE_INTERNALIZE32(dep, dp) \
- ((dep)->de_StartCluster |= getushort((dp)->deHighClust) << 16)
-#define DE_INTERNALIZE(dep, dp) \
- (bcopy((dp)->deName, (dep)->de_Name, 11), \
- (dep)->de_Attributes = (dp)->deAttributes, \
- (dep)->de_LowerCase = (dp)->deLowerCase, \
- (dep)->de_CHun = (dp)->deCHundredth, \
- (dep)->de_CTime = getushort((dp)->deCTime), \
- (dep)->de_CDate = getushort((dp)->deCDate), \
- (dep)->de_ADate = getushort((dp)->deADate), \
- (dep)->de_MTime = getushort((dp)->deMTime), \
- (dep)->de_MDate = getushort((dp)->deMDate), \
- (dep)->de_StartCluster = getushort((dp)->deStartCluster), \
- (dep)->de_FileSize = getulong((dp)->deFileSize), \
- (FAT32((dep)->de_pmp) ? DE_INTERNALIZE32((dep), (dp)) : 0))
-
-#define DE_EXTERNALIZE(dp, dep) \
- (bcopy((dep)->de_Name, (dp)->deName, 11), \
- (dp)->deAttributes = (dep)->de_Attributes, \
- (dp)->deLowerCase = (dep)->de_LowerCase, \
- (dp)->deCHundredth = (dep)->de_CHun, \
- putushort((dp)->deCTime, (dep)->de_CTime), \
- putushort((dp)->deCDate, (dep)->de_CDate), \
- putushort((dp)->deADate, (dep)->de_ADate), \
- putushort((dp)->deMTime, (dep)->de_MTime), \
- putushort((dp)->deMDate, (dep)->de_MDate), \
- putushort((dp)->deStartCluster, (dep)->de_StartCluster), \
- putulong((dp)->deFileSize, \
- ((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize), \
- putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16))
-
-#define de_forw de_chain[0]
-#define de_back de_chain[1]
-
-#ifdef _KERNEL
-
-#define VTODE(vp) ((struct denode *)(vp)->v_data)
-#define DETOV(de) ((de)->de_vnode)
-
-#define DETIMES(dep, acc, mod, cre) do { \
- if ((dep)->de_flag & DE_UPDATE) { \
- (dep)->de_flag |= DE_MODIFIED; \
- unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime, \
- NULL); \
- (dep)->de_Attributes |= ATTR_ARCHIVE; \
- } \
- if ((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) { \
- (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
- break; \
- } \
- if ((dep)->de_flag & DE_ACCESS) { \
- u_int16_t adate; \
- \
- unix2dostime((acc), &adate, NULL, NULL); \
- if (adate != (dep)->de_ADate) { \
- (dep)->de_flag |= DE_MODIFIED; \
- (dep)->de_ADate = adate; \
- } \
- } \
- if ((dep)->de_flag & DE_CREATE) { \
- unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime, \
- &(dep)->de_CHun); \
- (dep)->de_flag |= DE_MODIFIED; \
- } \
- (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
-} while (0);
-
-/*
- * This overlays the fid structure (see mount.h)
- */
-struct defid {
- u_short defid_len; /* length of structure */
- u_short defid_pad; /* force long alignment */
-
- u_long defid_dirclust; /* cluster this dir entry came from */
- u_long defid_dirofs; /* offset of entry within the cluster */
-#if 0
- u_long defid_gen; /* generation number */
-#endif
-};
-
-extern vop_t **msdosfs_vnodeop_p;
-
-int msdosfs_lookup __P((struct vop_cachedlookup_args *));
-int msdosfs_inactive __P((struct vop_inactive_args *));
-int msdosfs_reclaim __P((struct vop_reclaim_args *));
-
-/*
- * Internal service routine prototypes.
- */
-int deget __P((struct msdosfsmount *, u_long, u_long, struct denode **));
-int uniqdosname __P((struct denode *, struct componentname *, u_char *));
-int findwin95 __P((struct denode *));
-
-int readep __P((struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp));
-int readde __P((struct denode *dep, struct buf **bpp, struct direntry **epp));
-int deextend __P((struct denode *dep, u_long length, struct ucred *cred));
-int fillinusemap __P((struct msdosfsmount *pmp));
-void reinsert __P((struct denode *dep));
-int dosdirempty __P((struct denode *dep));
-int createde __P((struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp));
-int deupdat __P((struct denode *dep, int waitfor));
-int removede __P((struct denode *pdep, struct denode *dep));
-int detrunc __P((struct denode *dep, u_long length, int flags, struct ucred *cred, struct proc *p));
-int doscheckpath __P(( struct denode *source, struct denode *target));
-#endif /* _KERNEL */
diff --git a/sys/msdosfs/direntry.h b/sys/msdosfs/direntry.h
deleted file mode 100644
index fccf58b..0000000
--- a/sys/msdosfs/direntry.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: direntry.h,v 1.14 1997/11/17 15:36:32 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * Structure of a dos directory entry.
- */
-struct direntry {
- u_int8_t deName[8]; /* filename, blank filled */
-#define SLOT_EMPTY 0x00 /* slot has never been used */
-#define SLOT_E5 0x05 /* the real value is 0xe5 */
-#define SLOT_DELETED 0xe5 /* file in this slot deleted */
- u_int8_t deExtension[3]; /* extension, blank filled */
- u_int8_t deAttributes; /* file attributes */
-#define ATTR_NORMAL 0x00 /* normal file */
-#define ATTR_READONLY 0x01 /* file is readonly */
-#define ATTR_HIDDEN 0x02 /* file is hidden */
-#define ATTR_SYSTEM 0x04 /* file is a system file */
-#define ATTR_VOLUME 0x08 /* entry is a volume label */
-#define ATTR_DIRECTORY 0x10 /* entry is a directory name */
-#define ATTR_ARCHIVE 0x20 /* file is new or modified */
- u_int8_t deLowerCase; /* NT VFAT lower case flags */
-#define LCASE_BASE 0x08 /* filename base in lower case */
-#define LCASE_EXT 0x10 /* filename extension in lower case */
- u_int8_t deCHundredth; /* hundredth of seconds in CTime */
- u_int8_t deCTime[2]; /* create time */
- u_int8_t deCDate[2]; /* create date */
- u_int8_t deADate[2]; /* access date */
- u_int8_t deHighClust[2]; /* high bytes of cluster number */
- u_int8_t deMTime[2]; /* last update time */
- u_int8_t deMDate[2]; /* last update date */
- u_int8_t deStartCluster[2]; /* starting cluster of file */
- u_int8_t deFileSize[4]; /* size of file in bytes */
-};
-
-/*
- * Structure of a Win95 long name directory entry
- */
-struct winentry {
- u_int8_t weCnt;
-#define WIN_LAST 0x40
-#define WIN_CNT 0x3f
- u_int8_t wePart1[10];
- u_int8_t weAttributes;
-#define ATTR_WIN95 0x0f
- u_int8_t weReserved1;
- u_int8_t weChksum;
- u_int8_t wePart2[12];
- u_int16_t weReserved2;
- u_int8_t wePart3[4];
-};
-#define WIN_CHARS 13 /* Number of chars per winentry */
-
-/*
- * Maximum filename length in Win95
- * Note: Must be < sizeof(dirent.d_name)
- */
-#define WIN_MAXLEN 255
-
-/*
- * This is the format of the contents of the deTime field in the direntry
- * structure.
- * We don't use bitfields because we don't know how compilers for
- * arbitrary machines will lay them out.
- */
-#define DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
-#define DT_2SECONDS_SHIFT 0
-#define DT_MINUTES_MASK 0x7E0 /* minutes */
-#define DT_MINUTES_SHIFT 5
-#define DT_HOURS_MASK 0xF800 /* hours */
-#define DT_HOURS_SHIFT 11
-
-/*
- * This is the format of the contents of the deDate field in the direntry
- * structure.
- */
-#define DD_DAY_MASK 0x1F /* day of month */
-#define DD_DAY_SHIFT 0
-#define DD_MONTH_MASK 0x1E0 /* month */
-#define DD_MONTH_SHIFT 5
-#define DD_YEAR_MASK 0xFE00 /* year - 1980 */
-#define DD_YEAR_SHIFT 9
-
-#ifdef _KERNEL
-struct dirent;
-void unix2dostime __P((struct timespec *tsp, u_int16_t *ddp,
- u_int16_t *dtp, u_int8_t *dhp));
-void dos2unixtime __P((u_int dd, u_int dt, u_int dh, struct timespec *tsp));
-int dos2unixfn __P((u_char dn[11], u_char *un, int lower, int d2u_loaded, u_int8_t *d2u, int ul_loaded, u_int8_t *ul));
-int unix2dosfn __P((const u_char *un, u_char dn[12], int unlen, u_int gen, int u2d_loaded, u_int8_t *u2d, int lu_loaded, u_int8_t *lu));
-int unix2winfn __P((const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int table_loaded, u_int16_t *u2w));
-int winChkName __P((const u_char *un, int unlen, struct winentry *wep, int chksum, int u2w_loaded, u_int16_t *u2w, int ul_loaded, u_int8_t *ul));
-int win2unixfn __P((struct winentry *wep, struct dirent *dp, int chksum, int table_loaded, u_int16_t *u2w));
-u_int8_t winChksum __P((u_int8_t *name));
-int winSlotCnt __P((const u_char *un, int unlen));
-int winLenFixup __P((const u_char *un, int unlen));
-#endif /* _KERNEL */
diff --git a/sys/msdosfs/fat.h b/sys/msdosfs/fat.h
deleted file mode 100644
index 7dd5bbf..0000000
--- a/sys/msdosfs/fat.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: fat.h,v 1.12 1997/11/17 15:36:36 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * Some useful cluster numbers.
- */
-#define MSDOSFSROOT 0 /* cluster 0 means the root dir */
-#define CLUST_FREE 0 /* cluster 0 also means a free cluster */
-#define MSDOSFSFREE CLUST_FREE
-#define CLUST_FIRST 2 /* first legal cluster number */
-#define CLUST_RSRVD 0xfffffff6 /* reserved cluster range */
-#define CLUST_BAD 0xfffffff7 /* a cluster with a defect */
-#define CLUST_EOFS 0xfffffff8 /* start of eof cluster range */
-#define CLUST_EOFE 0xffffffff /* end of eof cluster range */
-
-#define FAT12_MASK 0x00000fff /* mask for 12 bit cluster numbers */
-#define FAT16_MASK 0x0000ffff /* mask for 16 bit cluster numbers */
-#define FAT32_MASK 0x0fffffff /* mask for FAT32 cluster numbers */
-
-/*
- * MSDOSFS:
- * Return true if filesystem uses 12 bit fats. Microsoft Programmer's
- * Reference says if the maximum cluster number in a filesystem is greater
- * than 4078 ((CLUST_RSRVS - CLUST_FIRST) & FAT12_MASK) then we've got a
- * 16 bit fat filesystem. While mounting, the result of this test is stored
- * in pm_fatentrysize.
- * GEMDOS-flavour (atari):
- * If the filesystem is on floppy we've got a 12 bit fat filesystem, otherwise
- * 16 bit. We check the d_type field in the disklabel struct while mounting
- * and store the result in the pm_fatentrysize. Note that this kind of
- * detection gets flakey when mounting a vnd-device.
- */
-#define FAT12(pmp) (pmp->pm_fatmask == FAT12_MASK)
-#define FAT16(pmp) (pmp->pm_fatmask == FAT16_MASK)
-#define FAT32(pmp) (pmp->pm_fatmask == FAT32_MASK)
-
-#define MSDOSFSEOF(pmp, cn) ((((cn) | ~(pmp)->pm_fatmask) & CLUST_EOFS) == CLUST_EOFS)
-
-#ifdef _KERNEL
-/*
- * These are the values for the function argument to the function
- * fatentry().
- */
-#define FAT_GET 0x0001 /* get a fat entry */
-#define FAT_SET 0x0002 /* set a fat entry */
-#define FAT_GET_AND_SET (FAT_GET | FAT_SET)
-
-/*
- * 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* sp));
-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));
-void fc_purge __P((struct denode *dep, u_int frcn));
-
-#endif /* _KERNEL */
diff --git a/sys/msdosfs/msdosfs_conv.c b/sys/msdosfs/msdosfs_conv.c
deleted file mode 100644
index 8c43f93..0000000
--- a/sys/msdosfs/msdosfs_conv.c
+++ /dev/null
@@ -1,1041 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_conv.c,v 1.25 1997/11/17 15:36:40 ws Exp $ */
-
-/*-
- * Copyright (C) 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * System include files.
- */
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/kernel.h> /* defines tz */
-#include <sys/systm.h>
-#include <machine/clock.h>
-#include <sys/dirent.h>
-
-/*
- * MSDOSFS include files.
- */
-#include <msdosfs/direntry.h>
-
-/*
- * Total number of days that have passed for each month in a regular year.
- */
-static u_short regyear[] = {
- 31, 59, 90, 120, 151, 181,
- 212, 243, 273, 304, 334, 365
-};
-
-/*
- * Total number of days that have passed for each month in a leap year.
- */
-static u_short leapyear[] = {
- 31, 60, 91, 121, 152, 182,
- 213, 244, 274, 305, 335, 366
-};
-
-/*
- * Variables used to remember parts of the last time conversion. Maybe we
- * can avoid a full conversion.
- */
-static u_long lasttime;
-static u_long lastday;
-static u_short lastddate;
-static u_short lastdtime;
-
-static __inline u_int8_t find_lcode __P((u_int16_t code, u_int16_t *u2w));
-
-/*
- * Convert the unix version of time to dos's idea of time to be used in
- * file timestamps. The passed in unix time is assumed to be in GMT.
- */
-void
-unix2dostime(tsp, ddp, dtp, dhp)
- struct timespec *tsp;
- u_int16_t *ddp;
- u_int16_t *dtp;
- u_int8_t *dhp;
-{
- u_long t;
- u_long days;
- u_long inc;
- u_long year;
- u_long month;
- u_short *months;
-
- /*
- * If the time from the last conversion is the same as now, then
- * skip the computations and use the saved result.
- */
- t = tsp->tv_sec - (tz.tz_minuteswest * 60)
- - (wall_cmos_clock ? adjkerntz : 0);
- /* - daylight savings time correction */
- t &= ~1;
- if (lasttime != t) {
- lasttime = t;
- lastdtime = (((t / 2) % 30) << DT_2SECONDS_SHIFT)
- + (((t / 60) % 60) << DT_MINUTES_SHIFT)
- + (((t / 3600) % 24) << DT_HOURS_SHIFT);
-
- /*
- * If the number of days since 1970 is the same as the last
- * time we did the computation then skip all this leap year
- * and month stuff.
- */
- days = t / (24 * 60 * 60);
- if (days != lastday) {
- lastday = days;
- for (year = 1970;; year++) {
- inc = year & 0x03 ? 365 : 366;
- if (days < inc)
- break;
- days -= inc;
- }
- months = year & 0x03 ? regyear : leapyear;
- for (month = 0; days >= months[month]; month++)
- ;
- if (month > 0)
- days -= months[month - 1];
- lastddate = ((days + 1) << DD_DAY_SHIFT)
- + ((month + 1) << DD_MONTH_SHIFT);
- /*
- * Remember dos's idea of time is relative to 1980.
- * unix's is relative to 1970. If somehow we get a
- * time before 1980 then don't give totally crazy
- * results.
- */
- if (year > 1980)
- lastddate += (year - 1980) << DD_YEAR_SHIFT;
- }
- }
- if (dtp)
- *dtp = lastdtime;
- if (dhp)
- *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
-
- *ddp = lastddate;
-}
-
-/*
- * The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
- * interval there were 8 regular years and 2 leap years.
- */
-#define SECONDSTO1980 (((8 * 365) + (2 * 366)) * (24 * 60 * 60))
-
-static u_short lastdosdate;
-static u_long lastseconds;
-
-/*
- * Convert from dos' idea of time to unix'. This will probably only be
- * called from the stat(), and fstat() system calls and so probably need
- * not be too efficient.
- */
-void
-dos2unixtime(dd, dt, dh, tsp)
- u_int dd;
- u_int dt;
- u_int dh;
- struct timespec *tsp;
-{
- u_long seconds;
- u_long month;
- u_long year;
- u_long days;
- u_short *months;
-
- if (dd == 0) {
- /*
- * Uninitialized field, return the epoch.
- */
- tsp->tv_sec = 0;
- tsp->tv_nsec = 0;
- return;
- }
- seconds = (((dt & DT_2SECONDS_MASK) >> DT_2SECONDS_SHIFT) << 1)
- + ((dt & DT_MINUTES_MASK) >> DT_MINUTES_SHIFT) * 60
- + ((dt & DT_HOURS_MASK) >> DT_HOURS_SHIFT) * 3600
- + dh / 100;
- /*
- * If the year, month, and day from the last conversion are the
- * same then use the saved value.
- */
- if (lastdosdate != dd) {
- lastdosdate = dd;
- days = 0;
- year = (dd & DD_YEAR_MASK) >> DD_YEAR_SHIFT;
- days = year * 365;
- days += year / 4 + 1; /* add in leap days */
- if ((year & 0x03) == 0)
- days--; /* if year is a leap year */
- months = year & 0x03 ? regyear : leapyear;
- month = (dd & DD_MONTH_MASK) >> DD_MONTH_SHIFT;
- if (month < 1 || month > 12) {
- printf("dos2unixtime(): month value out of range (%ld)\n",
- month);
- month = 1;
- }
- if (month > 1)
- days += months[month - 2];
- days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1;
- lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980;
- }
- tsp->tv_sec = seconds + lastseconds + (tz.tz_minuteswest * 60)
- + adjkerntz;
- /* + daylight savings time correction */
- tsp->tv_nsec = (dh % 100) * 10000000;
-}
-
-/*
- * 0 - character disallowed in long file name.
- * 1 - character should be replaced by '_' in DOS file name,
- * and generation number inserted.
- * 2 - character ('.' and ' ') should be skipped in DOS file name,
- * and generation number inserted.
- */
-static u_char
-unix2dos[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, /* 00-07 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 08-0f */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 18-1f */
- 2, 0x21, 0, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
- 0x28, 0x29, 0, 1, 1, 0x2d, 2, 0, /* 28-2f */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
- 0x38, 0x39, 0, 1, 0, 1, 0, 0, /* 38-3f */
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 48-4f */
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 50-57 */
- 0x58, 0x59, 0x5a, 1, 0, 1, 0x5e, 0x5f, /* 58-5f */
- 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 60-67 */
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 68-6f */
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 70-77 */
- 0x58, 0x59, 0x5a, 0x7b, 0, 0x7d, 0x7e, 0, /* 78-7f */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 80-87 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 88-8f */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 90-97 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 98-9f */
- 0, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* a0-a7 */
- 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* a8-af */
- 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* b0-b7 */
- 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* b8-bf */
- 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* c0-c7 */
- 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* c8-cf */
- 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* d0-d7 */
- 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* d8-df */
- 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* e0-e7 */
- 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* e8-ef */
- 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xf6, /* f0-f7 */
- 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0x98, /* f8-ff */
-};
-
-static u_char
-dos2unix[256] = {
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 00-07 */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 08-0f */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 10-17 */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 18-1f */
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 48-4f */
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 50-57 */
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 58-5f */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 60-67 */
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 68-6f */
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 70-77 */
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 78-7f */
- 0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, /* 80-87 */
- 0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5, /* 88-8f */
- 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, /* 90-97 */
- 0xff, 0xd6, 0xdc, 0xf8, 0xa3, 0xd8, 0xd7, 0x3f, /* 98-9f */
- 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, /* a0-a7 */
- 0xbf, 0xae, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, /* a8-af */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xc1, 0xc2, 0xc0, /* b0-b7 */
- 0xa9, 0x3f, 0x3f, 0x3f, 0x3f, 0xa2, 0xa5, 0x3f, /* b8-bf */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xe3, 0xc3, /* c0-c7 */
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xa4, /* c8-cf */
- 0xf0, 0xd0, 0xca, 0xcb, 0xc8, 0x3f, 0xcd, 0xce, /* d0-d7 */
- 0xcf, 0x3f, 0x3f, 0x3f, 0x3f, 0xa6, 0xcc, 0x3f, /* d8-df */
- 0xd3, 0xdf, 0xd4, 0xd2, 0xf5, 0xd5, 0xb5, 0xfe, /* e0-e7 */
- 0xde, 0xda, 0xdb, 0xd9, 0xfd, 0xdd, 0xaf, 0x3f, /* e8-ef */
- 0xad, 0xb1, 0x3f, 0xbe, 0xb6, 0xa7, 0xf7, 0xb8, /* f0-f7 */
- 0xb0, 0xa8, 0xb7, 0xb9, 0xb3, 0xb2, 0x3f, 0x3f, /* f8-ff */
-};
-
-static u_char
-u2l[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 00-07 */
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 08-0f */
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 18-1f */
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
- 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 40-47 */
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 48-4f */
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 50-57 */
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 58-5f */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 60-67 */
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 68-6f */
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 70-77 */
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 78-7f */
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 80-87 */
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 88-8f */
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 90-97 */
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 98-9f */
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* a0-a7 */
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* a8-af */
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* b0-b7 */
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* b8-bf */
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* c0-c7 */
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* c8-cf */
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* d0-d7 */
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* d8-df */
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* e0-e7 */
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* e8-ef */
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* f0-f7 */
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
-};
-
-static u_char
-l2u[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 00-07 */
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 08-0f */
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 18-1f */
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
- 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 40-47 */
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 48-4f */
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 50-57 */
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 58-5f */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 60-67 */
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 68-6f */
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 70-77 */
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 78-7f */
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 80-87 */
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 88-8f */
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 90-97 */
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 98-9f */
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* a0-a7 */
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* a8-af */
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* b0-b7 */
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* b8-bf */
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* c0-c7 */
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* c8-cf */
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* d0-d7 */
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* d8-df */
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* e0-e7 */
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* e8-ef */
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* f0-f7 */
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
-};
-
-/*
- * DOS filenames are made of 2 parts, the name part and the extension part.
- * The name part is 8 characters long and the extension part is 3
- * characters long. They may contain trailing blanks if the name or
- * extension are not long enough to fill their respective fields.
- */
-
-/*
- * Convert a DOS filename to a unix filename. And, return the number of
- * characters in the resulting unix filename excluding the terminating
- * null.
- */
-int
-dos2unixfn(dn, un, lower, d2u_loaded, d2u, ul_loaded, ul)
- u_char dn[11];
- u_char *un;
- int lower;
- int d2u_loaded;
- u_int8_t *d2u;
- int ul_loaded;
- u_int8_t *ul;
-{
- int i;
- int thislong = 1;
- u_char c;
-
- /*
- * If first char of the filename is SLOT_E5 (0x05), then the real
- * first char of the filename should be 0xe5. But, they couldn't
- * just have a 0xe5 mean 0xe5 because that is used to mean a freed
- * directory slot. Another dos quirk.
- */
- if (*dn == SLOT_E5)
- c = d2u_loaded ? d2u[0xe5 & 0x7f] : dos2unix[0xe5];
- else
- c = d2u_loaded && (*dn & 0x80) ? d2u[*dn & 0x7f] :
- dos2unix[*dn];
- *un++ = (lower & LCASE_BASE) ? (ul_loaded && (c & 0x80) ?
- ul[c & 0x7f] : u2l[c]) : c;
- dn++;
-
- /*
- * Copy the name portion into the unix filename string.
- */
- for (i = 1; i < 8 && *dn != ' '; i++) {
- c = d2u_loaded && (*dn & 0x80) ? d2u[*dn & 0x7f] :
- dos2unix[*dn];
- dn++;
- *un++ = (lower & LCASE_BASE) ? (ul_loaded && (c & 0x80) ?
- ul[c & 0x7f] : u2l[c]) : c;
- thislong++;
- }
- dn += 8 - i;
-
- /*
- * Now, if there is an extension then put in a period and copy in
- * the extension.
- */
- if (*dn != ' ') {
- *un++ = '.';
- thislong++;
- for (i = 0; i < 3 && *dn != ' '; i++) {
- c = d2u_loaded && (*dn & 0x80) ? d2u[*dn & 0x7f] :
- dos2unix[*dn];
- dn++;
- *un++ = (lower & LCASE_EXT) ? (ul_loaded && (c & 0x80) ?
- ul[c & 0x7f] : u2l[c]) : c;
- thislong++;
- }
- }
- *un++ = 0;
-
- return (thislong);
-}
-
-/*
- * Convert a unix filename to a DOS filename according to Win95 rules.
- * If applicable and gen is not 0, it is inserted into the converted
- * filename as a generation number.
- * Returns
- * 0 if name couldn't be converted
- * 1 if the converted name is the same as the original
- * (no long filename entry necessary for Win95)
- * 2 if conversion was successful
- * 3 if conversion was successful and generation number was inserted
- */
-int
-unix2dosfn(un, dn, unlen, gen, u2d_loaded, u2d, lu_loaded, lu)
- const u_char *un;
- u_char dn[12];
- int unlen;
- u_int gen;
- int u2d_loaded;
- u_int8_t *u2d;
- int lu_loaded;
- u_int8_t *lu;
-{
- int i, j, l;
- int conv = 1;
- const u_char *cp, *dp, *dp1;
- u_char gentext[6], *wcp;
- u_int8_t c;
-#define U2D(c) (u2d_loaded && ((c) & 0x80) ? u2d[(c) & 0x7f] : unix2dos[c])
-
- /*
- * Fill the dos filename string with blanks. These are DOS's pad
- * characters.
- */
- for (i = 0; i < 11; i++)
- dn[i] = ' ';
- dn[11] = 0;
-
- /*
- * The filenames "." and ".." are handled specially, since they
- * don't follow dos filename rules.
- */
- if (un[0] == '.' && unlen == 1) {
- dn[0] = '.';
- return gen <= 1;
- }
- if (un[0] == '.' && un[1] == '.' && unlen == 2) {
- dn[0] = '.';
- dn[1] = '.';
- return gen <= 1;
- }
-
- /*
- * Filenames with only blanks and dots are not allowed!
- */
- for (cp = un, i = unlen; --i >= 0; cp++)
- if (*cp != ' ' && *cp != '.')
- break;
- if (i < 0)
- return 0;
-
-
- /*
- * Filenames with some characters are not allowed!
- */
- for (cp = un, i = unlen; --i >= 0; cp++)
- if (U2D(*cp) == 0)
- return 0;
-
- /*
- * Now find the extension
- * Note: dot as first char doesn't start extension
- * and trailing dots and blanks are ignored
- */
- dp = dp1 = 0;
- for (cp = un + 1, i = unlen - 1; --i >= 0;) {
- switch (*cp++) {
- case '.':
- if (!dp1)
- dp1 = cp;
- break;
- case ' ':
- break;
- default:
- if (dp1)
- dp = dp1;
- dp1 = 0;
- break;
- }
- }
-
- /*
- * Now convert it
- */
- if (dp) {
- if (dp1)
- l = dp1 - dp;
- else
- l = unlen - (dp - un);
- for (i = 0, j = 8; i < l && j < 11; i++, j++) {
- c = dp[i];
- c = lu_loaded && (c & 0x80) ?
- lu[c & 0x7f] : l2u[c];
- c = U2D(c);
- if (dp[i] != (dn[j] = c)
- && conv != 3)
- conv = 2;
- if (dn[j] == 1) {
- conv = 3;
- dn[j] = '_';
- }
- if (dn[j] == 2) {
- conv = 3;
- dn[j--] = ' ';
- }
- }
- if (i < l)
- conv = 3;
- dp--;
- } else {
- for (dp = cp; *--dp == ' ' || *dp == '.';);
- dp++;
- }
-
- /*
- * Now convert the rest of the name
- */
- for (i = j = 0; un < dp && j < 8; i++, j++, un++) {
- c = lu_loaded && (*un & 0x80) ?
- lu[*un & 0x7f] : l2u[*un];
- c = U2D(c);
- if (*un != (dn[j] = c)
- && conv != 3)
- conv = 2;
- if (dn[j] == 1) {
- conv = 3;
- dn[j] = '_';
- }
- if (dn[j] == 2) {
- conv = 3;
- dn[j--] = ' ';
- }
- }
- if (un < dp)
- conv = 3;
- /*
- * If we didn't have any chars in filename,
- * generate a default
- */
- if (!j)
- dn[0] = '_';
-
- /*
- * The first character cannot be E5,
- * because that means a deleted entry
- */
- if (dn[0] == 0xe5)
- dn[0] = SLOT_E5;
-
- /*
- * If there wasn't any char dropped,
- * there is no place for generation numbers
- */
- if (conv != 3) {
- if (gen > 1)
- return 0;
- return conv;
- }
-
- /*
- * Now insert the generation number into the filename part
- */
- if (gen == 0)
- return conv;
- for (wcp = gentext + sizeof(gentext); wcp > gentext && gen; gen /= 10)
- *--wcp = gen % 10 + '0';
- if (gen)
- return 0;
- for (i = 8; dn[--i] == ' ';);
- i++;
- if (gentext + sizeof(gentext) - wcp + 1 > 8 - i)
- i = 8 - (gentext + sizeof(gentext) - wcp + 1);
- dn[i++] = '~';
- while (wcp < gentext + sizeof(gentext))
- dn[i++] = *wcp++;
- return 3;
-#undef U2D
-}
-
-/*
- * Create a Win95 long name directory entry
- * Note: assumes that the filename is valid,
- * i.e. doesn't consist solely of blanks and dots
- */
-int
-unix2winfn(un, unlen, wep, cnt, chksum, table_loaded, u2w)
- const u_char *un;
- int unlen;
- struct winentry *wep;
- int cnt;
- int chksum;
- int table_loaded;
- u_int16_t *u2w;
-{
- const u_int8_t *cp;
- u_int8_t *wcp;
- int i;
- u_int16_t code;
-
- /*
- * Drop trailing blanks and dots
- */
- for (cp = un + unlen; *--cp == ' ' || *cp == '.'; unlen--);
-
- un += (cnt - 1) * WIN_CHARS;
- unlen -= (cnt - 1) * WIN_CHARS;
-
- /*
- * Initialize winentry to some useful default
- */
- for (wcp = (u_int8_t *)wep, i = sizeof(*wep); --i >= 0; *wcp++ = 0xff);
- wep->weCnt = cnt;
- wep->weAttributes = ATTR_WIN95;
- wep->weReserved1 = 0;
- wep->weChksum = chksum;
- wep->weReserved2 = 0;
-
- /*
- * Now convert the filename parts
- */
- for (wcp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
- if (--unlen < 0)
- goto done;
- if (table_loaded && (*un & 0x80)) {
- code = u2w[*un++ & 0x7f];
- *wcp++ = code;
- *wcp++ = code >> 8;
- } else {
- *wcp++ = *un++;
- *wcp++ = 0;
- }
- }
- for (wcp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
- if (--unlen < 0)
- goto done;
- if (table_loaded && (*un & 0x80)) {
- code = u2w[*un++ & 0x7f];
- *wcp++ = code;
- *wcp++ = code >> 8;
- } else {
- *wcp++ = *un++;
- *wcp++ = 0;
- }
- }
- for (wcp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
- if (--unlen < 0)
- goto done;
- if (table_loaded && (*un & 0x80)) {
- code = u2w[*un++ & 0x7f];
- *wcp++ = code;
- *wcp++ = code >> 8;
- } else {
- *wcp++ = *un++;
- *wcp++ = 0;
- }
- }
- if (!unlen)
- wep->weCnt |= WIN_LAST;
- return unlen;
-
-done:
- *wcp++ = 0;
- *wcp++ = 0;
- wep->weCnt |= WIN_LAST;
- return 0;
-}
-
-static __inline u_int8_t
-find_lcode(code, u2w)
- u_int16_t code;
- u_int16_t *u2w;
-{
- int i;
-
- for (i = 0; i < 128; i++)
- if (u2w[i] == code)
- return (i | 0x80);
- return '?';
-}
-
-/*
- * Compare our filename to the one in the Win95 entry
- * Returns the checksum or -1 if no match
- */
-int
-winChkName(un, unlen, wep, chksum, u2w_loaded, u2w, ul_loaded, ul)
- const u_char *un;
- int unlen;
- struct winentry *wep;
- int chksum;
- int u2w_loaded;
- u_int16_t *u2w;
- int ul_loaded;
- u_int8_t *ul;
-{
- u_int8_t *cp;
- int i;
- u_int16_t code;
- u_int8_t c1, c2;
-
- /*
- * First compare checksums
- */
- if (wep->weCnt&WIN_LAST)
- chksum = wep->weChksum;
- else if (chksum != wep->weChksum)
- chksum = -1;
- if (chksum == -1)
- return -1;
-
- /*
- * Offset of this entry
- */
- i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS;
- un += i;
- if ((unlen -= i) <= 0)
- return -1;
- if ((wep->weCnt&WIN_LAST) && unlen > WIN_CHARS)
- return -1;
-
- /*
- * Compare the name parts
- */
- for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
- if (--unlen < 0) {
- if (!*cp++ && !*cp)
- return chksum;
- return -1;
- }
- code = (cp[1] << 8) | cp[0];
- if (code & 0xff80) {
- if (u2w_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- c1 = ul_loaded && (code & 0x80) ?
- ul[code & 0x7f] : u2l[code];
- c2 = ul_loaded && (*un & 0x80) ?
- ul[*un & 0x7f] : u2l[*un];
- if (c1 != c2)
- return -1;
- cp += 2;
- un++;
- }
- for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
- if (--unlen < 0) {
- if (!*cp++ && !*cp)
- return chksum;
- return -1;
- }
- code = (cp[1] << 8) | cp[0];
- if (code & 0xff80) {
- if (u2w_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- c1 = ul_loaded && (code & 0x80) ?
- ul[code & 0x7f] : u2l[code];
- c2 = ul_loaded && (*un & 0x80) ?
- ul[*un & 0x7f] : u2l[*un];
- if (c1 != c2)
- return -1;
- cp += 2;
- un++;
- }
- for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
- if (--unlen < 0) {
- if (!*cp++ && !*cp)
- return chksum;
- return -1;
- }
- code = (cp[1] << 8) | cp[0];
- if (code & 0xff80) {
- if (u2w_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- c1 = ul_loaded && (code & 0x80) ?
- ul[code & 0x7f] : u2l[code];
- c2 = ul_loaded && (*un & 0x80) ?
- ul[*un & 0x7f] : u2l[*un];
- if (c1 != c2)
- return -1;
- cp += 2;
- un++;
- }
- return chksum;
-}
-
-/*
- * Convert Win95 filename to dirbuf.
- * Returns the checksum or -1 if impossible
- */
-int
-win2unixfn(wep, dp, chksum, table_loaded, u2w)
- struct winentry *wep;
- struct dirent *dp;
- int chksum;
- int table_loaded;
- u_int16_t *u2w;
-{
- u_int8_t *cp;
- u_int8_t *np, *ep = dp->d_name + WIN_MAXLEN;
- u_int16_t code;
- int i;
-
- if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
- || !(wep->weCnt&WIN_CNT))
- return -1;
-
- /*
- * First compare checksums
- */
- if (wep->weCnt&WIN_LAST) {
- chksum = wep->weChksum;
- /*
- * This works even though d_namlen is one byte!
- */
- dp->d_namlen = (wep->weCnt&WIN_CNT) * WIN_CHARS;
- } else if (chksum != wep->weChksum)
- chksum = -1;
- if (chksum == -1)
- return -1;
-
- /*
- * Offset of this entry
- */
- i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS;
- np = (u_int8_t *)dp->d_name + i;
-
- /*
- * Convert the name parts
- */
- for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
- code = (cp[1] << 8) | cp[0];
- switch (code) {
- case 0:
- *np = '\0';
- dp->d_namlen -= sizeof(wep->wePart2)/2
- + sizeof(wep->wePart3)/2 + i + 1;
- return chksum;
- case '/':
- *np = '\0';
- return -1;
- default:
- if (code & 0xff80) {
- if (table_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- *np++ = code;
- break;
- }
- /*
- * The size comparison should result in the compiler
- * optimizing the whole if away
- */
- if (WIN_MAXLEN % WIN_CHARS < sizeof(wep->wePart1) / 2
- && np > ep) {
- np[-1] = 0;
- return -1;
- }
- cp += 2;
- }
- for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
- code = (cp[1] << 8) | cp[0];
- switch (code) {
- case 0:
- *np = '\0';
- dp->d_namlen -= sizeof(wep->wePart3)/2 + i + 1;
- return chksum;
- case '/':
- *np = '\0';
- return -1;
- default:
- if (code & 0xff80) {
- if (table_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- *np++ = code;
- break;
- }
- /*
- * The size comparisons should be optimized away
- */
- if (WIN_MAXLEN % WIN_CHARS >= sizeof(wep->wePart1) / 2
- && WIN_MAXLEN % WIN_CHARS < (sizeof(wep->wePart1) + sizeof(wep->wePart2)) / 2
- && np > ep) {
- np[-1] = 0;
- return -1;
- }
- cp += 2;
- }
- for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
- code = (cp[1] << 8) | cp[0];
- switch (code) {
- case 0:
- *np = '\0';
- dp->d_namlen -= i + 1;
- return chksum;
- case '/':
- *np = '\0';
- return -1;
- default:
- if (code & 0xff80) {
- if (table_loaded)
- code = find_lcode(code, u2w);
- else if (code & 0xff00)
- code = '?';
- }
- *np++ = code;
- break;
- }
- /*
- * See above
- */
- if (WIN_MAXLEN % WIN_CHARS >= (sizeof(wep->wePart1) + sizeof(wep->wePart2)) / 2
- && np > ep) {
- np[-1] = 0;
- return -1;
- }
- cp += 2;
- }
- return chksum;
-}
-
-/*
- * Compute the checksum of a DOS filename for Win95 use
- */
-u_int8_t
-winChksum(name)
- u_int8_t *name;
-{
- int i;
- u_int8_t s;
-
- for (s = 0, i = 11; --i >= 0; s += *name++)
- s = (s << 7)|(s >> 1);
- return s;
-}
-
-/*
- * Determine the number of slots necessary for Win95 names
- */
-int
-winSlotCnt(un, unlen)
- const u_char *un;
- int unlen;
-{
- unlen = winLenFixup(un, unlen);
- if (unlen > WIN_MAXLEN)
- return 0;
- return howmany(unlen, WIN_CHARS);
-}
-
-/*
- * Determine the number of bytes neccesary for Win95 names
- */
-int
-winLenFixup(un, unlen)
- const u_char* un;
- int unlen;
-{
- for (un += unlen; unlen > 0; unlen--)
- if (*--un != ' ' && *un != '.')
- break;
- return unlen;
-}
diff --git a/sys/msdosfs/msdosfs_denode.c b/sys/msdosfs/msdosfs_denode.c
deleted file mode 100644
index dbdf554..0000000
--- a/sys/msdosfs/msdosfs_denode.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_denode.c,v 1.28 1998/02/10 14:10:00 mrg Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mount.h>
-#include <sys/malloc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/mutex.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <msdosfs/bpb.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/fat.h>
-
-static MALLOC_DEFINE(M_MSDOSFSNODE, "MSDOSFS node", "MSDOSFS vnode private part");
-
-static struct denode **dehashtbl;
-static u_long dehash; /* size of hash table - 1 */
-#define DEHASH(dev, dcl, doff) (dehashtbl[(minor(dev) + (dcl) + (doff) / \
- sizeof(struct direntry)) & dehash])
-static struct mtx dehash_mtx;
-
-union _qcvt {
- quad_t qcvt;
- long val[2];
-};
-#define SETHIGH(q, h) { \
- union _qcvt tmp; \
- tmp.qcvt = (q); \
- tmp.val[_QUAD_HIGHWORD] = (h); \
- (q) = tmp.qcvt; \
-}
-#define SETLOW(q, l) { \
- union _qcvt tmp; \
- tmp.qcvt = (q); \
- tmp.val[_QUAD_LOWWORD] = (l); \
- (q) = tmp.qcvt; \
-}
-
-static struct denode *
- msdosfs_hashget __P((dev_t dev, u_long dirclust,
- u_long diroff));
-static void msdosfs_hashins __P((struct denode *dep));
-static void msdosfs_hashrem __P((struct denode *dep));
-
-/*ARGSUSED*/
-int
-msdosfs_init(vfsp)
- struct vfsconf *vfsp;
-{
- dehashtbl = hashinit(desiredvnodes/2, M_MSDOSFSMNT, &dehash);
- mtx_init(&dehash_mtx, "msdosfs dehash", MTX_DEF);
- return (0);
-}
-
-int
-msdosfs_uninit(vfsp)
- struct vfsconf *vfsp;
-{
-
- if (dehashtbl)
- free(dehashtbl, M_MSDOSFSMNT);
- mtx_destroy(&dehash_mtx);
- return (0);
-}
-
-static struct denode *
-msdosfs_hashget(dev, dirclust, diroff)
- dev_t dev;
- u_long dirclust;
- u_long diroff;
-{
- struct proc *p = curproc; /* XXX */
- struct denode *dep;
- struct vnode *vp;
-
-loop:
- mtx_lock(&dehash_mtx);
- for (dep = DEHASH(dev, dirclust, diroff); dep; dep = dep->de_next) {
- if (dirclust == dep->de_dirclust
- && diroff == dep->de_diroffset
- && dev == dep->de_dev
- && dep->de_refcnt != 0) {
- vp = DETOV(dep);
- mtx_lock(&vp->v_interlock);
- mtx_unlock(&dehash_mtx);
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
- goto loop;
- return (dep);
- }
- }
- mtx_unlock(&dehash_mtx);
- return (NULL);
-}
-
-static void
-msdosfs_hashins(dep)
- struct denode *dep;
-{
- struct denode **depp, *deq;
-
- mtx_lock(&dehash_mtx);
- depp = &DEHASH(dep->de_dev, dep->de_dirclust, dep->de_diroffset);
- deq = *depp;
- if (deq)
- deq->de_prev = &dep->de_next;
- dep->de_next = deq;
- dep->de_prev = depp;
- *depp = dep;
- mtx_unlock(&dehash_mtx);
-}
-
-static void
-msdosfs_hashrem(dep)
- struct denode *dep;
-{
- struct denode *deq;
-
- mtx_lock(&dehash_mtx);
- deq = dep->de_next;
- if (deq)
- deq->de_prev = dep->de_prev;
- *dep->de_prev = deq;
-#ifdef DIAGNOSTIC
- dep->de_next = NULL;
- dep->de_prev = NULL;
-#endif
- mtx_unlock(&dehash_mtx);
-}
-
-/*
- * If deget() succeeds it returns with the gotten denode locked().
- *
- * pmp - address of msdosfsmount structure of the filesystem containing
- * the denode of interest. The pm_dev field and the address of
- * the msdosfsmount structure are used.
- * dirclust - which cluster bp contains, if dirclust is 0 (root directory)
- * diroffset is relative to the beginning of the root directory,
- * otherwise it is cluster relative.
- * diroffset - offset past begin of cluster of denode we want
- * depp - returns the address of the gotten denode.
- */
-int
-deget(pmp, dirclust, diroffset, depp)
- struct msdosfsmount *pmp; /* so we know the maj/min number */
- u_long dirclust; /* cluster this dir entry came from */
- u_long diroffset; /* index of entry within the cluster */
- struct denode **depp; /* returns the addr of the gotten denode */
-{
- int error;
- dev_t dev = pmp->pm_dev;
- struct mount *mntp = pmp->pm_mountp;
- struct direntry *direntptr;
- struct denode *ldep;
- struct vnode *nvp;
- struct buf *bp;
- struct proc *p = curproc; /* XXX */
- struct timeval tv;
-
-#ifdef MSDOSFS_DEBUG
- printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n",
- pmp, dirclust, diroffset, depp);
-#endif
-
- /*
- * On FAT32 filesystems, root is a (more or less) normal
- * directory
- */
- if (FAT32(pmp) && dirclust == MSDOSFSROOT)
- dirclust = pmp->pm_rootdirblk;
-
- /*
- * See if the denode is in the denode cache. Use the location of
- * the directory entry to compute the hash value. For subdir use
- * address of "." entry. For root dir (if not FAT32) use cluster
- * MSDOSFSROOT, offset MSDOSFSROOT_OFS
- *
- * NOTE: The check for de_refcnt > 0 below insures the denode being
- * examined does not represent an unlinked but still open file.
- * These files are not to be accessible even when the directory
- * entry that represented the file happens to be reused while the
- * deleted file is still open.
- */
- ldep = msdosfs_hashget(dev, dirclust, diroffset);
- if (ldep) {
- *depp = ldep;
- return (0);
- }
-
- /*
- * Do the MALLOC before the getnewvnode since doing so afterward
- * might cause a bogus v_data pointer to get dereferenced
- * elsewhere if MALLOC should block.
- */
- MALLOC(ldep, struct denode *, sizeof(struct denode), M_MSDOSFSNODE, M_WAITOK);
-
- /*
- * Directory entry was not in cache, have to create a vnode and
- * copy it from the passed disk buffer.
- */
- /* getnewvnode() does a VREF() on the vnode */
- error = getnewvnode(VT_MSDOSFS, mntp, msdosfs_vnodeop_p, &nvp);
- if (error) {
- *depp = NULL;
- FREE(ldep, M_MSDOSFSNODE);
- return error;
- }
- bzero((caddr_t)ldep, sizeof *ldep);
- lockinit(&nvp->v_lock, PINOD, "denode", 0, 0);
- nvp->v_vnlock = &nvp->v_lock;
- nvp->v_data = ldep;
- ldep->de_vnode = nvp;
- ldep->de_flag = 0;
- ldep->de_devvp = 0;
- ldep->de_dev = dev;
- ldep->de_dirclust = dirclust;
- ldep->de_diroffset = diroffset;
- fc_purge(ldep, 0); /* init the fat cache for this denode */
-
- /*
- * Lock the denode so that it can't be accessed until we've read
- * it in and have done what we need to it. Do this here instead
- * of at the start of msdosfs_hashins() so that reinsert() can
- * call msdosfs_hashins() with a locked denode.
- */
- if (VOP_LOCK(nvp, LK_EXCLUSIVE, p) != 0)
- panic("deget: unexpected lock failure");
-
- /*
- * Insert the denode into the hash queue.
- */
- msdosfs_hashins(ldep);
-
- ldep->de_pmp = pmp;
- ldep->de_refcnt = 1;
- /*
- * Copy the directory entry into the denode area of the vnode.
- */
- if ((dirclust == MSDOSFSROOT
- || (FAT32(pmp) && dirclust == pmp->pm_rootdirblk))
- && diroffset == MSDOSFSROOT_OFS) {
- /*
- * Directory entry for the root directory. There isn't one,
- * so we manufacture one. We should probably rummage
- * through the root directory and find a label entry (if it
- * exists), and then use the time and date from that entry
- * as the time and date for the root denode.
- */
- nvp->v_flag |= VROOT; /* should be further down XXX */
-
- ldep->de_Attributes = ATTR_DIRECTORY;
- ldep->de_LowerCase = 0;
- if (FAT32(pmp))
- ldep->de_StartCluster = pmp->pm_rootdirblk;
- /* de_FileSize will be filled in further down */
- else {
- ldep->de_StartCluster = MSDOSFSROOT;
- ldep->de_FileSize = pmp->pm_rootdirsize * DEV_BSIZE;
- }
- /*
- * fill in time and date so that dos2unixtime() doesn't
- * spit up when called from msdosfs_getattr() with root
- * denode
- */
- ldep->de_CHun = 0;
- ldep->de_CTime = 0x0000; /* 00:00:00 */
- ldep->de_CDate = (0 << DD_YEAR_SHIFT) | (1 << DD_MONTH_SHIFT)
- | (1 << DD_DAY_SHIFT);
- /* Jan 1, 1980 */
- ldep->de_ADate = ldep->de_CDate;
- ldep->de_MTime = ldep->de_CTime;
- ldep->de_MDate = ldep->de_CDate;
- /* leave the other fields as garbage */
- } else {
- error = readep(pmp, dirclust, diroffset, &bp, &direntptr);
- if (error) {
- /*
- * The denode does not contain anything useful, so
- * it would be wrong to leave it on its hash chain.
- * Arrange for vput() to just forget about it.
- */
- ldep->de_Name[0] = SLOT_DELETED;
-
- vput(nvp);
- *depp = NULL;
- return (error);
- }
- DE_INTERNALIZE(ldep, direntptr);
- brelse(bp);
- }
-
- /*
- * Fill in a few fields of the vnode and finish filling in the
- * denode. Then return the address of the found denode.
- */
- if (ldep->de_Attributes & ATTR_DIRECTORY) {
- /*
- * Since DOS directory entries that describe directories
- * have 0 in the filesize field, we take this opportunity
- * to find out the length of the directory and plug it into
- * the denode structure.
- */
- u_long size;
-
- nvp->v_type = VDIR;
- if (ldep->de_StartCluster != MSDOSFSROOT) {
- error = pcbmap(ldep, 0xffff, 0, &size, 0);
- if (error == E2BIG) {
- ldep->de_FileSize = de_cn2off(pmp, size);
- error = 0;
- } else
- printf("deget(): pcbmap returned %d\n", error);
- }
- } else
- nvp->v_type = VREG;
- getmicrouptime(&tv);
- SETHIGH(ldep->de_modrev, tv.tv_sec);
- SETLOW(ldep->de_modrev, tv.tv_usec * 4294);
- ldep->de_devvp = pmp->pm_devvp;
- VREF(ldep->de_devvp);
- *depp = ldep;
- return (0);
-}
-
-int
-deupdat(dep, waitfor)
- struct denode *dep;
- int waitfor;
-{
- int error;
- struct buf *bp;
- struct direntry *dirp;
- struct timespec ts;
-
- if (DETOV(dep)->v_mount->mnt_flag & MNT_RDONLY)
- return (0);
- getnanotime(&ts);
- DETIMES(dep, &ts, &ts, &ts);
- if ((dep->de_flag & DE_MODIFIED) == 0)
- return (0);
- dep->de_flag &= ~DE_MODIFIED;
- if (dep->de_Attributes & ATTR_DIRECTORY)
- return (0);
- if (dep->de_refcnt <= 0)
- return (0);
- error = readde(dep, &bp, &dirp);
- if (error)
- return (error);
- DE_EXTERNALIZE(dirp, dep);
- if (waitfor)
- return (bwrite(bp));
- else {
- bdwrite(bp);
- return (0);
- }
-}
-
-/*
- * Truncate the file described by dep to the length specified by length.
- */
-int
-detrunc(dep, length, flags, cred, p)
- struct denode *dep;
- u_long length;
- int flags;
- struct ucred *cred;
- struct proc *p;
-{
- int error;
- int allerror;
- u_long eofentry;
- u_long chaintofree;
- daddr_t bn;
- int boff;
- int isadir = dep->de_Attributes & ATTR_DIRECTORY;
- struct buf *bp;
- struct msdosfsmount *pmp = dep->de_pmp;
-
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): file %s, length %lu, flags %x\n", dep->de_Name, length, flags);
-#endif
-
- /*
- * Disallow attempts to truncate the root directory since it is of
- * fixed size. That's just the way dos filesystems are. We use
- * the VROOT bit in the vnode because checking for the directory
- * bit and a startcluster of 0 in the denode is not adequate to
- * recognize the root directory at this point in a file or
- * directory's life.
- */
- if ((DETOV(dep)->v_flag & VROOT) && !FAT32(pmp)) {
- printf("detrunc(): can't truncate root directory, clust %ld, offset %ld\n",
- dep->de_dirclust, dep->de_diroffset);
- return (EINVAL);
- }
-
-
- if (dep->de_FileSize < length) {
- vnode_pager_setsize(DETOV(dep), length);
- return deextend(dep, length, cred);
- }
-
- /*
- * If the desired length is 0 then remember the starting cluster of
- * the file and set the StartCluster field in the directory entry
- * to 0. If the desired length is not zero, then get the number of
- * the last cluster in the shortened file. Then get the number of
- * the first cluster in the part of the file that is to be freed.
- * Then set the next cluster pointer in the last cluster of the
- * file to CLUST_EOFE.
- */
- if (length == 0) {
- chaintofree = dep->de_StartCluster;
- dep->de_StartCluster = 0;
- eofentry = ~0;
- } else {
- error = pcbmap(dep, de_clcount(pmp, length) - 1, 0,
- &eofentry, 0);
- if (error) {
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): pcbmap fails %d\n", error);
-#endif
- return (error);
- }
- }
-
- fc_purge(dep, de_clcount(pmp, length));
-
- /*
- * If the new length is not a multiple of the cluster size then we
- * must zero the tail end of the new last cluster in case it
- * becomes part of the file again because of a seek.
- */
- if ((boff = length & pmp->pm_crbomask) != 0) {
- if (isadir) {
- bn = cntobn(pmp, eofentry);
- error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
- NOCRED, &bp);
- } else {
- bn = de_blk(pmp, length);
- error = bread(DETOV(dep), bn, pmp->pm_bpcluster,
- NOCRED, &bp);
- }
- if (error) {
- brelse(bp);
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): bread fails %d\n", error);
-#endif
- return (error);
- }
- /*
- * is this the right place for it?
- */
- bzero(bp->b_data + boff, pmp->pm_bpcluster - boff);
- if (flags & IO_SYNC)
- bwrite(bp);
- else
- bdwrite(bp);
- }
-
- /*
- * Write out the updated directory entry. Even if the update fails
- * we free the trailing clusters.
- */
- dep->de_FileSize = length;
- if (!isadir)
- dep->de_flag |= DE_UPDATE|DE_MODIFIED;
- allerror = vtruncbuf(DETOV(dep), cred, p, length, pmp->pm_bpcluster);
-#ifdef MSDOSFS_DEBUG
- if (allerror)
- printf("detrunc(): vtruncbuf error %d\n", allerror);
-#endif
- error = deupdat(dep, 1);
- if (error && (allerror == 0))
- allerror = error;
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): allerror %d, eofentry %lu\n",
- allerror, eofentry);
-#endif
-
- /*
- * If we need to break the cluster chain for the file then do it
- * now.
- */
- if (eofentry != ~0) {
- error = fatentry(FAT_GET_AND_SET, pmp, eofentry,
- &chaintofree, CLUST_EOFE);
- if (error) {
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): fatentry errors %d\n", error);
-#endif
- return (error);
- }
- fc_setcache(dep, FC_LASTFC, de_cluster(pmp, length - 1),
- eofentry);
- }
-
- /*
- * Now free the clusters removed from the file because of the
- * truncation.
- */
- if (chaintofree != 0 && !MSDOSFSEOF(pmp, chaintofree))
- freeclusterchain(pmp, chaintofree);
-
- return (allerror);
-}
-
-/*
- * Extend the file described by dep to length specified by length.
- */
-int
-deextend(dep, length, cred)
- struct denode *dep;
- u_long length;
- struct ucred *cred;
-{
- struct msdosfsmount *pmp = dep->de_pmp;
- u_long count;
- int error;
-
- /*
- * The root of a DOS filesystem cannot be extended.
- */
- if ((DETOV(dep)->v_flag & VROOT) && !FAT32(pmp))
- return (EINVAL);
-
- /*
- * Directories cannot be extended.
- */
- if (dep->de_Attributes & ATTR_DIRECTORY)
- return (EISDIR);
-
- if (length <= dep->de_FileSize)
- panic("deextend: file too large");
-
- /*
- * Compute the number of clusters to allocate.
- */
- count = de_clcount(pmp, length) - de_clcount(pmp, dep->de_FileSize);
- if (count > 0) {
- if (count > pmp->pm_freeclustercount)
- return (ENOSPC);
- error = extendfile(dep, count, NULL, NULL, DE_CLEAR);
- if (error) {
- /* truncate the added clusters away again */
- (void) detrunc(dep, dep->de_FileSize, 0, cred, NULL);
- return (error);
- }
- }
- dep->de_FileSize = length;
- dep->de_flag |= DE_UPDATE|DE_MODIFIED;
- return (deupdat(dep, 1));
-}
-
-/*
- * Move a denode to its correct hash queue after the file it represents has
- * been moved to a new directory.
- */
-void
-reinsert(dep)
- struct denode *dep;
-{
- /*
- * Fix up the denode cache. If the denode is for a directory,
- * there is nothing to do since the hash is based on the starting
- * cluster of the directory file and that hasn't changed. If for a
- * file the hash is based on the location of the directory entry,
- * so we must remove it from the cache and re-enter it with the
- * hash based on the new location of the directory entry.
- */
- if (dep->de_Attributes & ATTR_DIRECTORY)
- return;
- msdosfs_hashrem(dep);
- msdosfs_hashins(dep);
-}
-
-int
-msdosfs_reclaim(ap)
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(vp);
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_reclaim(): dep %p, file %s, refcnt %ld\n",
- dep, dep->de_Name, dep->de_refcnt);
-#endif
-
- if (prtactive && vp->v_usecount != 0)
- vprint("msdosfs_reclaim(): pushing active", vp);
- /*
- * Remove the denode from its hash chain.
- */
- msdosfs_hashrem(dep);
- /*
- * Purge old data structures associated with the denode.
- */
- cache_purge(vp);
- if (dep->de_devvp) {
- vrele(dep->de_devvp);
- dep->de_devvp = 0;
- }
-#if 0 /* XXX */
- dep->de_flag = 0;
-#endif
- lockdestroy(&vp->v_lock);
- FREE(dep, M_MSDOSFSNODE);
- vp->v_data = NULL;
-
- return (0);
-}
-
-int
-msdosfs_inactive(ap)
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- struct proc *a_p;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(vp);
- struct proc *p = ap->a_p;
- int error = 0;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_inactive(): dep %p, de_Name[0] %x\n", dep, dep->de_Name[0]);
-#endif
-
- if (prtactive && vp->v_usecount != 0)
- vprint("msdosfs_inactive(): pushing active", vp);
-
- /*
- * Ignore denodes related to stale file handles.
- */
- if (dep->de_Name[0] == SLOT_DELETED)
- goto out;
-
- /*
- * If the file has been deleted and it is on a read/write
- * filesystem, then truncate the file, and mark the directory slot
- * as empty. (This may not be necessary for the dos filesystem.)
- */
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %x, MNT_RDONLY %x\n",
- dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
-#endif
- if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
- error = detrunc(dep, (u_long) 0, 0, NOCRED, p);
- dep->de_flag |= DE_UPDATE;
- dep->de_Name[0] = SLOT_DELETED;
- }
- deupdat(dep, 0);
-
-out:
- VOP_UNLOCK(vp, 0, p);
- /*
- * If we are done with the denode, reclaim it
- * so that it can be reused immediately.
- */
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n", vp->v_usecount,
- dep->de_Name[0]);
-#endif
- if (dep->de_Name[0] == SLOT_DELETED)
- vrecycle(vp, NULL, p);
- return (error);
-}
diff --git a/sys/msdosfs/msdosfs_fat.c b/sys/msdosfs/msdosfs_fat.c
deleted file mode 100644
index 38abc16..0000000
--- a/sys/msdosfs/msdosfs_fat.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_fat.c,v 1.28 1997/11/17 15:36:49 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-/*
- * kernel include files.
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/mount.h> /* to define statfs structure */
-#include <sys/vnode.h> /* to define vattr structure */
-
-/*
- * msdosfs include files.
- */
-#include <msdosfs/bpb.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/fat.h>
-
-/*
- * Fat cache stats.
- */
-static int fc_fileextends; /* # of file extends */
-static int fc_lfcempty; /* # of time last file cluster cache entry
- * was empty */
-static int fc_bmapcalls; /* # of times pcbmap was called */
-
-#define LMMAX 20
-static int fc_lmdistance[LMMAX];/* counters for how far off the last
- * cluster mapped entry was. */
-static int fc_largedistance; /* off by more than LMMAX */
-
-static int chainalloc __P((struct msdosfsmount *pmp, u_long start,
- u_long count, u_long fillwith,
- u_long *retcluster, u_long *got));
-static int chainlength __P((struct msdosfsmount *pmp, u_long start,
- u_long count));
-static void fatblock __P((struct msdosfsmount *pmp, u_long ofs,
- u_long *bnp, u_long *sizep, u_long *bop));
-static int fatchain __P((struct msdosfsmount *pmp, u_long start,
- u_long count, u_long fillwith));
-static void fc_lookup __P((struct denode *dep, u_long findcn,
- u_long *frcnp, u_long *fsrcnp));
-static void updatefats __P((struct msdosfsmount *pmp, struct buf *bp,
- u_long fatbn));
-static __inline void
- usemap_alloc __P((struct msdosfsmount *pmp, u_long cn));
-static __inline void
- usemap_free __P((struct msdosfsmount *pmp, u_long cn));
-
-static void
-fatblock(pmp, ofs, bnp, sizep, bop)
- struct msdosfsmount *pmp;
- u_long ofs;
- u_long *bnp;
- u_long *sizep;
- u_long *bop;
-{
- u_long bn, size;
-
- bn = ofs / pmp->pm_fatblocksize * pmp->pm_fatblocksec;
- size = min(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn)
- * DEV_BSIZE;
- bn += pmp->pm_fatblk + pmp->pm_curfat * pmp->pm_FATsecs;
-
- if (bnp)
- *bnp = bn;
- if (sizep)
- *sizep = size;
- if (bop)
- *bop = ofs % pmp->pm_fatblocksize;
-}
-
-/*
- * Map the logical cluster number of a file into a physical disk sector
- * that is filesystem relative.
- *
- * dep - address of denode representing the file of interest
- * findcn - file relative cluster whose filesystem relative cluster number
- * and/or block number are/is to be found
- * bnp - address of where to place the file system relative block number.
- * If this pointer is null then don't return this quantity.
- * cnp - address of where to place the file system relative cluster number.
- * If this pointer is null then don't return this quantity.
- *
- * NOTE: Either bnp or cnp must be non-null.
- * This function has one side effect. If the requested file relative cluster
- * is beyond the end of file, then the actual number of clusters in the file
- * is returned in *cnp. This is useful for determining how long a directory is.
- * If cnp is null, nothing is returned.
- */
-int
-pcbmap(dep, findcn, bnp, cnp, sp)
- struct denode *dep;
- u_long findcn; /* file relative cluster to get */
- daddr_t *bnp; /* returned filesys relative blk number */
- u_long *cnp; /* returned cluster number */
- int *sp; /* returned block size */
-{
- int error;
- u_long i;
- u_long cn;
- u_long prevcn = 0; /* XXX: prevcn could be used unititialized */
- u_long byteoffset;
- u_long bn;
- u_long bo;
- struct buf *bp = NULL;
- u_long bp_bn = -1;
- struct msdosfsmount *pmp = dep->de_pmp;
- u_long bsize;
-
- fc_bmapcalls++;
-
- /*
- * If they don't give us someplace to return a value then don't
- * bother doing anything.
- */
- if (bnp == NULL && cnp == NULL && sp == NULL)
- return (0);
-
- cn = dep->de_StartCluster;
- /*
- * The "file" that makes up the root directory is contiguous,
- * permanently allocated, of fixed size, and is not made up of
- * clusters. If the cluster number is beyond the end of the root
- * directory, then return the number of clusters in the file.
- */
- if (cn == MSDOSFSROOT) {
- if (dep->de_Attributes & ATTR_DIRECTORY) {
- if (de_cn2off(pmp, findcn) >= dep->de_FileSize) {
- if (cnp)
- *cnp = de_bn2cn(pmp, pmp->pm_rootdirsize);
- return (E2BIG);
- }
- if (bnp)
- *bnp = pmp->pm_rootdirblk + de_cn2bn(pmp, findcn);
- if (cnp)
- *cnp = MSDOSFSROOT;
- if (sp)
- *sp = min(pmp->pm_bpcluster,
- dep->de_FileSize - de_cn2off(pmp, findcn));
- return (0);
- } else { /* just an empty file */
- if (cnp)
- *cnp = 0;
- return (E2BIG);
- }
- }
-
- /*
- * All other files do I/O in cluster sized blocks
- */
- if (sp)
- *sp = pmp->pm_bpcluster;
-
- /*
- * Rummage around in the fat cache, maybe we can avoid tromping
- * thru every fat entry for the file. And, keep track of how far
- * off the cache was from where we wanted to be.
- */
- i = 0;
- fc_lookup(dep, findcn, &i, &cn);
- if ((bn = findcn - i) >= LMMAX)
- fc_largedistance++;
- else
- fc_lmdistance[bn]++;
-
- /*
- * Handle all other files or directories the normal way.
- */
- for (; i < findcn; i++) {
- /*
- * Stop with all reserved clusters, not just with EOF.
- */
- if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
- goto hiteof;
- byteoffset = FATOFS(pmp, cn);
- fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- if (bn != bp_bn) {
- if (bp)
- brelse(bp);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- bp_bn = bn;
- }
- prevcn = cn;
- if (FAT32(pmp))
- cn = getulong(&bp->b_data[bo]);
- else
- cn = getushort(&bp->b_data[bo]);
- if (FAT12(pmp) && (prevcn & 1))
- cn >>= 4;
- cn &= pmp->pm_fatmask;
-
- /*
- * Force the special cluster numbers
- * to be the same for all cluster sizes
- * to let the rest of msdosfs handle
- * all cases the same.
- */
- if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
- cn |= ~pmp->pm_fatmask;
- }
-
- if (!MSDOSFSEOF(pmp, cn)) {
- if (bp)
- brelse(bp);
- if (bnp)
- *bnp = cntobn(pmp, cn);
- if (cnp)
- *cnp = cn;
- fc_setcache(dep, FC_LASTMAP, i, cn);
- return (0);
- }
-
-hiteof:;
- if (cnp)
- *cnp = i;
- if (bp)
- brelse(bp);
- /* update last file cluster entry in the fat cache */
- fc_setcache(dep, FC_LASTFC, i - 1, prevcn);
- return (E2BIG);
-}
-
-/*
- * Find the closest entry in the fat cache to the cluster we are looking
- * for.
- */
-static void
-fc_lookup(dep, findcn, frcnp, fsrcnp)
- struct denode *dep;
- u_long findcn;
- u_long *frcnp;
- u_long *fsrcnp;
-{
- int i;
- u_long cn;
- struct fatcache *closest = 0;
-
- for (i = 0; i < FC_SIZE; i++) {
- cn = dep->de_fc[i].fc_frcn;
- if (cn != FCE_EMPTY && cn <= findcn) {
- if (closest == 0 || cn > closest->fc_frcn)
- closest = &dep->de_fc[i];
- }
- }
- if (closest) {
- *frcnp = closest->fc_frcn;
- *fsrcnp = closest->fc_fsrcn;
- }
-}
-
-/*
- * Purge the fat cache in denode dep of all entries relating to file
- * relative cluster frcn and beyond.
- */
-void
-fc_purge(dep, frcn)
- struct denode *dep;
- u_int frcn;
-{
- int i;
- struct fatcache *fcp;
-
- fcp = dep->de_fc;
- for (i = 0; i < FC_SIZE; i++, fcp++) {
- if (fcp->fc_frcn >= frcn)
- fcp->fc_frcn = FCE_EMPTY;
- }
-}
-
-/*
- * Update the fat.
- * If mirroring the fat, update all copies, with the first copy as last.
- * Else update only the current fat (ignoring the others).
- *
- * 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.
- */
-static void
-updatefats(pmp, bp, fatbn)
- struct msdosfsmount *pmp;
- struct buf *bp;
- u_long fatbn;
-{
- int i;
- struct buf *bpn;
-
-#ifdef MSDOSFS_DEBUG
- printf("updatefats(pmp %p, bp %p, fatbn %lu)\n", pmp, bp, fatbn);
-#endif
-
- /*
- * If we have an FSInfo block, update it.
- */
- if (pmp->pm_fsinfo) {
- u_long cn = pmp->pm_nxtfree;
-
- if (pmp->pm_freeclustercount
- && (pmp->pm_inusemap[cn / N_INUSEBITS]
- & (1 << (cn % N_INUSEBITS)))) {
- /*
- * The cluster indicated in FSInfo isn't free
- * any longer. Got get a new free one.
- */
- for (cn = 0; cn < pmp->pm_maxcluster; cn += N_INUSEBITS)
- if (pmp->pm_inusemap[cn / N_INUSEBITS] != (u_int)-1)
- break;
- pmp->pm_nxtfree = cn
- + ffs(pmp->pm_inusemap[cn / N_INUSEBITS]
- ^ (u_int)-1) - 1;
- }
- if (bread(pmp->pm_devvp, pmp->pm_fsinfo, fsi_size(pmp),
- NOCRED, &bpn) != 0) {
- /*
- * Ignore the error, but turn off FSInfo update for the future.
- */
- pmp->pm_fsinfo = 0;
- brelse(bpn);
- } else {
- struct fsinfo *fp = (struct fsinfo *)bpn->b_data;
-
- putulong(fp->fsinfree, pmp->pm_freeclustercount);
- putulong(fp->fsinxtfree, pmp->pm_nxtfree);
- if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
- bwrite(bpn);
- else
- bdwrite(bpn);
- }
- }
-
- if (pmp->pm_flags & MSDOSFS_FATMIRROR) {
- /*
- * Now copy the block(s) of the modified fat to the other copies of
- * the fat and write them out. This is faster than reading in the
- * other fats and then writing them back out. This could tie up
- * the fat for quite a while. Preventing others from accessing it.
- * To prevent us from going after the fat quite so much we use
- * delayed writes, unless they specfied "synchronous" when the
- * filesystem was mounted. If synch is asked for then use
- * bwrite()'s and really slow things down.
- */
- for (i = 1; i < pmp->pm_FATs; i++) {
- fatbn += pmp->pm_FATsecs;
- /* getblk() never fails */
- bpn = getblk(pmp->pm_devvp, fatbn, bp->b_bcount, 0, 0);
- bcopy(bp->b_data, bpn->b_data, bp->b_bcount);
- if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
- bwrite(bpn);
- else
- bdwrite(bpn);
- }
- }
-
- /*
- * Write out the first (or current) fat last.
- */
- if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
- bwrite(bp);
- else
- bdwrite(bp);
- /*
- * Maybe update fsinfo sector here?
- */
-}
-
-/*
- * Updating entries in 12 bit fats is a pain in the butt.
- *
- * The following picture shows where nibbles go when moving from a 12 bit
- * cluster number into the appropriate bytes in the FAT.
- *
- * byte m byte m+1 byte m+2
- * +----+----+ +----+----+ +----+----+
- * | 0 1 | | 2 3 | | 4 5 | FAT bytes
- * +----+----+ +----+----+ +----+----+
- *
- * +----+----+----+ +----+----+----+
- * | 3 0 1 | | 4 5 2 |
- * +----+----+----+ +----+----+----+
- * cluster n cluster n+1
- *
- * Where n is even. m = n + (n >> 2)
- *
- */
-static __inline void
-usemap_alloc(pmp, cn)
- struct msdosfsmount *pmp;
- u_long cn;
-{
-
- pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
- pmp->pm_freeclustercount--;
-}
-
-static __inline void
-usemap_free(pmp, cn)
- struct msdosfsmount *pmp;
- u_long cn;
-{
-
- pmp->pm_freeclustercount++;
- pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
-}
-
-int
-clusterfree(pmp, cluster, oldcnp)
- struct msdosfsmount *pmp;
- u_long cluster;
- u_long *oldcnp;
-{
- int error;
- u_long oldcn;
-
- usemap_free(pmp, cluster);
- error = fatentry(FAT_GET_AND_SET, pmp, cluster, &oldcn, MSDOSFSFREE);
- if (error) {
- usemap_alloc(pmp, cluster);
- return (error);
- }
- /*
- * If the cluster was successfully marked free, then update
- * the count of free clusters, and turn off the "allocated"
- * bit in the "in use" cluster bit map.
- */
- if (oldcnp)
- *oldcnp = oldcn;
- return (0);
-}
-
-/*
- * Get or Set or 'Get and Set' the cluster'th entry in the fat.
- *
- * function - whether to get or set a fat entry
- * pmp - address of the msdosfsmount structure for the filesystem
- * whose fat is to be manipulated.
- * cn - which cluster is of interest
- * oldcontents - address of a word that is to receive the contents of the
- * cluster'th entry if this is a get function
- * newcontents - the new value to be written into the cluster'th element of
- * the fat if this is a set function.
- *
- * This function can also be used to free a cluster by setting the fat entry
- * for a cluster to 0.
- *
- * All copies of the fat are updated if this is a set function. NOTE: If
- * fatentry() marks a cluster as free it does not update the inusemap in
- * the msdosfsmount structure. This is left to the caller.
- */
-int
-fatentry(function, pmp, cn, oldcontents, newcontents)
- int function;
- struct msdosfsmount *pmp;
- u_long cn;
- u_long *oldcontents;
- u_long newcontents;
-{
- int error;
- u_long readcn;
- u_long bn, bo, bsize, byteoffset;
- struct buf *bp;
-
-#ifdef MSDOSFS_DEBUG
- printf("fatentry(func %d, pmp %p, clust %lu, oldcon %p, newcon %lx)\n",
- function, pmp, cn, oldcontents, newcontents);
-#endif
-
-#ifdef DIAGNOSTIC
- /*
- * Be sure they asked us to do something.
- */
- if ((function & (FAT_SET | FAT_GET)) == 0) {
- printf("fatentry(): function code doesn't specify get or set\n");
- return (EINVAL);
- }
-
- /*
- * If they asked us to return a cluster number but didn't tell us
- * where to put it, give them an error.
- */
- if ((function & FAT_GET) && oldcontents == NULL) {
- printf("fatentry(): get function with no place to put result\n");
- return (EINVAL);
- }
-#endif
-
- /*
- * Be sure the requested cluster is in the filesystem.
- */
- if (cn < CLUST_FIRST || cn > pmp->pm_maxcluster)
- return (EINVAL);
-
- byteoffset = FATOFS(pmp, cn);
- fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- if (function & FAT_GET) {
- if (FAT32(pmp))
- readcn = getulong(&bp->b_data[bo]);
- else
- readcn = getushort(&bp->b_data[bo]);
- if (FAT12(pmp) & (cn & 1))
- readcn >>= 4;
- readcn &= pmp->pm_fatmask;
- /* map reserved fat entries to same values for all fats */
- if ((readcn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
- readcn |= ~pmp->pm_fatmask;
- *oldcontents = readcn;
- }
- if (function & FAT_SET) {
- switch (pmp->pm_fatmask) {
- case FAT12_MASK:
- readcn = getushort(&bp->b_data[bo]);
- if (cn & 1) {
- readcn &= 0x000f;
- readcn |= newcontents << 4;
- } else {
- readcn &= 0xf000;
- readcn |= newcontents & 0xfff;
- }
- putushort(&bp->b_data[bo], readcn);
- break;
- case FAT16_MASK:
- putushort(&bp->b_data[bo], newcontents);
- break;
- case FAT32_MASK:
- /*
- * According to spec we have to retain the
- * high order bits of the fat entry.
- */
- readcn = getulong(&bp->b_data[bo]);
- readcn &= ~FAT32_MASK;
- readcn |= newcontents & FAT32_MASK;
- putulong(&bp->b_data[bo], readcn);
- break;
- }
- updatefats(pmp, bp, bn);
- bp = NULL;
- pmp->pm_fmod = 1;
- }
- if (bp)
- brelse(bp);
- return (0);
-}
-
-/*
- * Update a contiguous cluster chain
- *
- * pmp - mount point
- * start - first cluster of chain
- * count - number of clusters in chain
- * fillwith - what to write into fat entry of last cluster
- */
-static int
-fatchain(pmp, start, count, fillwith)
- struct msdosfsmount *pmp;
- u_long start;
- u_long count;
- u_long fillwith;
-{
- int error;
- u_long bn, bo, bsize, byteoffset, readcn, newc;
- struct buf *bp;
-
-#ifdef MSDOSFS_DEBUG
- printf("fatchain(pmp %p, start %lu, count %lu, fillwith %lx)\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);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- while (count > 0) {
- start++;
- newc = --count > 0 ? start : fillwith;
- switch (pmp->pm_fatmask) {
- case FAT12_MASK:
- 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++;
- break;
- case FAT16_MASK:
- putushort(&bp->b_data[bo], newc);
- bo += 2;
- break;
- case FAT32_MASK:
- readcn = getulong(&bp->b_data[bo]);
- readcn &= ~pmp->pm_fatmask;
- readcn |= newc & pmp->pm_fatmask;
- putulong(&bp->b_data[bo], readcn);
- bo += 4;
- break;
- }
- if (bo >= bsize)
- break;
- }
- updatefats(pmp, bp, bn);
- }
- pmp->pm_fmod = 1;
- return (0);
-}
-
-/*
- * Check the length of a free cluster chain starting at start.
- *
- * pmp - mount point
- * start - start of chain
- * count - maximum interesting length
- */
-static 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 / 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;
- map = pmp->pm_inusemap[idx];
- if (map) {
- 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.
- */
-static 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;
- u_long cl, n;
-
- for (cl = start, n = count; n-- > 0;)
- usemap_alloc(pmp, cl++);
-
- error = fatchain(pmp, start, count, fillwith);
- if (error != 0)
- return (error);
-#ifdef MSDOSFS_DEBUG
- printf("clusteralloc(): allocated cluster chain at %lu (%lu clusters)\n",
- start, count);
-#endif
- if (retcluster)
- *retcluster = start;
- if (got)
- *got = count;
- return (0);
-}
-
-/*
- * 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;
-{
- u_long idx;
- u_long len, newst, foundl, cn, l;
- u_long foundcn = 0; /* XXX: foundcn could be used unititialized */
- u_int map;
-
-#ifdef MSDOSFS_DEBUG
- printf("clusteralloc(): find %lu clusters\n",count);
-#endif
- if (start) {
- if ((len = chainlength(pmp, start, count)) >= count)
- return (chainalloc(pmp, start, count, fillwith, retcluster, got));
- } else
- len = 0;
-
- /*
- * Start at a (pseudo) random place to maximize cluster runs
- * under multiple writers.
- */
- newst = random() % (pmp->pm_maxcluster + 1);
- foundl = 0;
-
- for (cn = newst; cn <= pmp->pm_maxcluster;) {
- idx = cn / N_INUSEBITS;
- map = pmp->pm_inusemap[idx];
- map |= (1 << (cn % N_INUSEBITS)) - 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;
- continue;
- }
- cn += N_INUSEBITS - cn % N_INUSEBITS;
- }
- for (cn = 0; cn < newst;) {
- idx = cn / N_INUSEBITS;
- map = pmp->pm_inusemap[idx];
- map |= (1 << (cn % N_INUSEBITS)) - 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;
- continue;
- }
- cn += N_INUSEBITS - cn % N_INUSEBITS;
- }
-
- 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.
- *
- * pmp - address of the msdosfs mount structure for the filesystem
- * containing the cluster chain to be freed.
- * startcluster - number of the 1st cluster in the chain of clusters to be
- * freed.
- */
-int
-freeclusterchain(pmp, cluster)
- struct msdosfsmount *pmp;
- u_long cluster;
-{
- int error;
- 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, lbn);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- lbn = bn;
- }
- usemap_free(pmp, cluster);
- switch (pmp->pm_fatmask) {
- case FAT12_MASK:
- readcn = getushort(&bp->b_data[bo]);
- 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);
- break;
- case FAT16_MASK:
- cluster = getushort(&bp->b_data[bo]);
- putushort(&bp->b_data[bo], MSDOSFSFREE);
- break;
- case FAT32_MASK:
- cluster = getulong(&bp->b_data[bo]);
- putulong(&bp->b_data[bo],
- (MSDOSFSFREE & FAT32_MASK) | (cluster & ~FAT32_MASK));
- break;
- }
- cluster &= pmp->pm_fatmask;
- if ((cluster | ~pmp->pm_fatmask) >= CLUST_RSRVD)
- cluster |= pmp->pm_fatmask;
- }
- if (bp)
- updatefats(pmp, bp, bn);
- return (0);
-}
-
-/*
- * Read in fat blocks looking for free clusters. For every free cluster
- * found turn off its corresponding bit in the pm_inusemap.
- */
-int
-fillinusemap(pmp)
- struct msdosfsmount *pmp;
-{
- struct buf *bp = NULL;
- u_long cn, readcn;
- int error;
- u_long bn, bo, bsize, byteoffset;
-
- /*
- * Mark all clusters in use, we mark the free ones in the fat scan
- * loop further down.
- */
- for (cn = 0; cn < (pmp->pm_maxcluster + N_INUSEBITS) / N_INUSEBITS; cn++)
- pmp->pm_inusemap[cn] = (u_int)-1;
-
- /*
- * Figure how many free clusters are in the filesystem by ripping
- * through the fat counting the number of entries whose content is
- * zero. These represent free clusters.
- */
- pmp->pm_freeclustercount = 0;
- for (cn = CLUST_FIRST; cn <= pmp->pm_maxcluster; cn++) {
- byteoffset = FATOFS(pmp, cn);
- bo = byteoffset % pmp->pm_fatblocksize;
- if (!bo || !bp) {
- /* Read new FAT block */
- if (bp)
- brelse(bp);
- fatblock(pmp, byteoffset, &bn, &bsize, NULL);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
- if (FAT32(pmp))
- readcn = getulong(&bp->b_data[bo]);
- else
- readcn = getushort(&bp->b_data[bo]);
- if (FAT12(pmp) && (cn & 1))
- readcn >>= 4;
- readcn &= pmp->pm_fatmask;
-
- if (readcn == 0)
- usemap_free(pmp, cn);
- }
- brelse(bp);
- return (0);
-}
-
-/*
- * Allocate a new cluster and chain it onto the end of the file.
- *
- * 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_UPDATE 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, count, bpp, ncp, flags)
- struct denode *dep;
- u_long count;
- struct buf **bpp;
- u_long *ncp;
- int flags;
-{
- int error;
- u_long frcn;
- u_long cn, got;
- struct msdosfsmount *pmp = dep->de_pmp;
- struct buf *bp;
-
- /*
- * Don't try to extend the root directory
- */
- if (dep->de_StartCluster == MSDOSFSROOT
- && (dep->de_Attributes & ATTR_DIRECTORY)) {
- printf("extendfile(): attempt to extend root directory\n");
- return (ENOSPC);
- }
-
- /*
- * If the "file's last cluster" cache entry is empty, and the file
- * is not empty, then fill the cache entry by calling pcbmap().
- */
- fc_fileextends++;
- if (dep->de_fc[FC_LASTFC].fc_frcn == FCE_EMPTY &&
- dep->de_StartCluster != 0) {
- fc_lfcempty++;
- error = pcbmap(dep, 0xffff, 0, &cn, 0);
- /* we expect it to return E2BIG */
- if (error != E2BIG)
- return (error);
- }
-
- 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;
- error = clusteralloc(pmp, cn, count, CLUST_EOFE, &cn, &got);
- if (error)
- 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), de_cn2bn(pmp, frcn++),
- pmp->pm_bpcluster, 0, 0);
- /*
- * Do the bmap now, as in msdosfs_write
- */
- if (pcbmap(dep,
- de_bn2cn(pmp, bp->b_lblkno),
- &bp->b_blkno, 0, 0))
- bp->b_blkno = -1;
- if (bp->b_blkno == -1)
- panic("extendfile: pcbmap");
- }
- clrbuf(bp);
- if (bpp) {
- *bpp = bp;
- bpp = NULL;
- } else
- bdwrite(bp);
- }
- }
- }
-
- return (0);
-}
diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c
deleted file mode 100644
index 776559d..0000000
--- a/sys/msdosfs/msdosfs_lookup.c
+++ /dev/null
@@ -1,1100 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-
-#include <msdosfs/bpb.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
-
-/*
- * When we search a directory the blocks containing directory entries are
- * read and examined. The directory entries contain information that would
- * normally be in the inode of a unix filesystem. This means that some of
- * a directory's contents may also be in memory resident denodes (sort of
- * an inode). This can cause problems if we are searching while some other
- * process is modifying a directory. To prevent one process from accessing
- * incompletely modified directory information we depend upon being the
- * sole owner of a directory block. bread/brelse provide this service.
- * This being the case, when a process modifies a directory it must first
- * acquire the disk block that contains the directory entry to be modified.
- * Then update the disk block and the denode, and then write the disk block
- * out to disk. This way disk blocks containing directory entries and in
- * memory denode's will be in synch.
- */
-int
-msdosfs_lookup(ap)
- struct vop_cachedlookup_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- struct vnode *vdp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- daddr_t bn;
- int error;
- int lockparent;
- int wantparent;
- int slotcount;
- int slotoffset = 0;
- int frcn;
- u_long cluster;
- int blkoff;
- int diroff;
- int blsize;
- int isadir; /* ~0 if found direntry is a directory */
- u_long scn; /* starting cluster number */
- struct vnode *pdp;
- struct denode *dp;
- struct denode *tdp;
- struct msdosfsmount *pmp;
- struct buf *bp = 0;
- struct direntry *dep = NULL;
- u_char dosfilename[12];
- int flags = cnp->cn_flags;
- int nameiop = cnp->cn_nameiop;
- struct proc *p = cnp->cn_proc;
- int unlen;
-
- int wincnt = 1;
- int chksum = -1;
- int olddos = 1;
- cnp->cn_flags &= ~PDIRUNLOCK;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
-#endif
- dp = VTODE(vdp);
- pmp = dp->de_pmp;
- *vpp = NULL;
- lockparent = flags & LOCKPARENT;
- wantparent = flags & (LOCKPARENT | WANTPARENT);
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
- vdp, dp, dp->de_Attributes);
-#endif
-
- /*
- * If they are going after the . or .. entry in the root directory,
- * they won't find it. DOS filesystems don't have them in the root
- * directory. So, we fake it. deget() is in on this scam too.
- */
- if ((vdp->v_flag & VROOT) && cnp->cn_nameptr[0] == '.' &&
- (cnp->cn_namelen == 1 ||
- (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) {
- isadir = ATTR_DIRECTORY;
- scn = MSDOSFSROOT;
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): looking for . or .. in root directory\n");
-#endif
- cluster = MSDOSFSROOT;
- blkoff = MSDOSFSROOT_OFS;
- goto foundroot;
- }
-
- switch (unix2dosfn((const u_char *)cnp->cn_nameptr, dosfilename,
- cnp->cn_namelen, 0,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
- pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu)) {
- case 0:
- return (EINVAL);
- case 1:
- break;
- case 2:
- wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen) + 1;
- break;
- case 3:
- olddos = 0;
- wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen) + 1;
- break;
- }
- if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME) {
- wincnt = 1;
- olddos = 1;
- }
- unlen = winLenFixup(cnp->cn_nameptr, cnp->cn_namelen);
-
- /*
- * Suppress search for slots unless creating
- * file and at end of pathname, in which case
- * we watch for a place to put the new file in
- * case it doesn't already exist.
- */
- slotcount = wincnt;
- if ((nameiop == CREATE || nameiop == RENAME) &&
- (flags & ISLASTCN))
- slotcount = 0;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): dos version of filename %s, length %ld\n",
- dosfilename, cnp->cn_namelen);
-#endif
- /*
- * Search the directory pointed at by vdp for the name pointed at
- * by cnp->cn_nameptr.
- */
- tdp = NULL;
- /*
- * The outer loop ranges over the clusters that make up the
- * directory. Note that the root directory is different from all
- * other directories. It has a fixed number of blocks that are not
- * part of the pool of allocatable clusters. So, we treat it a
- * little differently. The root directory starts at "cluster" 0.
- */
- diroff = 0;
- for (frcn = 0;; frcn++) {
- error = pcbmap(dp, frcn, &bn, &cluster, &blsize);
- if (error) {
- if (error == E2BIG)
- break;
- return (error);
- }
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- for (blkoff = 0; blkoff < blsize;
- blkoff += sizeof(struct direntry),
- diroff += sizeof(struct direntry)) {
- dep = (struct direntry *)(bp->b_data + blkoff);
- /*
- * If the slot is empty and we are still looking
- * for an empty then remember this one. If the
- * slot is not empty then check to see if it
- * matches what we are looking for. If the slot
- * has never been filled with anything, then the
- * remainder of the directory has never been used,
- * so there is no point in searching it.
- */
- if (dep->deName[0] == SLOT_EMPTY ||
- dep->deName[0] == SLOT_DELETED) {
- /*
- * Drop memory of previous long matches
- */
- chksum = -1;
-
- if (slotcount < wincnt) {
- slotcount++;
- slotoffset = diroff;
- }
- if (dep->deName[0] == SLOT_EMPTY) {
- brelse(bp);
- goto notfound;
- }
- } else {
- /*
- * If there wasn't enough space for our winentries,
- * forget about the empty space
- */
- if (slotcount < wincnt)
- slotcount = 0;
-
- /*
- * Check for Win95 long filename entry
- */
- if (dep->deAttributes == ATTR_WIN95) {
- if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
- continue;
-
- chksum = winChkName((const u_char *)cnp->cn_nameptr,
- unlen,
- (struct winentry *)dep,
- chksum,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
- pmp->pm_u2w,
- pmp->pm_flags & MSDOSFSMNT_ULTABLE,
- pmp->pm_ul);
- continue;
- }
-
- /*
- * Ignore volume labels (anywhere, not just
- * the root directory).
- */
- if (dep->deAttributes & ATTR_VOLUME) {
- chksum = -1;
- continue;
- }
-
- /*
- * Check for a checksum or name match
- */
- if (chksum != winChksum(dep->deName)
- && (!olddos || bcmp(dosfilename, dep->deName, 11))) {
- chksum = -1;
- continue;
- }
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): match blkoff %d, diroff %d\n",
- blkoff, diroff);
-#endif
- /*
- * Remember where this directory
- * entry came from for whoever did
- * this lookup.
- */
- dp->de_fndoffset = diroff;
- dp->de_fndcnt = wincnt - 1;
-
- goto found;
- }
- } /* for (blkoff = 0; .... */
- /*
- * Release the buffer holding the directory cluster just
- * searched.
- */
- brelse(bp);
- } /* for (frcn = 0; ; frcn++) */
-
-notfound:
- /*
- * We hold no disk buffers at this point.
- */
-
- /*
- * Fixup the slot description to point to the place where
- * we might put the new DOS direntry (putting the Win95
- * long name entries before that)
- */
- if (!slotcount) {
- slotcount = 1;
- slotoffset = diroff;
- }
- if (wincnt > slotcount)
- slotoffset += sizeof(struct direntry) * (wincnt - slotcount);
-
- /*
- * If we get here we didn't find the entry we were looking for. But
- * that's ok if we are creating or renaming and are at the end of
- * the pathname and the directory hasn't been removed.
- */
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): op %d, refcnt %ld\n",
- nameiop, dp->de_refcnt);
- printf(" slotcount %d, slotoffset %d\n",
- slotcount, slotoffset);
-#endif
- if ((nameiop == CREATE || nameiop == RENAME) &&
- (flags & ISLASTCN) && dp->de_refcnt != 0) {
- /*
- * Access for write is interpreted as allowing
- * creation of files in the directory.
- */
- error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc);
- if (error)
- return (error);
- /*
- * Return an indication of where the new directory
- * entry should be put.
- */
- dp->de_fndoffset = slotoffset;
- dp->de_fndcnt = wincnt - 1;
-
- /*
- * We return with the directory locked, so that
- * the parameters we set up above will still be
- * valid if we actually decide to do a direnter().
- * We return ni_vp == NULL to indicate that the entry
- * does not currently exist; we leave a pointer to
- * the (locked) directory inode in ndp->ni_dvp.
- * The pathname buffer is saved so that the name
- * can be obtained later.
- *
- * NB - if the directory is unlocked, then this
- * information cannot be used.
- */
- cnp->cn_flags |= SAVENAME;
- if (!lockparent) {
- VOP_UNLOCK(vdp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (EJUSTRETURN);
- }
- /*
- * Insert name into cache (as non-existent) if appropriate.
- */
- if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
- cache_enter(vdp, *vpp, cnp);
- return (ENOENT);
-
-found:
- /*
- * NOTE: We still have the buffer with matched directory entry at
- * this point.
- */
- isadir = dep->deAttributes & ATTR_DIRECTORY;
- scn = getushort(dep->deStartCluster);
- if (FAT32(pmp)) {
- scn |= getushort(dep->deHighClust) << 16;
- if (scn == pmp->pm_rootdirblk) {
- /*
- * There should actually be 0 here.
- * Just ignore the error.
- */
- scn = MSDOSFSROOT;
- }
- }
-
- if (isadir) {
- cluster = scn;
- if (cluster == MSDOSFSROOT)
- blkoff = MSDOSFSROOT_OFS;
- else
- blkoff = 0;
- } else if (cluster == MSDOSFSROOT)
- blkoff = diroff;
-
- /*
- * Now release buf to allow deget to read the entry again.
- * Reserving it here and giving it to deget could result
- * in a deadlock.
- */
- brelse(bp);
- bp = 0;
-
-foundroot:
- /*
- * If we entered at foundroot, then we are looking for the . or ..
- * entry of the filesystems root directory. isadir and scn were
- * setup before jumping here. And, bp is already null.
- */
- if (FAT32(pmp) && scn == MSDOSFSROOT)
- scn = pmp->pm_rootdirblk;
-
- /*
- * If deleting, and at end of pathname, return
- * parameters which can be used to remove file.
- * If the wantparent flag isn't set, we return only
- * the directory (in ndp->ni_dvp), otherwise we go
- * on and lock the inode, being careful with ".".
- */
- if (nameiop == DELETE && (flags & ISLASTCN)) {
- /*
- * Don't allow deleting the root.
- */
- if (blkoff == MSDOSFSROOT_OFS)
- return EROFS; /* really? XXX */
-
- /*
- * Write access to directory required to delete files.
- */
- error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc);
- if (error)
- return (error);
-
- /*
- * Return pointer to current entry in dp->i_offset.
- * Save directory inode pointer in ndp->ni_dvp for dirremove().
- */
- if (dp->de_StartCluster == scn && isadir) { /* "." */
- VREF(vdp);
- *vpp = vdp;
- return (0);
- }
- error = deget(pmp, cluster, blkoff, &tdp);
- if (error)
- return (error);
- *vpp = DETOV(tdp);
- if (!lockparent) {
- VOP_UNLOCK(vdp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (0);
- }
-
- /*
- * If rewriting (RENAME), return the inode and the
- * information required to rewrite the present directory
- * Must get inode of directory entry to verify it's a
- * regular file, or empty directory.
- */
- if (nameiop == RENAME && wantparent &&
- (flags & ISLASTCN)) {
- if (blkoff == MSDOSFSROOT_OFS)
- return EROFS; /* really? XXX */
-
- error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_proc);
- if (error)
- return (error);
-
- /*
- * Careful about locking second inode.
- * This can only occur if the target is ".".
- */
- if (dp->de_StartCluster == scn && isadir)
- return (EISDIR);
-
- if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
- return (error);
- *vpp = DETOV(tdp);
- cnp->cn_flags |= SAVENAME;
- if (!lockparent) {
- VOP_UNLOCK(vdp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- return (0);
- }
-
- /*
- * Step through the translation in the name. We do not `vput' the
- * directory because we may need it again if a symbolic link
- * is relative to the current directory. Instead we save it
- * unlocked as "pdp". We must get the target inode before unlocking
- * the directory to insure that the inode will not be removed
- * before we get it. We prevent deadlock by always fetching
- * inodes from the root, moving down the directory tree. Thus
- * when following backward pointers ".." we must unlock the
- * parent directory before getting the requested directory.
- * There is a potential race condition here if both the current
- * and parent directories are removed before the VFS_VGET for the
- * inode associated with ".." returns. We hope that this occurs
- * infrequently since we cannot avoid this race condition without
- * implementing a sophisticated deadlock detection algorithm.
- * Note also that this simple deadlock detection scheme will not
- * work if the file system has any hard links other than ".."
- * that point backwards in the directory structure.
- */
- pdp = vdp;
- if (flags & ISDOTDOT) {
- VOP_UNLOCK(pdp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- error = deget(pmp, cluster, blkoff, &tdp);
- if (error) {
- vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
- cnp->cn_flags &= ~PDIRUNLOCK;
- return (error);
- }
- if (lockparent && (flags & ISLASTCN)) {
- error = vn_lock(pdp, LK_EXCLUSIVE, p);
- if (error) {
- vput(DETOV(tdp));
- return (error);
- }
- cnp->cn_flags &= ~PDIRUNLOCK;
- }
- *vpp = DETOV(tdp);
- } else if (dp->de_StartCluster == scn && isadir) {
- VREF(vdp); /* we want ourself, ie "." */
- *vpp = vdp;
- } else {
- if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
- return (error);
- if (!lockparent || !(flags & ISLASTCN)) {
- VOP_UNLOCK(pdp, 0, p);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- *vpp = DETOV(tdp);
- }
-
- /*
- * Insert name into cache if appropriate.
- */
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(vdp, *vpp, cnp);
- return (0);
-}
-
-/*
- * dep - directory entry to copy into the directory
- * ddep - directory to add to
- * depp - return the address of the denode for the created directory entry
- * if depp != 0
- * cnp - componentname needed for Win95 long filenames
- */
-int
-createde(dep, ddep, depp, cnp)
- struct denode *dep;
- struct denode *ddep;
- struct denode **depp;
- struct componentname *cnp;
-{
- int error;
- u_long dirclust, diroffset;
- struct direntry *ndep;
- struct msdosfsmount *pmp = ddep->de_pmp;
- struct buf *bp;
- daddr_t bn;
- int blsize;
-
-#ifdef MSDOSFS_DEBUG
- printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n",
- dep, ddep, depp, cnp);
-#endif
-
- /*
- * If no space left in the directory then allocate another cluster
- * and chain it onto the end of the file. There is one exception
- * to this. That is, if the root directory has no more space it
- * can NOT be expanded. extendfile() checks for and fails attempts
- * to extend the root directory. We just return an error in that
- * case.
- */
- if (ddep->de_fndoffset >= ddep->de_FileSize) {
- diroffset = ddep->de_fndoffset + sizeof(struct direntry)
- - ddep->de_FileSize;
- dirclust = de_clcount(pmp, diroffset);
- error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR);
- if (error) {
- (void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED, NULL);
- return error;
- }
-
- /*
- * Update the size of the directory
- */
- ddep->de_FileSize += de_cn2off(pmp, dirclust);
- }
-
- /*
- * We just read in the cluster with space. Copy the new directory
- * entry in. Then write it to disk. NOTE: DOS directories
- * do not get smaller as clusters are emptied.
- */
- error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset),
- &bn, &dirclust, &blsize);
- if (error)
- return error;
- diroffset = ddep->de_fndoffset;
- if (dirclust != MSDOSFSROOT)
- diroffset &= pmp->pm_crbomask;
- if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) != 0) {
- brelse(bp);
- return error;
- }
- ndep = bptoep(pmp, bp, ddep->de_fndoffset);
-
- DE_EXTERNALIZE(ndep, dep);
-
- /*
- * Now write the Win95 long name
- */
- if (ddep->de_fndcnt > 0) {
- u_int8_t chksum = winChksum(ndep->deName);
- const u_char *un = (const u_char *)cnp->cn_nameptr;
- int unlen = cnp->cn_namelen;
- int cnt = 1;
-
- while (--ddep->de_fndcnt >= 0) {
- if (!(ddep->de_fndoffset & pmp->pm_crbomask)) {
- if ((error = bwrite(bp)) != 0)
- return error;
-
- ddep->de_fndoffset -= sizeof(struct direntry);
- error = pcbmap(ddep,
- de_cluster(pmp,
- ddep->de_fndoffset),
- &bn, 0, &blsize);
- if (error)
- return error;
-
- error = bread(pmp->pm_devvp, bn, blsize,
- NOCRED, &bp);
- if (error) {
- brelse(bp);
- return error;
- }
- ndep = bptoep(pmp, bp, ddep->de_fndoffset);
- } else {
- ndep--;
- ddep->de_fndoffset -= sizeof(struct direntry);
- }
- if (!unix2winfn(un, unlen, (struct winentry *)ndep,
- cnt++, chksum,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
- pmp->pm_u2w))
- break;
- }
- }
-
- if ((error = bwrite(bp)) != 0)
- return error;
-
- /*
- * If they want us to return with the denode gotten.
- */
- if (depp) {
- if (dep->de_Attributes & ATTR_DIRECTORY) {
- dirclust = dep->de_StartCluster;
- if (FAT32(pmp) && dirclust == pmp->pm_rootdirblk)
- dirclust = MSDOSFSROOT;
- if (dirclust == MSDOSFSROOT)
- diroffset = MSDOSFSROOT_OFS;
- else
- diroffset = 0;
- }
- return deget(pmp, dirclust, diroffset, depp);
- }
-
- return 0;
-}
-
-/*
- * Be sure a directory is empty except for "." and "..". Return 1 if empty,
- * return 0 if not empty or error.
- */
-int
-dosdirempty(dep)
- struct denode *dep;
-{
- int blsize;
- int error;
- u_long cn;
- daddr_t bn;
- struct buf *bp;
- struct msdosfsmount *pmp = dep->de_pmp;
- struct direntry *dentp;
-
- /*
- * Since the filesize field in directory entries for a directory is
- * zero, we just have to feel our way through the directory until
- * we hit end of file.
- */
- for (cn = 0;; cn++) {
- if ((error = pcbmap(dep, cn, &bn, 0, &blsize)) != 0) {
- if (error == E2BIG)
- return (1); /* it's empty */
- return (0);
- }
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (0);
- }
- for (dentp = (struct direntry *)bp->b_data;
- (char *)dentp < bp->b_data + blsize;
- dentp++) {
- if (dentp->deName[0] != SLOT_DELETED &&
- (dentp->deAttributes & ATTR_VOLUME) == 0) {
- /*
- * In dos directories an entry whose name
- * starts with SLOT_EMPTY (0) starts the
- * beginning of the unused part of the
- * directory, so we can just return that it
- * is empty.
- */
- if (dentp->deName[0] == SLOT_EMPTY) {
- brelse(bp);
- return (1);
- }
- /*
- * Any names other than "." and ".." in a
- * directory mean it is not empty.
- */
- if (bcmp(dentp->deName, ". ", 11) &&
- bcmp(dentp->deName, ".. ", 11)) {
- brelse(bp);
-#ifdef MSDOSFS_DEBUG
- printf("dosdirempty(): entry found %02x, %02x\n",
- dentp->deName[0], dentp->deName[1]);
-#endif
- return (0); /* not empty */
- }
- }
- }
- brelse(bp);
- }
- /* NOTREACHED */
-}
-
-/*
- * Check to see if the directory described by target is in some
- * subdirectory of source. This prevents something like the following from
- * succeeding and leaving a bunch or files and directories orphaned. mv
- * /a/b/c /a/b/c/d/e/f Where c and f are directories.
- *
- * source - the inode for /a/b/c
- * target - the inode for /a/b/c/d/e/f
- *
- * Returns 0 if target is NOT a subdirectory of source.
- * Otherwise returns a non-zero error number.
- * The target inode is always unlocked on return.
- */
-int
-doscheckpath(source, target)
- struct denode *source;
- struct denode *target;
-{
- daddr_t scn;
- struct msdosfsmount *pmp;
- struct direntry *ep;
- struct denode *dep;
- struct buf *bp = NULL;
- int error = 0;
-
- dep = target;
- if ((target->de_Attributes & ATTR_DIRECTORY) == 0 ||
- (source->de_Attributes & ATTR_DIRECTORY) == 0) {
- error = ENOTDIR;
- goto out;
- }
- if (dep->de_StartCluster == source->de_StartCluster) {
- error = EEXIST;
- goto out;
- }
- if (dep->de_StartCluster == MSDOSFSROOT)
- goto out;
- pmp = dep->de_pmp;
-#ifdef DIAGNOSTIC
- if (pmp != source->de_pmp)
- panic("doscheckpath: source and target on different filesystems");
-#endif
- if (FAT32(pmp) && dep->de_StartCluster == pmp->pm_rootdirblk)
- goto out;
-
- for (;;) {
- if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) {
- error = ENOTDIR;
- break;
- }
- scn = dep->de_StartCluster;
- error = bread(pmp->pm_devvp, cntobn(pmp, scn),
- pmp->pm_bpcluster, NOCRED, &bp);
- if (error)
- break;
-
- ep = (struct direntry *) bp->b_data + 1;
- if ((ep->deAttributes & ATTR_DIRECTORY) == 0 ||
- bcmp(ep->deName, ".. ", 11) != 0) {
- error = ENOTDIR;
- break;
- }
- scn = getushort(ep->deStartCluster);
- if (FAT32(pmp))
- scn |= getushort(ep->deHighClust) << 16;
-
- if (scn == source->de_StartCluster) {
- error = EINVAL;
- break;
- }
- if (scn == MSDOSFSROOT)
- break;
- if (FAT32(pmp) && scn == pmp->pm_rootdirblk) {
- /*
- * scn should be 0 in this case,
- * but we silently ignore the error.
- */
- break;
- }
-
- vput(DETOV(dep));
- brelse(bp);
- bp = NULL;
- /* NOTE: deget() clears dep on error */
- if ((error = deget(pmp, scn, 0, &dep)) != 0)
- break;
- }
-out:;
- if (bp)
- brelse(bp);
- if (error == ENOTDIR)
- printf("doscheckpath(): .. not a directory?\n");
- if (dep != NULL)
- vput(DETOV(dep));
- return (error);
-}
-
-/*
- * Read in the disk block containing the directory entry (dirclu, dirofs)
- * and return the address of the buf header, and the address of the
- * directory entry within the block.
- */
-int
-readep(pmp, dirclust, diroffset, bpp, epp)
- struct msdosfsmount *pmp;
- u_long dirclust, diroffset;
- struct buf **bpp;
- struct direntry **epp;
-{
- int error;
- daddr_t bn;
- int blsize;
-
- blsize = pmp->pm_bpcluster;
- if (dirclust == MSDOSFSROOT
- && de_blk(pmp, diroffset + blsize) > pmp->pm_rootdirsize)
- blsize = de_bn2off(pmp, pmp->pm_rootdirsize) & pmp->pm_crbomask;
- bn = detobn(pmp, dirclust, diroffset);
- if ((error = bread(pmp->pm_devvp, bn, blsize, NOCRED, bpp)) != 0) {
- brelse(*bpp);
- *bpp = NULL;
- return (error);
- }
- if (epp)
- *epp = bptoep(pmp, *bpp, diroffset);
- return (0);
-}
-
-/*
- * Read in the disk block containing the directory entry dep came from and
- * return the address of the buf header, and the address of the directory
- * entry within the block.
- */
-int
-readde(dep, bpp, epp)
- struct denode *dep;
- struct buf **bpp;
- struct direntry **epp;
-{
-
- return (readep(dep->de_pmp, dep->de_dirclust, dep->de_diroffset,
- bpp, epp));
-}
-
-/*
- * Remove a directory entry. At this point the file represented by the
- * directory entry to be removed is still full length until noone has it
- * open. When the file no longer being used msdosfs_inactive() is called
- * and will truncate the file to 0 length. When the vnode containing the
- * denode is needed for some other purpose by VFS it will call
- * msdosfs_reclaim() which will remove the denode from the denode cache.
- */
-int
-removede(pdep, dep)
- struct denode *pdep; /* directory where the entry is removed */
- struct denode *dep; /* file to be removed */
-{
- int error;
- struct direntry *ep;
- struct buf *bp;
- daddr_t bn;
- int blsize;
- struct msdosfsmount *pmp = pdep->de_pmp;
- u_long offset = pdep->de_fndoffset;
-
-#ifdef MSDOSFS_DEBUG
- printf("removede(): filename %s, dep %p, offset %08lx\n",
- dep->de_Name, dep, offset);
-#endif
-
- dep->de_refcnt--;
- offset += sizeof(struct direntry);
- do {
- offset -= sizeof(struct direntry);
- error = pcbmap(pdep, de_cluster(pmp, offset), &bn, 0, &blsize);
- if (error)
- return error;
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return error;
- }
- ep = bptoep(pmp, bp, offset);
- /*
- * Check whether, if we came here the second time, i.e.
- * when underflowing into the previous block, the last
- * entry in this block is a longfilename entry, too.
- */
- if (ep->deAttributes != ATTR_WIN95
- && offset != pdep->de_fndoffset) {
- brelse(bp);
- break;
- }
- offset += sizeof(struct direntry);
- while (1) {
- /*
- * We are a bit agressive here in that we delete any Win95
- * entries preceding this entry, not just the ones we "own".
- * Since these presumably aren't valid anyway,
- * there should be no harm.
- */
- offset -= sizeof(struct direntry);
- ep--->deName[0] = SLOT_DELETED;
- if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95)
- || !(offset & pmp->pm_crbomask)
- || ep->deAttributes != ATTR_WIN95)
- break;
- }
- if ((error = bwrite(bp)) != 0)
- return error;
- } while (!(pmp->pm_flags & MSDOSFSMNT_NOWIN95)
- && !(offset & pmp->pm_crbomask)
- && offset);
- return 0;
-}
-
-/*
- * Create a unique DOS name in dvp
- */
-int
-uniqdosname(dep, cnp, cp)
- struct denode *dep;
- struct componentname *cnp;
- u_char *cp;
-{
- struct msdosfsmount *pmp = dep->de_pmp;
- struct direntry *dentp;
- int gen;
- int blsize;
- u_long cn;
- daddr_t bn;
- struct buf *bp;
- int error;
-
- if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
- return (unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
- cnp->cn_namelen, 0,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
- pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu) ?
- 0 : EINVAL);
-
- for (gen = 1;; gen++) {
- /*
- * Generate DOS name with generation number
- */
- if (!unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
- cnp->cn_namelen, gen,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE, pmp->pm_u2d,
- pmp->pm_flags & MSDOSFSMNT_ULTABLE, pmp->pm_lu))
- return gen == 1 ? EINVAL : EEXIST;
-
- /*
- * Now look for a dir entry with this exact name
- */
- for (cn = error = 0; !error; cn++) {
- if ((error = pcbmap(dep, cn, &bn, 0, &blsize)) != 0) {
- if (error == E2BIG) /* EOF reached and not found */
- return 0;
- return error;
- }
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return error;
- }
- for (dentp = (struct direntry *)bp->b_data;
- (char *)dentp < bp->b_data + blsize;
- dentp++) {
- if (dentp->deName[0] == SLOT_EMPTY) {
- /*
- * Last used entry and not found
- */
- brelse(bp);
- return 0;
- }
- /*
- * Ignore volume labels and Win95 entries
- */
- if (dentp->deAttributes & ATTR_VOLUME)
- continue;
- if (!bcmp(dentp->deName, cp, 11)) {
- error = EEXIST;
- break;
- }
- }
- brelse(bp);
- }
- }
-}
-
-/*
- * Find any Win'95 long filename entry in directory dep
- */
-int
-findwin95(dep)
- struct denode *dep;
-{
- struct msdosfsmount *pmp = dep->de_pmp;
- struct direntry *dentp;
- int blsize, win95;
- u_long cn;
- daddr_t bn;
- struct buf *bp;
-
- win95 = 1;
- /*
- * Read through the directory looking for Win'95 entries
- * Note: Error currently handled just as EOF XXX
- */
- for (cn = 0;; cn++) {
- if (pcbmap(dep, cn, &bn, 0, &blsize))
- return (win95);
- if (bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp)) {
- brelse(bp);
- return (win95);
- }
- for (dentp = (struct direntry *)bp->b_data;
- (char *)dentp < bp->b_data + blsize;
- dentp++) {
- if (dentp->deName[0] == SLOT_EMPTY) {
- /*
- * Last used entry and not found
- */
- brelse(bp);
- return (win95);
- }
- if (dentp->deName[0] == SLOT_DELETED) {
- /*
- * Ignore deleted files
- * Note: might be an indication of Win'95 anyway XXX
- */
- continue;
- }
- if (dentp->deAttributes == ATTR_WIN95) {
- brelse(bp);
- return 1;
- }
- win95 = 0;
- }
- brelse(bp);
- }
-}
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
deleted file mode 100644
index abaeb7f..0000000
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ /dev/null
@@ -1,964 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/stat.h> /* defines ALLPERMS */
-#include <sys/mutex.h>
-
-#include <msdosfs/bpb.h>
-#include <msdosfs/bootsect.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
-
-#define MSDOSFS_DFLTBSIZE 4096
-
-#if 1 /*def PC98*/
-/*
- * XXX - The boot signature formatted by NEC PC-98 DOS looks like a
- * garbage or a random value :-{
- * If you want to use that broken-signatured media, define the
- * following symbol even though PC/AT.
- * (ex. mount PC-98 DOS formatted FD on PC/AT)
- */
-#define MSDOSFS_NOCHECKSIG
-#endif
-
-MALLOC_DEFINE(M_MSDOSFSMNT, "MSDOSFS mount", "MSDOSFS mount structure");
-static MALLOC_DEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOSFS file allocation table");
-
-static int update_mp __P((struct mount *mp, struct msdosfs_args *argp));
-static int mountmsdosfs __P((struct vnode *devvp, struct mount *mp,
- struct proc *p, struct msdosfs_args *argp));
-static int msdosfs_fhtovp __P((struct mount *, struct fid *,
- struct vnode **));
-static int msdosfs_mount __P((struct mount *, char *, caddr_t,
- struct nameidata *, struct proc *));
-static int msdosfs_root __P((struct mount *, struct vnode **));
-static int msdosfs_statfs __P((struct mount *, struct statfs *,
- struct proc *));
-static int msdosfs_sync __P((struct mount *, int, struct ucred *,
- struct proc *));
-static int msdosfs_unmount __P((struct mount *, int, struct proc *));
-static int msdosfs_vptofh __P((struct vnode *, struct fid *));
-
-static int
-update_mp(mp, argp)
- struct mount *mp;
- struct msdosfs_args *argp;
-{
- struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
- int error;
-
- pmp->pm_gid = argp->gid;
- pmp->pm_uid = argp->uid;
- pmp->pm_mask = argp->mask & ALLPERMS;
- pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT;
- if (pmp->pm_flags & MSDOSFSMNT_U2WTABLE) {
- bcopy(argp->u2w, pmp->pm_u2w, sizeof(pmp->pm_u2w));
- bcopy(argp->d2u, pmp->pm_d2u, sizeof(pmp->pm_d2u));
- bcopy(argp->u2d, pmp->pm_u2d, sizeof(pmp->pm_u2d));
- }
- if (pmp->pm_flags & MSDOSFSMNT_ULTABLE) {
- bcopy(argp->ul, pmp->pm_ul, sizeof(pmp->pm_ul));
- bcopy(argp->lu, pmp->pm_lu, sizeof(pmp->pm_lu));
- }
-
-#ifndef __FreeBSD__
- /*
- * GEMDOS knows nothing (yet) about win95
- */
- if (pmp->pm_flags & MSDOSFSMNT_GEMDOSFS)
- pmp->pm_flags |= MSDOSFSMNT_NOWIN95;
-#endif
-
- if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
- pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
- else if (!(pmp->pm_flags &
- (MSDOSFSMNT_SHORTNAME | MSDOSFSMNT_LONGNAME))) {
- struct vnode *rootvp;
-
- /*
- * Try to divine whether to support Win'95 long filenames
- */
- if (FAT32(pmp))
- pmp->pm_flags |= MSDOSFSMNT_LONGNAME;
- else {
- if ((error = msdosfs_root(mp, &rootvp)) != 0)
- return error;
- pmp->pm_flags |= findwin95(VTODE(rootvp))
- ? MSDOSFSMNT_LONGNAME
- : MSDOSFSMNT_SHORTNAME;
- vput(rootvp);
- }
- }
- return 0;
-}
-
-#ifndef __FreeBSD__
-int
-msdosfs_mountroot()
-{
- register struct mount *mp;
- struct proc *p = curproc; /* XXX */
- size_t size;
- int error;
- struct msdosfs_args args;
-
- if (root_device->dv_class != DV_DISK)
- return (ENODEV);
-
- /*
- * Get vnodes for swapdev and rootdev.
- */
- if (bdevvp(rootdev, &rootvp))
- panic("msdosfs_mountroot: can't setup rootvp");
-
- mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
- mp->mnt_op = &msdosfs_vfsops;
- mp->mnt_flag = 0;
- LIST_INIT(&mp->mnt_vnodelist);
-
- args.flags = 0;
- args.uid = 0;
- args.gid = 0;
- args.mask = 0777;
-
- if ((error = mountmsdosfs(rootvp, mp, p, &args)) != 0) {
- free(mp, M_MOUNT);
- return (error);
- }
-
- if ((error = update_mp(mp, &args)) != 0) {
- (void)msdosfs_unmount(mp, 0, p);
- free(mp, M_MOUNT);
- return (error);
- }
-
- if ((error = vfs_lock(mp)) != 0) {
- (void)msdosfs_unmount(mp, 0, p);
- free(mp, M_MOUNT);
- return (error);
- }
-
- TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mp->mnt_vnodecovered = NULLVP;
- (void) copystr("/", mp->mnt_stat.f_mntonname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
- (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void)msdosfs_statfs(mp, &mp->mnt_stat, p);
- vfs_unlock(mp);
- return (0);
-}
-#endif
-
-/*
- * mp - path - addr in user space of mount point (ie /usr or whatever)
- * data - addr in user space of mount params including the name of the block
- * special file to treat as a filesystem.
- */
-static int
-msdosfs_mount(mp, path, data, ndp, p)
- struct mount *mp;
- char *path;
- caddr_t data;
- struct nameidata *ndp;
- struct proc *p;
-{
- struct vnode *devvp; /* vnode for blk device to mount */
- struct msdosfs_args args; /* will hold data from mount request */
- /* msdosfs specific mount control block */
- struct msdosfsmount *pmp = NULL;
- size_t size;
- int error, flags;
- mode_t accessmode;
-
- error = copyin(data, (caddr_t)&args, sizeof(struct msdosfs_args));
- if (error)
- return (error);
- if (args.magic != MSDOSFS_ARGSMAGIC)
- args.flags = 0;
- /*
- * If updating, check whether changing from read-only to
- * read/write; if there is no device name, that's all we do.
- */
- if (mp->mnt_flag & MNT_UPDATE) {
- pmp = VFSTOMSDOSFS(mp);
- error = 0;
- if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_RDONLY)) {
- flags = WRITECLOSE;
- if (mp->mnt_flag & MNT_FORCE)
- flags |= FORCECLOSE;
- error = vflush(mp, 0, flags);
- }
- if (!error && (mp->mnt_flag & MNT_RELOAD))
- /* not yet implemented */
- error = EOPNOTSUPP;
- if (error)
- return (error);
- if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
- /*
- * If upgrade to read-write by non-root, then verify
- * that user has necessary permissions on the device.
- */
- if (p->p_ucred->cr_uid != 0) {
- devvp = pmp->pm_devvp;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = VOP_ACCESS(devvp, VREAD | VWRITE,
- p->p_ucred, p);
- if (error) {
- VOP_UNLOCK(devvp, 0, p);
- return (error);
- }
- VOP_UNLOCK(devvp, 0, p);
- }
- pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
- }
- if (args.fspec == 0) {
-#ifdef __notyet__ /* doesn't work correctly with current mountd XXX */
- if (args.flags & MSDOSFSMNT_MNTOPT) {
- pmp->pm_flags &= ~MSDOSFSMNT_MNTOPT;
- pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;
- if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
- pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
- }
-#endif
- /*
- * Process export requests.
- */
- return (vfs_export(mp, &args.export));
- }
- }
- /*
- * Not an update, or updating the name: look up the name
- * and verify that it refers to a sensible block device.
- */
- NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
- error = namei(ndp);
- if (error)
- return (error);
- devvp = ndp->ni_vp;
- NDFREE(ndp, NDF_ONLY_PNBUF);
-
- if (!vn_isdisk(devvp, &error)) {
- vrele(devvp);
- return (error);
- }
- /*
- * If mount by non-root, then verify that user has necessary
- * permissions on the device.
- */
- if (p->p_ucred->cr_uid != 0) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
- if (error) {
- vput(devvp);
- return (error);
- }
- VOP_UNLOCK(devvp, 0, p);
- }
- if ((mp->mnt_flag & MNT_UPDATE) == 0) {
- error = mountmsdosfs(devvp, mp, p, &args);
-#ifdef MSDOSFS_DEBUG /* only needed for the printf below */
- pmp = VFSTOMSDOSFS(mp);
-#endif
- } else {
- if (devvp != pmp->pm_devvp)
- error = EINVAL; /* XXX needs translation */
- else
- vrele(devvp);
- }
- if (error) {
- vrele(devvp);
- return (error);
- }
-
- error = update_mp(mp, &args);
- if (error) {
- msdosfs_unmount(mp, MNT_FORCE, p);
- return error;
- }
- (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void) msdosfs_statfs(mp, &mp->mnt_stat, p);
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_mount(): mp %p, pmp %p, inusemap %p\n", mp, pmp, pmp->pm_inusemap);
-#endif
- return (0);
-}
-
-static int
-mountmsdosfs(devvp, mp, p, argp)
- struct vnode *devvp;
- struct mount *mp;
- struct proc *p;
- struct msdosfs_args *argp;
-{
- struct msdosfsmount *pmp;
- struct buf *bp;
- dev_t dev = devvp->v_rdev;
-#ifndef __FreeBSD__
- struct partinfo dpart;
- int bsize = 0, dtype = 0, tmp;
-#endif
- union bootsector *bsp;
- struct byte_bpb33 *b33;
- struct byte_bpb50 *b50;
- struct byte_bpb710 *b710;
- u_int8_t SecPerClust;
- u_long clusters;
- int ronly, error;
-
- /*
- * Disallow multiple mounts of the same device.
- * Disallow mounting of a device that is currently in use
- * (except for root, which might share swap device for miniroot).
- * Flush out any old buffers remaining from a previous use.
- */
- error = vfs_mountedon(devvp);
- if (error)
- return (error);
- if (vcount(devvp) > 1 && devvp != rootvp)
- return (EBUSY);
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
- VOP_UNLOCK(devvp, 0, p);
- if (error)
- return (error);
-
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
- VOP_UNLOCK(devvp, 0, p);
- if (error)
- return (error);
-
- bp = NULL; /* both used in error_exit */
- pmp = NULL;
-
-#ifndef __FreeBSD__
- if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
- /*
- * We need the disklabel to calculate the size of a FAT entry
- * later on. Also make sure the partition contains a filesystem
- * of type FS_MSDOS. This doesn't work for floppies, so we have
- * to check for them too.
- *
- * At least some parts of the msdos fs driver seem to assume
- * that the size of a disk block will always be 512 bytes.
- * Let's check it...
- */
- error = VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart,
- FREAD, NOCRED, p);
- if (error)
- goto error_exit;
- tmp = dpart.part->p_fstype;
- dtype = dpart.disklab->d_type;
- bsize = dpart.disklab->d_secsize;
- if (bsize != 512 || (dtype!=DTYPE_FLOPPY && tmp!=FS_MSDOS)) {
- error = EINVAL;
- goto error_exit;
- }
- }
-#endif
-
- /*
- * Read the boot sector of the filesystem, and then check the
- * boot signature. If not a dos boot sector then error out.
- *
- * NOTE: 2048 is a maximum sector size in current...
- */
- error = bread(devvp, 0, 2048, NOCRED, &bp);
- if (error)
- goto error_exit;
- bp->b_flags |= B_AGE;
- bsp = (union bootsector *)bp->b_data;
- b33 = (struct byte_bpb33 *)bsp->bs33.bsBPB;
- b50 = (struct byte_bpb50 *)bsp->bs50.bsBPB;
- b710 = (struct byte_bpb710 *)bsp->bs710.bsPBP;
-
-#ifndef __FreeBSD__
- if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) {
-#endif
-#ifndef MSDOSFS_NOCHECKSIG
- if (bsp->bs50.bsBootSectSig0 != BOOTSIG0
- || bsp->bs50.bsBootSectSig1 != BOOTSIG1) {
- error = EINVAL;
- goto error_exit;
- }
-#endif
-#ifndef __FreeBSD__
- }
-#endif
-
- pmp = malloc(sizeof *pmp, M_MSDOSFSMNT, M_WAITOK | M_ZERO);
- pmp->pm_mountp = mp;
-
- /*
- * Compute several useful quantities from the bpb in the
- * bootsector. Copy in the dos 5 variant of the bpb then fix up
- * the fields that are different between dos 5 and dos 3.3.
- */
- SecPerClust = b50->bpbSecPerClust;
- pmp->pm_BytesPerSec = getushort(b50->bpbBytesPerSec);
- pmp->pm_ResSectors = getushort(b50->bpbResSectors);
- pmp->pm_FATs = b50->bpbFATs;
- pmp->pm_RootDirEnts = getushort(b50->bpbRootDirEnts);
- pmp->pm_Sectors = getushort(b50->bpbSectors);
- pmp->pm_FATsecs = getushort(b50->bpbFATsecs);
- pmp->pm_SecPerTrack = getushort(b50->bpbSecPerTrack);
- pmp->pm_Heads = getushort(b50->bpbHeads);
- pmp->pm_Media = b50->bpbMedia;
-
- /* calculate the ratio of sector size to DEV_BSIZE */
- pmp->pm_BlkPerSec = pmp->pm_BytesPerSec / DEV_BSIZE;
-
-#ifndef __FreeBSD__
- if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) {
-#endif
- /* XXX - We should probably check more values here */
- if (!pmp->pm_BytesPerSec || !SecPerClust
- || !pmp->pm_Heads || pmp->pm_Heads > 255
-#ifdef PC98
- || !pmp->pm_SecPerTrack || pmp->pm_SecPerTrack > 255) {
-#else
- || !pmp->pm_SecPerTrack || pmp->pm_SecPerTrack > 63) {
-#endif
- error = EINVAL;
- goto error_exit;
- }
-#ifndef __FreeBSD__
- }
-#endif
-
- if (pmp->pm_Sectors == 0) {
- pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs);
- pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors);
- } else {
- pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs);
- pmp->pm_HugeSectors = pmp->pm_Sectors;
- }
- if (pmp->pm_HugeSectors > 0xffffffff /
- (pmp->pm_BytesPerSec / sizeof(struct direntry)) + 1) {
- /*
- * We cannot deal currently with this size of disk
- * due to fileid limitations (see msdosfs_getattr and
- * msdosfs_readdir)
- */
- error = EINVAL;
- printf("mountmsdosfs(): disk too big, sorry\n");
- goto error_exit;
- }
-
- if (pmp->pm_RootDirEnts == 0) {
- if (bsp->bs710.bsBootSectSig2 != BOOTSIG2
- || bsp->bs710.bsBootSectSig3 != BOOTSIG3
- || pmp->pm_Sectors
- || pmp->pm_FATsecs
- || getushort(b710->bpbFSVers)) {
- error = EINVAL;
- printf("mountmsdosfs(): bad FAT32 filesystem\n");
- goto error_exit;
- }
- pmp->pm_fatmask = FAT32_MASK;
- pmp->pm_fatmult = 4;
- pmp->pm_fatdiv = 1;
- pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs);
- if (getushort(b710->bpbExtFlags) & FATMIRROR)
- pmp->pm_curfat = getushort(b710->bpbExtFlags) & FATNUM;
- else
- pmp->pm_flags |= MSDOSFS_FATMIRROR;
- } else
- pmp->pm_flags |= MSDOSFS_FATMIRROR;
-
- /*
- * Check a few values (could do some more):
- * - logical sector size: power of 2, >= block size
- * - sectors per cluster: power of 2, >= 1
- * - number of sectors: >= 1, <= size of partition
- */
- if ( (SecPerClust == 0)
- || (SecPerClust & (SecPerClust - 1))
- || (pmp->pm_BytesPerSec < DEV_BSIZE)
- || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
- || (pmp->pm_HugeSectors == 0)
- ) {
- error = EINVAL;
- goto error_exit;
- }
-
- pmp->pm_HugeSectors *= pmp->pm_BlkPerSec;
- pmp->pm_HiddenSects *= pmp->pm_BlkPerSec; /* XXX not used? */
- pmp->pm_FATsecs *= pmp->pm_BlkPerSec;
- SecPerClust *= pmp->pm_BlkPerSec;
-
- pmp->pm_fatblk = pmp->pm_ResSectors * pmp->pm_BlkPerSec;
-
- if (FAT32(pmp)) {
- pmp->pm_rootdirblk = getulong(b710->bpbRootClust);
- pmp->pm_firstcluster = pmp->pm_fatblk
- + (pmp->pm_FATs * pmp->pm_FATsecs);
- pmp->pm_fsinfo = getushort(b710->bpbFSInfo) * pmp->pm_BlkPerSec;
- } else {
- pmp->pm_rootdirblk = pmp->pm_fatblk +
- (pmp->pm_FATs * pmp->pm_FATsecs);
- pmp->pm_rootdirsize = (pmp->pm_RootDirEnts * sizeof(struct direntry)
- + DEV_BSIZE - 1)
- / DEV_BSIZE; /* in blocks */
- pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize;
- }
-
- pmp->pm_maxcluster = (pmp->pm_HugeSectors - pmp->pm_firstcluster) /
- SecPerClust + 1;
- pmp->pm_fatsize = pmp->pm_FATsecs * DEV_BSIZE; /* XXX not used? */
-
-#ifndef __FreeBSD__
- if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
- if ((pmp->pm_maxcluster <= (0xff0 - 2))
- && ((dtype == DTYPE_FLOPPY) || ((dtype == DTYPE_VNODE)
- && ((pmp->pm_Heads == 1) || (pmp->pm_Heads == 2))))
- ) {
- pmp->pm_fatmask = FAT12_MASK;
- pmp->pm_fatmult = 3;
- pmp->pm_fatdiv = 2;
- } else {
- pmp->pm_fatmask = FAT16_MASK;
- pmp->pm_fatmult = 2;
- pmp->pm_fatdiv = 1;
- }
- } else
-#endif
- if (pmp->pm_fatmask == 0) {
- if (pmp->pm_maxcluster
- <= ((CLUST_RSRVD - CLUST_FIRST) & FAT12_MASK)) {
- /*
- * This will usually be a floppy disk. This size makes
- * sure that one fat entry will not be split across
- * multiple blocks.
- */
- pmp->pm_fatmask = FAT12_MASK;
- pmp->pm_fatmult = 3;
- pmp->pm_fatdiv = 2;
- } else {
- pmp->pm_fatmask = FAT16_MASK;
- pmp->pm_fatmult = 2;
- pmp->pm_fatdiv = 1;
- }
- }
-
- clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv;
- if (pmp->pm_maxcluster >= clusters) {
- printf("Warning: number of clusters (%ld) exceeds FAT "
- "capacity (%ld)\n", pmp->pm_maxcluster + 1, clusters);
- pmp->pm_maxcluster = clusters - 1;
- }
-
-
- if (FAT12(pmp))
- pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
- else
- pmp->pm_fatblocksize = MSDOSFS_DFLTBSIZE;
-
- pmp->pm_fatblocksec = pmp->pm_fatblocksize / DEV_BSIZE;
- pmp->pm_bnshift = ffs(DEV_BSIZE) - 1;
-
- /*
- * Compute mask and shift value for isolating cluster relative byte
- * offsets and cluster numbers from a file offset.
- */
- pmp->pm_bpcluster = SecPerClust * DEV_BSIZE;
- pmp->pm_crbomask = pmp->pm_bpcluster - 1;
- pmp->pm_cnshift = ffs(pmp->pm_bpcluster) - 1;
-
- /*
- * Check for valid cluster size
- * must be a power of 2
- */
- if (pmp->pm_bpcluster ^ (1 << pmp->pm_cnshift)) {
- error = EINVAL;
- goto error_exit;
- }
-
- /*
- * Release the bootsector buffer.
- */
- brelse(bp);
- bp = NULL;
-
- /*
- * Check FSInfo.
- */
- if (pmp->pm_fsinfo) {
- struct fsinfo *fp;
-
- if ((error = bread(devvp, pmp->pm_fsinfo, fsi_size(pmp),
- NOCRED, &bp)) != 0)
- goto error_exit;
- fp = (struct fsinfo *)bp->b_data;
- if (!bcmp(fp->fsisig1, "RRaA", 4)
- && !bcmp(fp->fsisig2, "rrAa", 4)
- && !bcmp(fp->fsisig3, "\0\0\125\252", 4)
- && !bcmp(fp->fsisig4, "\0\0\125\252", 4))
- pmp->pm_nxtfree = getulong(fp->fsinxtfree);
- else
- pmp->pm_fsinfo = 0;
- brelse(bp);
- bp = NULL;
- }
-
- /*
- * Check and validate (or perhaps invalidate?) the fsinfo structure? XXX
- */
-
- /*
- * Allocate memory for the bitmap of allocated clusters, and then
- * fill it in.
- */
- pmp->pm_inusemap = malloc(((pmp->pm_maxcluster + N_INUSEBITS - 1)
- / N_INUSEBITS)
- * sizeof(*pmp->pm_inusemap),
- M_MSDOSFSFAT, M_WAITOK);
-
- /*
- * fillinusemap() needs pm_devvp.
- */
- pmp->pm_dev = dev;
- pmp->pm_devvp = devvp;
-
- /*
- * Have the inuse map filled in.
- */
- if ((error = fillinusemap(pmp)) != 0)
- goto error_exit;
-
- /*
- * If they want fat updates to be synchronous then let them suffer
- * the performance degradation in exchange for the on disk copy of
- * the fat being correct just about all the time. I suppose this
- * would be a good thing to turn on if the kernel is still flakey.
- */
- if (mp->mnt_flag & MNT_SYNCHRONOUS)
- pmp->pm_flags |= MSDOSFSMNT_WAITONFAT;
-
- /*
- * Finish up.
- */
- if (ronly)
- pmp->pm_flags |= MSDOSFSMNT_RONLY;
- else
- pmp->pm_fmod = 1;
- mp->mnt_data = (qaddr_t) pmp;
- mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
- mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
- mp->mnt_flag |= MNT_LOCAL;
- devvp->v_rdev->si_mountpoint = mp;
-
- return 0;
-
-error_exit:
- if (bp)
- brelse(bp);
- (void) VOP_CLOSE(devvp, ronly ? FREAD : FREAD | FWRITE, NOCRED, p);
- if (pmp) {
- if (pmp->pm_inusemap)
- free(pmp->pm_inusemap, M_MSDOSFSFAT);
- free(pmp, M_MSDOSFSMNT);
- mp->mnt_data = (qaddr_t)0;
- }
- return (error);
-}
-
-/*
- * Unmount the filesystem described by mp.
- */
-static int
-msdosfs_unmount(mp, mntflags, p)
- struct mount *mp;
- int mntflags;
- struct proc *p;
-{
- struct msdosfsmount *pmp;
- int error, flags;
-
- flags = 0;
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
- error = vflush(mp, 0, flags);
- if (error)
- return error;
- pmp = VFSTOMSDOSFS(mp);
- pmp->pm_devvp->v_rdev->si_mountpoint = NULL;
-#ifdef MSDOSFS_DEBUG
- {
- struct vnode *vp = pmp->pm_devvp;
-
- printf("msdosfs_umount(): just before calling VOP_CLOSE()\n");
- printf("flag %08lx, usecount %d, writecount %d, holdcnt %ld\n",
- vp->v_flag, vp->v_usecount, vp->v_writecount, vp->v_holdcnt);
- printf("id %lu, mount %p, op %p\n",
- vp->v_id, vp->v_mount, vp->v_op);
- printf("freef %p, freeb %p, mount %p\n",
- TAILQ_NEXT(vp, v_freelist), vp->v_freelist.tqe_prev,
- vp->v_mount);
- printf("cleanblkhd %p, dirtyblkhd %p, numoutput %ld, type %d\n",
- TAILQ_FIRST(&vp->v_cleanblkhd),
- TAILQ_FIRST(&vp->v_dirtyblkhd),
- vp->v_numoutput, vp->v_type);
- printf("union %p, tag %d, data[0] %08x, data[1] %08x\n",
- vp->v_socket, vp->v_tag,
- ((u_int *)vp->v_data)[0],
- ((u_int *)vp->v_data)[1]);
- }
-#endif
- error = VOP_CLOSE(pmp->pm_devvp,
- (pmp->pm_flags&MSDOSFSMNT_RONLY) ? FREAD : FREAD | FWRITE,
- NOCRED, p);
- vrele(pmp->pm_devvp);
- free(pmp->pm_inusemap, M_MSDOSFSFAT);
- free(pmp, M_MSDOSFSMNT);
- mp->mnt_data = (qaddr_t)0;
- mp->mnt_flag &= ~MNT_LOCAL;
- return (error);
-}
-
-static int
-msdosfs_root(mp, vpp)
- struct mount *mp;
- struct vnode **vpp;
-{
- struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
- struct denode *ndep;
- int error;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_root(); mp %p, pmp %p\n", mp, pmp);
-#endif
- error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, &ndep);
- if (error)
- return (error);
- *vpp = DETOV(ndep);
- return (0);
-}
-
-static int
-msdosfs_statfs(mp, sbp, p)
- struct mount *mp;
- struct statfs *sbp;
- struct proc *p;
-{
- struct msdosfsmount *pmp;
-
- pmp = VFSTOMSDOSFS(mp);
- sbp->f_bsize = pmp->pm_bpcluster;
- sbp->f_iosize = pmp->pm_bpcluster;
- sbp->f_blocks = pmp->pm_maxcluster + 1;
- sbp->f_bfree = pmp->pm_freeclustercount;
- sbp->f_bavail = pmp->pm_freeclustercount;
- sbp->f_files = pmp->pm_RootDirEnts; /* XXX */
- sbp->f_ffree = 0; /* what to put in here? */
- if (sbp != &mp->mnt_stat) {
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
- bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
- }
- strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
- return (0);
-}
-
-static int
-msdosfs_sync(mp, waitfor, cred, p)
- struct mount *mp;
- int waitfor;
- struct ucred *cred;
- struct proc *p;
-{
- struct vnode *vp, *nvp;
- struct denode *dep;
- struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
- int error, allerror = 0;
-
- /*
- * If we ever switch to not updating all of the fats all the time,
- * this would be the place to update them from the first one.
- */
- if (pmp->pm_fmod != 0) {
- if (pmp->pm_flags & MSDOSFSMNT_RONLY)
- panic("msdosfs_sync: rofs mod");
- else {
- /* update fats here */
- }
- }
- /*
- * Write back each (modified) denode.
- */
- mtx_lock(&mntvnode_mtx);
-loop:
- for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
- /*
- * If the vnode that we are about to sync is no longer
- * associated with this mount point, start over.
- */
- if (vp->v_mount != mp)
- goto loop;
-
- mtx_lock(&vp->v_interlock);
- nvp = LIST_NEXT(vp, v_mntvnodes);
- dep = VTODE(vp);
- if (vp->v_type == VNON ||
- ((dep->de_flag &
- (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0 &&
- (TAILQ_EMPTY(&vp->v_dirtyblkhd) || waitfor == MNT_LAZY))) {
- mtx_unlock(&vp->v_interlock);
- continue;
- }
- mtx_unlock(&mntvnode_mtx);
- error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
- if (error) {
- mtx_lock(&mntvnode_mtx);
- if (error == ENOENT)
- goto loop;
- continue;
- }
- error = VOP_FSYNC(vp, cred, waitfor, p);
- if (error)
- allerror = error;
- VOP_UNLOCK(vp, 0, p);
- vrele(vp);
- mtx_lock(&mntvnode_mtx);
- }
- mtx_unlock(&mntvnode_mtx);
-
- /*
- * Flush filesystem control info.
- */
- if (waitfor != MNT_LAZY) {
- vn_lock(pmp->pm_devvp, LK_EXCLUSIVE | LK_RETRY, p);
- error = VOP_FSYNC(pmp->pm_devvp, cred, waitfor, p);
- if (error)
- allerror = error;
- VOP_UNLOCK(pmp->pm_devvp, 0, p);
- }
- return (allerror);
-}
-
-static int
-msdosfs_fhtovp(mp, fhp, vpp)
- struct mount *mp;
- struct fid *fhp;
- struct vnode **vpp;
-{
- struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
- struct defid *defhp = (struct defid *) fhp;
- struct denode *dep;
- int error;
-
- error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs, &dep);
- if (error) {
- *vpp = NULLVP;
- return (error);
- }
- *vpp = DETOV(dep);
- return (0);
-}
-
-static int
-msdosfs_vptofh(vp, fhp)
- struct vnode *vp;
- struct fid *fhp;
-{
- struct denode *dep;
- struct defid *defhp;
-
- dep = VTODE(vp);
- defhp = (struct defid *)fhp;
- defhp->defid_len = sizeof(struct defid);
- defhp->defid_dirclust = dep->de_dirclust;
- defhp->defid_dirofs = dep->de_diroffset;
- /* defhp->defid_gen = dep->de_gen; */
- return (0);
-}
-
-static struct vfsops msdosfs_vfsops = {
- msdosfs_mount,
- vfs_stdstart,
- msdosfs_unmount,
- msdosfs_root,
- vfs_stdquotactl,
- msdosfs_statfs,
- msdosfs_sync,
- vfs_stdvget,
- msdosfs_fhtovp,
- vfs_stdcheckexp,
- msdosfs_vptofh,
- msdosfs_init,
- msdosfs_uninit,
- vfs_stdextattrctl,
-};
-
-VFS_SET(msdosfs_vfsops, msdos, 0);
diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c
deleted file mode 100644
index b942d30..0000000
--- a/sys/msdosfs/msdosfs_vnops.c
+++ /dev/null
@@ -1,1905 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/resourcevar.h> /* defines plimit structure in proc struct */
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <sys/signalvar.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vnode_pager.h>
-
-#include <machine/mutex.h>
-
-#include <msdosfs/bpb.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/denode.h>
-#include <msdosfs/msdosfsmount.h>
-#include <msdosfs/fat.h>
-
-#define DOS_FILESIZE_MAX 0xffffffff
-
-/*
- * Prototypes for MSDOSFS vnode operations
- */
-static int msdosfs_create __P((struct vop_create_args *));
-static int msdosfs_mknod __P((struct vop_mknod_args *));
-static int msdosfs_close __P((struct vop_close_args *));
-static int msdosfs_access __P((struct vop_access_args *));
-static int msdosfs_getattr __P((struct vop_getattr_args *));
-static int msdosfs_setattr __P((struct vop_setattr_args *));
-static int msdosfs_read __P((struct vop_read_args *));
-static int msdosfs_write __P((struct vop_write_args *));
-static int msdosfs_fsync __P((struct vop_fsync_args *));
-static int msdosfs_remove __P((struct vop_remove_args *));
-static int msdosfs_link __P((struct vop_link_args *));
-static int msdosfs_rename __P((struct vop_rename_args *));
-static int msdosfs_mkdir __P((struct vop_mkdir_args *));
-static int msdosfs_rmdir __P((struct vop_rmdir_args *));
-static int msdosfs_symlink __P((struct vop_symlink_args *));
-static int msdosfs_readdir __P((struct vop_readdir_args *));
-static int msdosfs_bmap __P((struct vop_bmap_args *));
-static int msdosfs_strategy __P((struct vop_strategy_args *));
-static int msdosfs_print __P((struct vop_print_args *));
-static int msdosfs_pathconf __P((struct vop_pathconf_args *ap));
-
-/*
- * Some general notes:
- *
- * In the ufs filesystem the inodes, superblocks, and indirect blocks are
- * read/written using the vnode for the filesystem. Blocks that represent
- * the contents of a file are read/written using the vnode for the file
- * (including directories when they are read/written as files). This
- * presents problems for the dos filesystem because data that should be in
- * an inode (if dos had them) resides in the directory itself. Since we
- * must update directory entries without the benefit of having the vnode
- * for the directory we must use the vnode for the filesystem. This means
- * that when a directory is actually read/written (via read, write, or
- * readdir, or seek) we must use the vnode for the filesystem instead of
- * the vnode for the directory as would happen in ufs. This is to insure we
- * retreive the correct block from the buffer cache since the hash value is
- * based upon the vnode address and the desired block number.
- */
-
-/*
- * Create a regular file. On entry the directory to contain the file being
- * created is locked. We must release before we return. We must also free
- * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or
- * only if the SAVESTART bit in cn_flags is clear on success.
- */
-static int
-msdosfs_create(ap)
- struct vop_create_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap;
-{
- struct componentname *cnp = ap->a_cnp;
- struct denode ndirent;
- struct denode *dep;
- struct denode *pdep = VTODE(ap->a_dvp);
- struct timespec ts;
- int error;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap);
-#endif
-
- /*
- * If this is the root directory and there is no space left we
- * can't do anything. This is because the root directory can not
- * change size.
- */
- if (pdep->de_StartCluster == MSDOSFSROOT
- && pdep->de_fndoffset >= pdep->de_FileSize) {
- error = ENOSPC;
- goto bad;
- }
-
- /*
- * Create a directory entry for the file, then call createde() to
- * have it installed. NOTE: DOS files are always executable. We
- * use the absence of the owner write bit to make the file
- * readonly.
- */
-#ifdef DIAGNOSTIC
- if ((cnp->cn_flags & HASBUF) == 0)
- panic("msdosfs_create: no name");
-#endif
- bzero(&ndirent, sizeof(ndirent));
- error = uniqdosname(pdep, cnp, ndirent.de_Name);
- if (error)
- goto bad;
-
- ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ?
- ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY;
- ndirent.de_LowerCase = 0;
- ndirent.de_StartCluster = 0;
- ndirent.de_FileSize = 0;
- ndirent.de_dev = pdep->de_dev;
- ndirent.de_devvp = pdep->de_devvp;
- ndirent.de_pmp = pdep->de_pmp;
- ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
- getnanotime(&ts);
- DETIMES(&ndirent, &ts, &ts, &ts);
- error = createde(&ndirent, pdep, &dep, cnp);
- if (error)
- goto bad;
- *ap->a_vpp = DETOV(dep);
- return (0);
-
-bad:
- return (error);
-}
-
-static int
-msdosfs_mknod(ap)
- struct vop_mknod_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap;
-{
-
- switch (ap->a_vap->va_type) {
- case VDIR:
- return (msdosfs_mkdir((struct vop_mkdir_args *)ap));
- break;
-
- case VREG:
- return (msdosfs_create((struct vop_create_args *)ap));
- break;
-
- default:
- return (EINVAL);
- }
- /* NOTREACHED */
-}
-
-static int
-msdosfs_close(ap)
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(vp);
- struct timespec ts;
-
- mtx_lock(&vp->v_interlock);
- if (vp->v_usecount > 1) {
- getnanotime(&ts);
- DETIMES(dep, &ts, &ts, &ts);
- }
- mtx_unlock(&vp->v_interlock);
- return 0;
-}
-
-static int
-msdosfs_access(ap)
- struct vop_access_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(ap->a_vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- mode_t file_mode, mode = ap->a_mode;
-
- file_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));
- file_mode &= pmp->pm_mask;
-
- /*
- * Disallow write attempts on read-only file systems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the file system.
- */
- if (mode & VWRITE) {
- switch (vp->v_type) {
- case VDIR:
- case VLNK:
- case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
- default:
- break;
- }
- }
-
- return (vaccess(vp->v_type, file_mode, pmp->pm_uid, pmp->pm_gid,
- ap->a_mode, ap->a_cred, NULL));
-}
-
-static int
-msdosfs_getattr(ap)
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- struct denode *dep = VTODE(ap->a_vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- struct vattr *vap = ap->a_vap;
- mode_t mode;
- struct timespec ts;
- u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);
- u_long fileid;
-
- getnanotime(&ts);
- DETIMES(dep, &ts, &ts, &ts);
- vap->va_fsid = dev2udev(dep->de_dev);
- /*
- * The following computation of the fileid must be the same as that
- * used in msdosfs_readdir() to compute d_fileno. If not, pwd
- * doesn't work.
- */
- if (dep->de_Attributes & ATTR_DIRECTORY) {
- fileid = cntobn(pmp, dep->de_StartCluster) * dirsperblk;
- if (dep->de_StartCluster == MSDOSFSROOT)
- fileid = 1;
- } else {
- fileid = cntobn(pmp, dep->de_dirclust) * dirsperblk;
- if (dep->de_dirclust == MSDOSFSROOT)
- fileid = roottobn(pmp, 0) * dirsperblk;
- fileid += dep->de_diroffset / sizeof(struct direntry);
- }
- vap->va_fileid = fileid;
- if ((dep->de_Attributes & ATTR_READONLY) == 0)
- mode = S_IRWXU|S_IRWXG|S_IRWXO;
- else
- mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
- vap->va_mode = mode & pmp->pm_mask;
- vap->va_uid = pmp->pm_uid;
- vap->va_gid = pmp->pm_gid;
- vap->va_nlink = 1;
- vap->va_rdev = 0;
- vap->va_size = dep->de_FileSize;
- dos2unixtime(dep->de_MDate, dep->de_MTime, 0, &vap->va_mtime);
- if (pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
- dos2unixtime(dep->de_ADate, 0, 0, &vap->va_atime);
- dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun, &vap->va_ctime);
- } else {
- vap->va_atime = vap->va_mtime;
- vap->va_ctime = vap->va_mtime;
- }
- vap->va_flags = 0;
- if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
- vap->va_flags |= SF_ARCHIVED;
- vap->va_gen = 0;
- vap->va_blocksize = pmp->pm_bpcluster;
- vap->va_bytes =
- (dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask;
- vap->va_type = ap->a_vp->v_type;
- vap->va_filerev = dep->de_modrev;
- return (0);
-}
-
-static int
-msdosfs_setattr(ap)
- struct vop_setattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(ap->a_vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- struct vattr *vap = ap->a_vap;
- struct ucred *cred = ap->a_cred;
- int error = 0;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_setattr(): vp %p, vap %p, cred %p, p %p\n",
- ap->a_vp, vap, cred, ap->a_p);
-#endif
-
- /*
- * Check for unsettable attributes.
- */
- if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
- (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
- (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
- (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_setattr(): returning EINVAL\n");
- printf(" va_type %d, va_nlink %x, va_fsid %lx, va_fileid %lx\n",
- vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
- printf(" va_blocksize %lx, va_rdev %x, va_bytes %qx, va_gen %lx\n",
- vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
- printf(" va_uid %x, va_gid %x\n",
- vap->va_uid, vap->va_gid);
-#endif
- return (EINVAL);
- }
- if (vap->va_flags != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
- return (error);
- /*
- * We are very inconsistent about handling unsupported
- * attributes. We ignored the access time and the
- * read and execute bits. We were strict for the other
- * attributes.
- *
- * Here we are strict, stricter than ufs in not allowing
- * users to attempt to set SF_SETTABLE bits or anyone to
- * set unsupported bits. However, we ignore attempts to
- * set ATTR_ARCHIVE for directories `cp -pr' from a more
- * sensible file system attempts it a lot.
- */
- if (cred->cr_uid != 0) {
- if (vap->va_flags & SF_SETTABLE)
- return EPERM;
- }
- if (vap->va_flags & ~SF_ARCHIVED)
- return EOPNOTSUPP;
- if (vap->va_flags & SF_ARCHIVED)
- dep->de_Attributes &= ~ATTR_ARCHIVE;
- else if (!(dep->de_Attributes & ATTR_DIRECTORY))
- dep->de_Attributes |= ATTR_ARCHIVE;
- dep->de_flag |= DE_MODIFIED;
- }
-
- if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
- uid_t uid;
- gid_t gid;
-
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- uid = vap->va_uid;
- if (uid == (uid_t)VNOVAL)
- uid = pmp->pm_uid;
- gid = vap->va_gid;
- if (gid == (gid_t)VNOVAL)
- gid = pmp->pm_gid;
- if ((cred->cr_uid != pmp->pm_uid || uid != pmp->pm_uid ||
- (gid != pmp->pm_gid && !groupmember(gid, cred))) &&
- (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
- return error;
- if (uid != pmp->pm_uid || gid != pmp->pm_gid)
- return EINVAL;
- }
-
- if (vap->va_size != VNOVAL) {
- /*
- * Disallow write attempts on read-only file systems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the file system.
- */
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- /* NOT REACHED */
- case VLNK:
- case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
- default:
- break;
- }
- error = detrunc(dep, vap->va_size, 0, cred, ap->a_p);
- if (error)
- return error;
- }
- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)) &&
- ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
- (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p))))
- return (error);
- if (vp->v_type != VDIR) {
- if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
- vap->va_atime.tv_sec != VNOVAL)
- unix2dostime(&vap->va_atime, &dep->de_ADate, NULL, NULL);
- if (vap->va_mtime.tv_sec != VNOVAL)
- unix2dostime(&vap->va_mtime, &dep->de_MDate, &dep->de_MTime, NULL);
- dep->de_Attributes |= ATTR_ARCHIVE;
- dep->de_flag |= DE_MODIFIED;
- }
- }
- /*
- * DOS files only have the ability to have their writability
- * attribute set, so we use the owner write bit to set the readonly
- * attribute.
- */
- if (vap->va_mode != (mode_t)VNOVAL) {
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- if (cred->cr_uid != pmp->pm_uid &&
- (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
- return (error);
- if (vp->v_type != VDIR) {
- /* We ignore the read and execute bits. */
- if (vap->va_mode & VWRITE)
- dep->de_Attributes &= ~ATTR_READONLY;
- else
- dep->de_Attributes |= ATTR_READONLY;
- dep->de_flag |= DE_MODIFIED;
- }
- }
- return (deupdat(dep, 1));
-}
-
-static int
-msdosfs_read(ap)
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- int error = 0;
- int blsize;
- int isadir;
- int orig_resid;
- u_int n;
- u_long diff;
- u_long on;
- daddr_t lbn;
- daddr_t rablock;
- int rasize;
- int seqcount;
- struct buf *bp;
- struct vnode *vp = ap->a_vp;
- struct denode *dep = VTODE(vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- struct uio *uio = ap->a_uio;
-
- if (uio->uio_offset < 0)
- return (EINVAL);
-
- if ((uoff_t)uio->uio_offset > DOS_FILESIZE_MAX)
- return (0);
- /*
- * If they didn't ask for any data, then we are done.
- */
- orig_resid = uio->uio_resid;
- if (orig_resid <= 0)
- return (0);
-
- seqcount = ap->a_ioflag >> 16;
-
- isadir = dep->de_Attributes & ATTR_DIRECTORY;
- do {
- if (uio->uio_offset >= dep->de_FileSize)
- break;
- lbn = de_cluster(pmp, uio->uio_offset);
- /*
- * If we are operating on a directory file then be sure to
- * do i/o with the vnode for the filesystem instead of the
- * vnode for the directory.
- */
- if (isadir) {
- /* convert cluster # to block # */
- error = pcbmap(dep, lbn, &lbn, 0, &blsize);
- if (error == E2BIG) {
- error = EINVAL;
- break;
- } else if (error)
- break;
- error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
- } else {
- blsize = pmp->pm_bpcluster;
- rablock = lbn + 1;
- if (seqcount > 1 &&
- de_cn2off(pmp, rablock) < dep->de_FileSize) {
- rasize = pmp->pm_bpcluster;
- error = breadn(vp, lbn, blsize,
- &rablock, &rasize, 1, NOCRED, &bp);
- } else {
- error = bread(vp, lbn, blsize, NOCRED, &bp);
- }
- }
- if (error) {
- brelse(bp);
- break;
- }
- on = uio->uio_offset & pmp->pm_crbomask;
- diff = pmp->pm_bpcluster - on;
- n = diff > uio->uio_resid ? uio->uio_resid : diff;
- diff = dep->de_FileSize - uio->uio_offset;
- if (diff < n)
- n = diff;
- diff = blsize - bp->b_resid;
- if (diff < n)
- n = diff;
- error = uiomove(bp->b_data + on, (int) n, uio);
- brelse(bp);
- } while (error == 0 && uio->uio_resid > 0 && n != 0);
- if (!isadir && (error == 0 || uio->uio_resid != orig_resid) &&
- (vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
- dep->de_flag |= DE_ACCESS;
- return (error);
-}
-
-/*
- * Write data to a file or directory.
- */
-static int
-msdosfs_write(ap)
- struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- int n;
- int croffset;
- int resid;
- u_long osize;
- int error = 0;
- u_long count;
- daddr_t bn, lastcn;
- struct buf *bp;
- int ioflag = ap->a_ioflag;
- struct uio *uio = ap->a_uio;
- struct proc *p = uio->uio_procp;
- struct vnode *vp = ap->a_vp;
- struct vnode *thisvp;
- struct denode *dep = VTODE(vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- struct ucred *cred = ap->a_cred;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_write(vp %p, uio %p, ioflag %x, cred %p\n",
- vp, uio, ioflag, cred);
- printf("msdosfs_write(): diroff %lu, dirclust %lu, startcluster %lu\n",
- dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster);
-#endif
-
- switch (vp->v_type) {
- case VREG:
- if (ioflag & IO_APPEND)
- uio->uio_offset = dep->de_FileSize;
- thisvp = vp;
- break;
- case VDIR:
- return EISDIR;
- default:
- panic("msdosfs_write(): bad file type");
- }
-
- if (uio->uio_offset < 0)
- return (EFBIG);
-
- if (uio->uio_resid == 0)
- return (0);
-
- /*
- * If they've exceeded their filesize limit, tell them about it.
- */
- if (p &&
- ((uoff_t)uio->uio_offset + uio->uio_resid >
- p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) {
- PROC_LOCK(p);
- psignal(p, SIGXFSZ);
- PROC_UNLOCK(p);
- return (EFBIG);
- }
-
- if ((uoff_t)uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX)
- return (EFBIG);
-
- /*
- * If the offset we are starting the write at is beyond the end of
- * the file, then they've done a seek. Unix filesystems allow
- * files with holes in them, DOS doesn't so we must fill the hole
- * with zeroed blocks.
- */
- if (uio->uio_offset > dep->de_FileSize) {
- error = deextend(dep, uio->uio_offset, cred);
- if (error)
- return (error);
- }
-
- /*
- * Remember some values in case the write fails.
- */
- 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);
- error = extendfile(dep, count, NULL, NULL, 0);
- if (error && (error != ENOSPC || (ioflag & IO_UNIT)))
- goto errexit;
- lastcn = dep->de_fc[FC_LASTFC].fc_frcn;
- } else
- lastcn = de_clcount(pmp, osize) - 1;
-
- do {
- if (de_cluster(pmp, uio->uio_offset) > lastcn) {
- error = ENOSPC;
- 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) {
- dep->de_FileSize = uio->uio_offset + n;
- /* The object size needs to be set before buffer is allocated */
- vnode_pager_setsize(vp, dep->de_FileSize);
- }
-
- bn = de_cluster(pmp, uio->uio_offset);
- if ((uio->uio_offset & pmp->pm_crbomask) == 0
- && (de_cluster(pmp, uio->uio_offset + uio->uio_resid)
- > de_cluster(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 (bp->b_blkno == bp->b_lblkno) {
- error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno,
- 0, 0);
- if (error)
- 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 read it in.
- */
- error = bread(thisvp, bn, pmp->pm_bpcluster, cred, &bp);
- if (error) {
- brelse(bp);
- break;
- }
- }
-
- /*
- * Should these vnode_pager_* functions be done on dir
- * files?
- */
-
- /*
- * Copy the data from user space into the buf header.
- */
- error = uiomove(bp->b_data + croffset, n, uio);
- if (error) {
- brelse(bp);
- break;
- }
-
- /*
- * If they want this synchronous then write it and wait for
- * it. Otherwise, if on a cluster boundary write it
- * asynchronously so we can move on to the next block
- * without delay. Otherwise do a delayed write because we
- * may want to write somemore into the block later.
- */
- if (ioflag & IO_SYNC)
- (void) bwrite(bp);
- else if (n + croffset == pmp->pm_bpcluster)
- bawrite(bp);
- else
- bdwrite(bp);
- dep->de_flag |= DE_UPDATE;
- } 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.
- */
-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_SYNC)
- error = deupdat(dep, 1);
- return (error);
-}
-
-/*
- * Flush the blocks of a file to disk.
- *
- * This function is worthless for vnodes that represent directories. Maybe we
- * could just do a sync if they try an fsync on a directory file.
- */
-static int
-msdosfs_fsync(ap)
- struct vop_fsync_args /* {
- struct vnode *a_vp;
- struct ucred *a_cred;
- int a_waitfor;
- struct proc *a_p;
- } */ *ap;
-{
- struct vnode *vp = ap->a_vp;
- int s;
- struct buf *bp, *nbp;
-
- /*
- * Flush all dirty buffers associated with a vnode.
- */
-loop:
- s = splbio();
- for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
- nbp = TAILQ_NEXT(bp, b_vnbufs);
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
- continue;
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("msdosfs_fsync: not dirty");
- bremfree(bp);
- splx(s);
- (void) bwrite(bp);
- goto loop;
- }
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- (void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "msdosfsn", 0);
- }
-#ifdef DIAGNOSTIC
- if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
- vprint("msdosfs_fsync: dirty", vp);
- goto loop;
- }
-#endif
- splx(s);
- return (deupdat(VTODE(vp), ap->a_waitfor == MNT_WAIT));
-}
-
-static int
-msdosfs_remove(ap)
- struct vop_remove_args /* {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- struct denode *dep = VTODE(ap->a_vp);
- struct denode *ddep = VTODE(ap->a_dvp);
- int error;
-
- if (ap->a_vp->v_type == VDIR)
- error = EPERM;
- else
- error = removede(ddep, dep);
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_remove(), dep %p, v_usecount %d\n", dep, ap->a_vp->v_usecount);
-#endif
- return (error);
-}
-
-/*
- * DOS filesystems don't know what links are.
- */
-static int
-msdosfs_link(ap)
- struct vop_link_args /* {
- struct vnode *a_tdvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- return (EOPNOTSUPP);
-}
-
-/*
- * Renames on files require moving the denode to a new hash queue since the
- * denode's location is used to compute which hash queue to put the file
- * in. Unless it is a rename in place. For example "mv a b".
- *
- * What follows is the basic algorithm:
- *
- * if (file move) {
- * if (dest file exists) {
- * remove dest file
- * }
- * if (dest and src in same directory) {
- * rewrite name in existing directory slot
- * } else {
- * write new entry in dest directory
- * update offset and dirclust in denode
- * move denode to new hash chain
- * clear old directory entry
- * }
- * } else {
- * directory move
- * if (dest directory exists) {
- * if (dest is not empty) {
- * return ENOTEMPTY
- * }
- * remove dest directory
- * }
- * if (dest and src in same directory) {
- * rewrite name in existing entry
- * } else {
- * be sure dest is not a child of src directory
- * write entry in dest directory
- * update "." and ".." in moved directory
- * clear old directory entry for moved directory
- * }
- * }
- *
- * On entry:
- * source's parent directory is unlocked
- * source file or directory is unlocked
- * destination's parent directory is locked
- * destination file or directory is locked if it exists
- *
- * On exit:
- * all denodes should be released
- */
-static int
-msdosfs_rename(ap)
- struct vop_rename_args /* {
- struct vnode *a_fdvp;
- struct vnode *a_fvp;
- struct componentname *a_fcnp;
- struct vnode *a_tdvp;
- struct vnode *a_tvp;
- struct componentname *a_tcnp;
- } */ *ap;
-{
- struct vnode *tdvp = ap->a_tdvp;
- struct vnode *fvp = ap->a_fvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tvp = ap->a_tvp;
- struct componentname *tcnp = ap->a_tcnp;
- struct componentname *fcnp = ap->a_fcnp;
- struct proc *p = fcnp->cn_proc;
- struct denode *ip, *xp, *dp, *zp;
- u_char toname[11], oldname[11];
- u_long from_diroffset, to_diroffset;
- u_char to_count;
- int doingdirectory = 0, newparent = 0;
- int error;
- u_long cn;
- daddr_t bn;
- struct denode *fddep; /* from file's parent directory */
- struct denode *fdep; /* from file or directory */
- struct denode *tddep; /* to file's parent directory */
- struct denode *tdep; /* to file or directory */
- struct msdosfsmount *pmp;
- struct direntry *dotdotp;
- struct buf *bp;
-
- fddep = VTODE(ap->a_fdvp);
- fdep = VTODE(ap->a_fvp);
- tddep = VTODE(ap->a_tdvp);
- tdep = tvp ? VTODE(tvp) : NULL;
- pmp = fddep->de_pmp;
-
- pmp = VFSTOMSDOSFS(fdvp->v_mount);
-
-#ifdef DIAGNOSTIC
- if ((tcnp->cn_flags & HASBUF) == 0 ||
- (fcnp->cn_flags & HASBUF) == 0)
- panic("msdosfs_rename: no name");
-#endif
- /*
- * Check for cross-device rename.
- */
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount))) {
- error = EXDEV;
-abortit:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
- vrele(fvp);
- return (error);
- }
-
- /*
- * If source and dest are the same, do nothing.
- */
- if (tvp == fvp) {
- error = 0;
- goto abortit;
- }
-
- error = vn_lock(fvp, LK_EXCLUSIVE, p);
- if (error)
- goto abortit;
- dp = VTODE(fdvp);
- ip = VTODE(fvp);
-
- /*
- * Be sure we are not renaming ".", "..", or an alias of ".". This
- * leads to a crippled directory tree. It's pretty tough to do a
- * "ls" or "pwd" with the "." directory entry missing, and "cd .."
- * doesn't work if the ".." entry is missing.
- */
- if (ip->de_Attributes & ATTR_DIRECTORY) {
- /*
- * Avoid ".", "..", and aliases of "." for obvious reasons.
- */
- if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
- dp == ip ||
- (fcnp->cn_flags & ISDOTDOT) ||
- (tcnp->cn_flags & ISDOTDOT) ||
- (ip->de_flag & DE_RENAME)) {
- VOP_UNLOCK(fvp, 0, p);
- error = EINVAL;
- goto abortit;
- }
- ip->de_flag |= DE_RENAME;
- doingdirectory++;
- }
-
- /*
- * When the target exists, both the directory
- * and target vnodes are returned locked.
- */
- dp = VTODE(tdvp);
- xp = tvp ? VTODE(tvp) : NULL;
- /*
- * Remember direntry place to use for destination
- */
- to_diroffset = dp->de_fndoffset;
- to_count = dp->de_fndcnt;
-
- /*
- * If ".." must be changed (ie the directory gets a new
- * parent) then the source directory must not be in the
- * directory heirarchy above the target, as this would
- * orphan everything below the source directory. Also
- * the user must have write permission in the source so
- * as to be able to change "..". We must repeat the call
- * to namei, as the parent directory is unlocked by the
- * call to doscheckpath().
- */
- error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
- VOP_UNLOCK(fvp, 0, p);
- if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
- newparent = 1;
- if (doingdirectory && newparent) {
- if (error) /* write access check above */
- goto bad;
- if (xp != NULL)
- vput(tvp);
- /*
- * doscheckpath() vput()'s dp,
- * so we have to do a relookup afterwards
- */
- error = doscheckpath(ip, dp);
- if (error)
- goto out;
- if ((tcnp->cn_flags & SAVESTART) == 0)
- panic("msdosfs_rename: lost to startdir");
- error = relookup(tdvp, &tvp, tcnp);
- if (error)
- goto out;
- dp = VTODE(tdvp);
- xp = tvp ? VTODE(tvp) : NULL;
- }
-
- if (xp != NULL) {
- /*
- * Target must be empty if a directory and have no links
- * to it. Also, ensure source and target are compatible
- * (both directories, or both not directories).
- */
- if (xp->de_Attributes & ATTR_DIRECTORY) {
- if (!dosdirempty(xp)) {
- error = ENOTEMPTY;
- goto bad;
- }
- if (!doingdirectory) {
- error = ENOTDIR;
- goto bad;
- }
- cache_purge(tdvp);
- } else if (doingdirectory) {
- error = EISDIR;
- goto bad;
- }
- error = removede(dp, xp);
- if (error)
- goto bad;
- vput(tvp);
- xp = NULL;
- }
-
- /*
- * Convert the filename in tcnp into a dos filename. We copy this
- * into the denode and directory entry for the destination
- * file/directory.
- */
- error = uniqdosname(VTODE(tdvp), tcnp, toname);
- if (error)
- goto abortit;
-
- /*
- * Since from wasn't locked at various places above,
- * have to do a relookup here.
- */
- fcnp->cn_flags &= ~MODMASK;
- fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
- if ((fcnp->cn_flags & SAVESTART) == 0)
- panic("msdosfs_rename: lost from startdir");
- if (!newparent)
- VOP_UNLOCK(tdvp, 0, p);
- if (relookup(fdvp, &fvp, fcnp) == 0)
- vrele(fdvp);
- if (fvp == NULL) {
- /*
- * From name has disappeared.
- */
- if (doingdirectory)
- panic("rename: lost dir entry");
- vrele(ap->a_fvp);
- if (newparent)
- VOP_UNLOCK(tdvp, 0, p);
- vrele(tdvp);
- return 0;
- }
- xp = VTODE(fvp);
- zp = VTODE(fdvp);
- from_diroffset = zp->de_fndoffset;
-
- /*
- * Ensure that the directory entry still exists and has not
- * changed till now. If the source is a file the entry may
- * have been unlinked or renamed. In either case there is
- * no further work to be done. If the source is a directory
- * then it cannot have been rmdir'ed or renamed; this is
- * prohibited by the DE_RENAME flag.
- */
- if (xp != ip) {
- if (doingdirectory)
- panic("rename: lost dir entry");
- vrele(ap->a_fvp);
- VOP_UNLOCK(fvp, 0, p);
- if (newparent)
- VOP_UNLOCK(fdvp, 0, p);
- xp = NULL;
- } else {
- vrele(fvp);
- xp = NULL;
-
- /*
- * First write a new entry in the destination
- * directory and mark the entry in the source directory
- * as deleted. Then move the denode to the correct hash
- * chain for its new location in the filesystem. And, if
- * we moved a directory, then update its .. entry to point
- * to the new parent directory.
- */
- bcopy(ip->de_Name, oldname, 11);
- bcopy(toname, ip->de_Name, 11); /* update denode */
- dp->de_fndoffset = to_diroffset;
- dp->de_fndcnt = to_count;
- error = createde(ip, dp, (struct denode **)0, tcnp);
- if (error) {
- bcopy(oldname, ip->de_Name, 11);
- if (newparent)
- VOP_UNLOCK(fdvp, 0, p);
- VOP_UNLOCK(fvp, 0, p);
- goto bad;
- }
- ip->de_refcnt++;
- zp->de_fndoffset = from_diroffset;
- error = removede(zp, ip);
- if (error) {
- /* XXX should really panic here, fs is corrupt */
- if (newparent)
- VOP_UNLOCK(fdvp, 0, p);
- VOP_UNLOCK(fvp, 0, p);
- goto bad;
- }
- if (!doingdirectory) {
- error = pcbmap(dp, de_cluster(pmp, to_diroffset), 0,
- &ip->de_dirclust, 0);
- if (error) {
- /* XXX should really panic here, fs is corrupt */
- if (newparent)
- VOP_UNLOCK(fdvp, 0, p);
- VOP_UNLOCK(fvp, 0, p);
- goto bad;
- }
- if (ip->de_dirclust == MSDOSFSROOT)
- ip->de_diroffset = to_diroffset;
- else
- ip->de_diroffset = to_diroffset & pmp->pm_crbomask;
- }
- reinsert(ip);
- if (newparent)
- VOP_UNLOCK(fdvp, 0, p);
- }
-
- /*
- * If we moved a directory to a new parent directory, then we must
- * fixup the ".." entry in the moved directory.
- */
- if (doingdirectory && newparent) {
- cn = ip->de_StartCluster;
- if (cn == MSDOSFSROOT) {
- /* this should never happen */
- panic("msdosfs_rename(): updating .. in root directory?");
- } else
- bn = cntobn(pmp, cn);
- error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
- NOCRED, &bp);
- if (error) {
- /* XXX should really panic here, fs is corrupt */
- brelse(bp);
- VOP_UNLOCK(fvp, 0, p);
- goto bad;
- }
- dotdotp = (struct direntry *)bp->b_data + 1;
- putushort(dotdotp->deStartCluster, dp->de_StartCluster);
- if (FAT32(pmp))
- putushort(dotdotp->deHighClust, dp->de_StartCluster >> 16);
- error = bwrite(bp);
- if (error) {
- /* XXX should really panic here, fs is corrupt */
- VOP_UNLOCK(fvp, 0, p);
- goto bad;
- }
- }
-
- VOP_UNLOCK(fvp, 0, p);
-bad:
- if (xp)
- vput(tvp);
- vput(tdvp);
-out:
- ip->de_flag &= ~DE_RENAME;
- vrele(fdvp);
- vrele(fvp);
- return (error);
-
-}
-
-static struct {
- struct direntry dot;
- struct direntry dotdot;
-} dosdirtemplate = {
- { ". ", " ", /* the . entry */
- ATTR_DIRECTORY, /* file attribute */
- 0, /* reserved */
- 0, { 0, 0 }, { 0, 0 }, /* create time & date */
- { 0, 0 }, /* access date */
- { 0, 0 }, /* high bits of start cluster */
- { 210, 4 }, { 210, 4 }, /* modify time & date */
- { 0, 0 }, /* startcluster */
- { 0, 0, 0, 0 } /* filesize */
- },
- { ".. ", " ", /* the .. entry */
- ATTR_DIRECTORY, /* file attribute */
- 0, /* reserved */
- 0, { 0, 0 }, { 0, 0 }, /* create time & date */
- { 0, 0 }, /* access date */
- { 0, 0 }, /* high bits of start cluster */
- { 210, 4 }, { 210, 4 }, /* modify time & date */
- { 0, 0 }, /* startcluster */
- { 0, 0, 0, 0 } /* filesize */
- }
-};
-
-static int
-msdosfs_mkdir(ap)
- struct vop_mkdir_args /* {
- struct vnode *a_dvp;
- struvt vnode **a_vpp;
- struvt componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap;
-{
- struct componentname *cnp = ap->a_cnp;
- struct denode *dep;
- struct denode *pdep = VTODE(ap->a_dvp);
- struct direntry *denp;
- struct msdosfsmount *pmp = pdep->de_pmp;
- struct buf *bp;
- u_long newcluster, pcl;
- int bn;
- int error;
- struct denode ndirent;
- struct timespec ts;
-
- /*
- * If this is the root directory and there is no space left we
- * can't do anything. This is because the root directory can not
- * change size.
- */
- if (pdep->de_StartCluster == MSDOSFSROOT
- && pdep->de_fndoffset >= pdep->de_FileSize) {
- error = ENOSPC;
- goto bad2;
- }
-
- /*
- * Allocate a cluster to hold the about to be created directory.
- */
- error = clusteralloc(pmp, 0, 1, CLUST_EOFE, &newcluster, NULL);
- if (error)
- goto bad2;
-
- bzero(&ndirent, sizeof(ndirent));
- ndirent.de_pmp = pmp;
- ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
- getnanotime(&ts);
- DETIMES(&ndirent, &ts, &ts, &ts);
-
- /*
- * Now fill the cluster with the "." and ".." entries. And write
- * the cluster to disk. This way it is there for the parent
- * directory to be pointing at if there were a crash.
- */
- bn = cntobn(pmp, newcluster);
- /* always succeeds */
- bp = getblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0);
- bzero(bp->b_data, pmp->pm_bpcluster);
- bcopy(&dosdirtemplate, bp->b_data, sizeof dosdirtemplate);
- denp = (struct direntry *)bp->b_data;
- putushort(denp[0].deStartCluster, newcluster);
- putushort(denp[0].deCDate, ndirent.de_CDate);
- putushort(denp[0].deCTime, ndirent.de_CTime);
- denp[0].deCHundredth = ndirent.de_CHun;
- putushort(denp[0].deADate, ndirent.de_ADate);
- putushort(denp[0].deMDate, ndirent.de_MDate);
- putushort(denp[0].deMTime, ndirent.de_MTime);
- pcl = pdep->de_StartCluster;
- if (FAT32(pmp) && pcl == pmp->pm_rootdirblk)
- pcl = 0;
- putushort(denp[1].deStartCluster, pcl);
- putushort(denp[1].deCDate, ndirent.de_CDate);
- putushort(denp[1].deCTime, ndirent.de_CTime);
- denp[1].deCHundredth = ndirent.de_CHun;
- putushort(denp[1].deADate, ndirent.de_ADate);
- putushort(denp[1].deMDate, ndirent.de_MDate);
- putushort(denp[1].deMTime, ndirent.de_MTime);
- if (FAT32(pmp)) {
- putushort(denp[0].deHighClust, newcluster >> 16);
- putushort(denp[1].deHighClust, pdep->de_StartCluster >> 16);
- }
-
- error = bwrite(bp);
- if (error)
- goto bad;
-
- /*
- * Now build up a directory entry pointing to the newly allocated
- * cluster. This will be written to an empty slot in the parent
- * directory.
- */
-#ifdef DIAGNOSTIC
- if ((cnp->cn_flags & HASBUF) == 0)
- panic("msdosfs_mkdir: no name");
-#endif
- error = uniqdosname(pdep, cnp, ndirent.de_Name);
- if (error)
- goto bad;
-
- ndirent.de_Attributes = ATTR_DIRECTORY;
- ndirent.de_LowerCase = 0;
- ndirent.de_StartCluster = newcluster;
- ndirent.de_FileSize = 0;
- ndirent.de_dev = pdep->de_dev;
- ndirent.de_devvp = pdep->de_devvp;
- error = createde(&ndirent, pdep, &dep, cnp);
- if (error)
- goto bad;
- *ap->a_vpp = DETOV(dep);
- return (0);
-
-bad:
- clusterfree(pmp, newcluster, NULL);
-bad2:
- return (error);
-}
-
-static int
-msdosfs_rmdir(ap)
- struct vop_rmdir_args /* {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct vnode *dvp = ap->a_dvp;
- register struct componentname *cnp = ap->a_cnp;
- register struct denode *ip, *dp;
- struct proc *p = cnp->cn_proc;
- int error;
-
- ip = VTODE(vp);
- dp = VTODE(dvp);
-
- /*
- * Verify the directory is empty (and valid).
- * (Rmdir ".." won't be valid since
- * ".." will contain a reference to
- * the current directory and thus be
- * non-empty.)
- */
- error = 0;
- if (!dosdirempty(ip) || ip->de_flag & DE_RENAME) {
- error = ENOTEMPTY;
- goto out;
- }
- /*
- * 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 vput() on dep is done we give
- * up access and eventually msdosfs_reclaim() will be called which
- * will remove it from the denode cache.
- */
- error = removede(dp, ip);
- if (error)
- goto out;
- /*
- * This is where we decrement the link count in the parent
- * directory. Since dos filesystems don't do this we just purge
- * the name cache.
- */
- cache_purge(dvp);
- VOP_UNLOCK(dvp, 0, p);
- /*
- * Truncate the directory that is being deleted.
- */
- error = detrunc(ip, (u_long)0, IO_SYNC, cnp->cn_cred, p);
- cache_purge(vp);
-
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
-out:
- return (error);
-}
-
-/*
- * DOS filesystems don't know what symlinks are.
- */
-static int
-msdosfs_symlink(ap)
- struct vop_symlink_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- char *a_target;
- } */ *ap;
-{
- return (EOPNOTSUPP);
-}
-
-static int
-msdosfs_readdir(ap)
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_eofflag;
- int *a_ncookies;
- u_long **a_cookies;
- } */ *ap;
-{
- int error = 0;
- int diff;
- long n;
- int blsize;
- long on;
- u_long cn;
- u_long fileno;
- u_long dirsperblk;
- long bias = 0;
- daddr_t bn, lbn;
- struct buf *bp;
- struct denode *dep = VTODE(ap->a_vp);
- struct msdosfsmount *pmp = dep->de_pmp;
- struct direntry *dentp;
- struct dirent dirbuf;
- struct uio *uio = ap->a_uio;
- u_long *cookies = NULL;
- int ncookies = 0;
- off_t offset, off;
- int chksum = -1;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n",
- ap->a_vp, uio, ap->a_cred, ap->a_eofflag);
-#endif
-
- /*
- * msdosfs_readdir() won't operate properly on regular files since
- * it does i/o only with the the filesystem vnode, and hence can
- * retrieve the wrong block from the buffer cache for a plain file.
- * So, fail attempts to readdir() on a plain file.
- */
- if ((dep->de_Attributes & ATTR_DIRECTORY) == 0)
- return (ENOTDIR);
-
- /*
- * To be safe, initialize dirbuf
- */
- bzero(dirbuf.d_name, sizeof(dirbuf.d_name));
-
- /*
- * If the user buffer is smaller than the size of one dos directory
- * entry or the file offset is not a multiple of the size of a
- * directory entry, then we fail the read.
- */
- off = offset = uio->uio_offset;
- if (uio->uio_resid < sizeof(struct direntry) ||
- (offset & (sizeof(struct direntry) - 1)))
- return (EINVAL);
-
- if (ap->a_ncookies) {
- ncookies = uio->uio_resid / 16;
- MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP,
- M_WAITOK);
- *ap->a_cookies = cookies;
- *ap->a_ncookies = ncookies;
- }
-
- dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);
-
- /*
- * If they are reading from the root directory then, we simulate
- * the . and .. entries since these don't exist in the root
- * directory. We also set the offset bias to make up for having to
- * simulate these entries. By this I mean that at file offset 64 we
- * read the first entry in the root directory that lives on disk.
- */
- if (dep->de_StartCluster == MSDOSFSROOT
- || (FAT32(pmp) && dep->de_StartCluster == pmp->pm_rootdirblk)) {
-#if 0
- printf("msdosfs_readdir(): going after . or .. in root dir, offset %d\n",
- offset);
-#endif
- bias = 2 * sizeof(struct direntry);
- if (offset < bias) {
- for (n = (int)offset / sizeof(struct direntry);
- n < 2; n++) {
- if (FAT32(pmp))
- dirbuf.d_fileno = cntobn(pmp,
- pmp->pm_rootdirblk)
- * dirsperblk;
- else
- dirbuf.d_fileno = 1;
- dirbuf.d_type = DT_DIR;
- switch (n) {
- case 0:
- dirbuf.d_namlen = 1;
- strcpy(dirbuf.d_name, ".");
- break;
- case 1:
- dirbuf.d_namlen = 2;
- strcpy(dirbuf.d_name, "..");
- break;
- }
- dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf);
- if (uio->uio_resid < dirbuf.d_reclen)
- goto out;
- error = uiomove((caddr_t) &dirbuf,
- dirbuf.d_reclen, uio);
- if (error)
- goto out;
- offset += sizeof(struct direntry);
- off = offset;
- if (cookies) {
- *cookies++ = offset;
- if (--ncookies <= 0)
- goto out;
- }
- }
- }
- }
-
- off = offset;
- while (uio->uio_resid > 0) {
- lbn = de_cluster(pmp, offset - bias);
- on = (offset - bias) & pmp->pm_crbomask;
- n = min(pmp->pm_bpcluster - on, uio->uio_resid);
- diff = dep->de_FileSize - (offset - bias);
- if (diff <= 0)
- break;
- n = min(n, diff);
- error = pcbmap(dep, lbn, &bn, &cn, &blsize);
- if (error)
- break;
- error = bread(pmp->pm_devvp, bn, blsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- n = min(n, blsize - bp->b_resid);
-
- /*
- * Convert from dos directory entries to fs-independent
- * directory entries.
- */
- for (dentp = (struct direntry *)(bp->b_data + on);
- (char *)dentp < bp->b_data + on + n;
- dentp++, offset += sizeof(struct direntry)) {
-#if 0
- printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n",
- dentp, prev, crnt, dentp->deName[0], dentp->deAttributes);
-#endif
- /*
- * If this is an unused entry, we can stop.
- */
- if (dentp->deName[0] == SLOT_EMPTY) {
- brelse(bp);
- goto out;
- }
- /*
- * Skip deleted entries.
- */
- if (dentp->deName[0] == SLOT_DELETED) {
- chksum = -1;
- continue;
- }
-
- /*
- * Handle Win95 long directory entries
- */
- if (dentp->deAttributes == ATTR_WIN95) {
- if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
- continue;
- chksum = win2unixfn((struct winentry *)dentp,
- &dirbuf, chksum,
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
- pmp->pm_u2w);
- continue;
- }
-
- /*
- * Skip volume labels
- */
- if (dentp->deAttributes & ATTR_VOLUME) {
- chksum = -1;
- continue;
- }
- /*
- * This computation of d_fileno must match
- * the computation of va_fileid in
- * msdosfs_getattr.
- */
- if (dentp->deAttributes & ATTR_DIRECTORY) {
- fileno = getushort(dentp->deStartCluster);
- if (FAT32(pmp))
- fileno |= getushort(dentp->deHighClust) << 16;
- /* if this is the root directory */
- if (fileno == MSDOSFSROOT)
- if (FAT32(pmp))
- fileno = cntobn(pmp,
- pmp->pm_rootdirblk)
- * dirsperblk;
- else
- fileno = 1;
- else
- fileno = cntobn(pmp, fileno) * dirsperblk;
- dirbuf.d_fileno = fileno;
- dirbuf.d_type = DT_DIR;
- } else {
- dirbuf.d_fileno = offset / sizeof(struct direntry);
- dirbuf.d_type = DT_REG;
- }
- if (chksum != winChksum(dentp->deName))
- dirbuf.d_namlen = dos2unixfn(dentp->deName,
- (u_char *)dirbuf.d_name,
- dentp->deLowerCase |
- ((pmp->pm_flags & MSDOSFSMNT_SHORTNAME) ?
- (LCASE_BASE | LCASE_EXT) : 0),
- pmp->pm_flags & MSDOSFSMNT_U2WTABLE,
- pmp->pm_d2u,
- pmp->pm_flags & MSDOSFSMNT_ULTABLE,
- pmp->pm_ul);
- else
- dirbuf.d_name[dirbuf.d_namlen] = 0;
- chksum = -1;
- dirbuf.d_reclen = GENERIC_DIRSIZ(&dirbuf);
- if (uio->uio_resid < dirbuf.d_reclen) {
- brelse(bp);
- goto out;
- }
- error = uiomove((caddr_t) &dirbuf,
- dirbuf.d_reclen, uio);
- if (error) {
- brelse(bp);
- goto out;
- }
- if (cookies) {
- *cookies++ = offset + sizeof(struct direntry);
- if (--ncookies <= 0) {
- brelse(bp);
- goto out;
- }
- }
- off = offset + sizeof(struct direntry);
- }
- brelse(bp);
- }
-out:
- /* Subtract unused cookies */
- if (ap->a_ncookies)
- *ap->a_ncookies -= ncookies;
-
- uio->uio_offset = off;
-
- /*
- * Set the eofflag (NFS uses it)
- */
- if (ap->a_eofflag) {
- if (dep->de_FileSize - (offset - bias) <= 0)
- *ap->a_eofflag = 1;
- else
- *ap->a_eofflag = 0;
- }
- return (error);
-}
-
-/*
- * vp - address of vnode file the file
- * bn - which cluster we are interested in mapping to a filesystem block number.
- * vpp - returns the vnode for the block special file holding the filesystem
- * containing the file of interest
- * bnp - address of where to return the filesystem relative block number
- */
-static int
-msdosfs_bmap(ap)
- struct vop_bmap_args /* {
- struct vnode *a_vp;
- daddr_t a_bn;
- struct vnode **a_vpp;
- daddr_t *a_bnp;
- int *a_runp;
- int *a_runb;
- } */ *ap;
-{
- struct denode *dep = VTODE(ap->a_vp);
-
- if (ap->a_vpp != NULL)
- *ap->a_vpp = dep->de_devvp;
- if (ap->a_bnp == NULL)
- return (0);
- if (ap->a_runp) {
- /*
- * Sequential clusters should be counted here.
- */
- *ap->a_runp = 0;
- }
- if (ap->a_runb) {
- *ap->a_runb = 0;
- }
- return (pcbmap(dep, ap->a_bn, ap->a_bnp, 0, 0));
-}
-
-static int
-msdosfs_strategy(ap)
- struct vop_strategy_args /* {
- struct vnode *a_vp;
- struct buf *a_bp;
- } */ *ap;
-{
- struct buf *bp = ap->a_bp;
- struct denode *dep = VTODE(bp->b_vp);
- struct vnode *vp;
- int error = 0;
-
- if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
- panic("msdosfs_strategy: spec");
- /*
- * If we don't already know the filesystem relative block number
- * then get it using pcbmap(). If pcbmap() returns the block
- * number as -1 then we've got a hole in the file. DOS filesystems
- * don't allow files with holes, so we shouldn't ever see this.
- */
- if (bp->b_blkno == bp->b_lblkno) {
- error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0, 0);
- if (error) {
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return (error);
- }
- if ((long)bp->b_blkno == -1)
- vfs_bio_clrbuf(bp);
- }
- if (bp->b_blkno == -1) {
- bufdone(bp);
- return (0);
- }
- /*
- * Read/write the block from/to the disk that contains the desired
- * file block.
- */
- vp = dep->de_devvp;
- bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
- return (0);
-}
-
-static int
-msdosfs_print(ap)
- struct vop_print_args /* {
- struct vnode *vp;
- } */ *ap;
-{
- struct denode *dep = VTODE(ap->a_vp);
-
- printf(
- "tag VT_MSDOSFS, startcluster %lu, dircluster %lu, diroffset %lu ",
- dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
- printf(" dev %d, %d", major(dep->de_dev), minor(dep->de_dev));
- lockmgr_printinfo(&ap->a_vp->v_lock);
- printf("\n");
- return (0);
-}
-
-static int
-msdosfs_pathconf(ap)
- struct vop_pathconf_args /* {
- struct vnode *a_vp;
- int a_name;
- int *a_retval;
- } */ *ap;
-{
- struct msdosfsmount *pmp = VTODE(ap->a_vp)->de_pmp;
-
- switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = 1;
- return (0);
- case _PC_NAME_MAX:
- *ap->a_retval = pmp->pm_flags & MSDOSFSMNT_LONGNAME ? WIN_MAXLEN : 12;
- return (0);
- case _PC_PATH_MAX:
- *ap->a_retval = PATH_MAX;
- return (0);
- case _PC_CHOWN_RESTRICTED:
- *ap->a_retval = 1;
- return (0);
- case _PC_NO_TRUNC:
- *ap->a_retval = 0;
- return (0);
- default:
- return (EINVAL);
- }
- /* NOTREACHED */
-}
-
-
-/* Global vfs data structures for msdosfs */
-vop_t **msdosfs_vnodeop_p;
-static struct vnodeopv_entry_desc msdosfs_vnodeop_entries[] = {
- { &vop_default_desc, (vop_t *) vop_defaultop },
- { &vop_access_desc, (vop_t *) msdosfs_access },
- { &vop_bmap_desc, (vop_t *) msdosfs_bmap },
- { &vop_cachedlookup_desc, (vop_t *) msdosfs_lookup },
- { &vop_close_desc, (vop_t *) msdosfs_close },
- { &vop_create_desc, (vop_t *) msdosfs_create },
- { &vop_fsync_desc, (vop_t *) msdosfs_fsync },
- { &vop_getattr_desc, (vop_t *) msdosfs_getattr },
- { &vop_inactive_desc, (vop_t *) msdosfs_inactive },
- { &vop_islocked_desc, (vop_t *) vop_stdislocked },
- { &vop_link_desc, (vop_t *) msdosfs_link },
- { &vop_lock_desc, (vop_t *) vop_stdlock },
- { &vop_lookup_desc, (vop_t *) vfs_cache_lookup },
- { &vop_mkdir_desc, (vop_t *) msdosfs_mkdir },
- { &vop_mknod_desc, (vop_t *) msdosfs_mknod },
- { &vop_pathconf_desc, (vop_t *) msdosfs_pathconf },
- { &vop_print_desc, (vop_t *) msdosfs_print },
- { &vop_read_desc, (vop_t *) msdosfs_read },
- { &vop_readdir_desc, (vop_t *) msdosfs_readdir },
- { &vop_reclaim_desc, (vop_t *) msdosfs_reclaim },
- { &vop_remove_desc, (vop_t *) msdosfs_remove },
- { &vop_rename_desc, (vop_t *) msdosfs_rename },
- { &vop_rmdir_desc, (vop_t *) msdosfs_rmdir },
- { &vop_setattr_desc, (vop_t *) msdosfs_setattr },
- { &vop_strategy_desc, (vop_t *) msdosfs_strategy },
- { &vop_symlink_desc, (vop_t *) msdosfs_symlink },
- { &vop_unlock_desc, (vop_t *) vop_stdunlock },
- { &vop_write_desc, (vop_t *) msdosfs_write },
- { NULL, NULL }
-};
-static struct vnodeopv_desc msdosfs_vnodeop_opv_desc =
- { &msdosfs_vnodeop_p, msdosfs_vnodeop_entries };
-
-VNODEOP_SET(msdosfs_vnodeop_opv_desc);
diff --git a/sys/msdosfs/msdosfsmount.h b/sys/msdosfs/msdosfsmount.h
deleted file mode 100644
index 1c9a890..0000000
--- a/sys/msdosfs/msdosfsmount.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* $FreeBSD$ */
-/* $NetBSD: msdosfsmount.h,v 1.17 1997/11/17 15:37:07 ws Exp $ */
-
-/*-
- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
- * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
- * All rights reserved.
- * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
- *
- * 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 remove this notice.
- *
- * This software is provided "as is".
- *
- * 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.
- *
- * October 1992
- */
-
-#ifndef _MSDOSFS_MSDOSFSMOUNT_H_
-#define _MSDOSFS_MSDOSFSMOUNT_H_
-
-#ifdef _KERNEL
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_MSDOSFSMNT);
-#endif
-
-/*
- * Layout of the mount control block for a msdos file system.
- */
-struct msdosfsmount {
- struct mount *pm_mountp;/* vfs mount struct for this fs */
- dev_t pm_dev; /* block special device mounted */
- uid_t pm_uid; /* uid to set as owner of the files */
- gid_t pm_gid; /* gid to set as owner of the files */
- mode_t pm_mask; /* mask to and with file protection bits */
- struct vnode *pm_devvp; /* vnode for block device mntd */
- struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */
- u_long pm_BlkPerSec; /* How many DEV_BSIZE blocks fit inside a physical sector */
- u_long pm_FATsecs; /* actual number of fat sectors */
- u_long pm_fatblk; /* block # of first FAT */
- u_long pm_rootdirblk; /* block # (cluster # for FAT32) of root directory number */
- u_long pm_rootdirsize; /* size in blocks (not clusters) */
- u_long pm_firstcluster; /* block number of first cluster */
- u_long pm_maxcluster; /* maximum cluster number */
- u_long pm_freeclustercount; /* number of free clusters */
- u_long pm_cnshift; /* shift file offset right this amount to get a cluster number */
- u_long pm_crbomask; /* and a file offset with this mask to get cluster rel offset */
- u_long pm_bnshift; /* shift file offset right this amount to get a block number */
- u_long pm_bpcluster; /* bytes per cluster */
- u_long pm_fmod; /* ~0 if fs is modified, this can rollover to 0 */
- 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_int32_t pm_fatmask; /* mask to use for fat numbers */
- u_long pm_fsinfo; /* fsinfo block number */
- u_long pm_nxtfree; /* next free cluster in fsinfo block */
- u_int pm_fatmult; /* these 2 values are used in fat */
- u_int pm_fatdiv; /* offset computation */
- u_int pm_curfat; /* current fat for FAT32 (0 otherwise) */
- u_int *pm_inusemap; /* ptr to bitmap of in-use clusters */
- u_int pm_flags; /* see below */
- u_int16_t pm_u2w[128]; /* Local->Unicode table */
- u_int8_t pm_ul[128]; /* Local upper->lower table */
- u_int8_t pm_lu[128]; /* Local lower->upper table */
- u_int8_t pm_d2u[128]; /* DOS->local table */
- u_int8_t pm_u2d[128]; /* Local->DOS table */
-};
-/* Byte offset in FAT on filesystem pmp, cluster cn */
-#define FATOFS(pmp, cn) ((cn) * (pmp)->pm_fatmult / (pmp)->pm_fatdiv)
-
-
-#define VFSTOMSDOSFS(mp) ((struct msdosfsmount *)mp->mnt_data)
-
-/* Number of bits in one pm_inusemap item: */
-#define N_INUSEBITS (8 * sizeof(u_int))
-
-/*
- * Shorthand for fields in the bpb contained in the msdosfsmount structure.
- */
-#define pm_BytesPerSec pm_bpb.bpbBytesPerSec
-#define pm_ResSectors pm_bpb.bpbResSectors
-#define pm_FATs pm_bpb.bpbFATs
-#define pm_RootDirEnts pm_bpb.bpbRootDirEnts
-#define pm_Sectors pm_bpb.bpbSectors
-#define pm_Media pm_bpb.bpbMedia
-#define pm_SecPerTrack pm_bpb.bpbSecPerTrack
-#define pm_Heads pm_bpb.bpbHeads
-#define pm_HiddenSects pm_bpb.bpbHiddenSecs
-#define pm_HugeSectors pm_bpb.bpbHugeSectors
-
-/*
- * Convert pointer to buffer -> pointer to direntry
- */
-#define bptoep(pmp, bp, dirofs) \
- ((struct direntry *)(((bp)->b_data) \
- + ((dirofs) & (pmp)->pm_crbomask)))
-
-/*
- * Convert block number to cluster number
- */
-#define de_bn2cn(pmp, bn) \
- ((bn) >> ((pmp)->pm_cnshift - (pmp)->pm_bnshift))
-
-/*
- * Convert cluster number to block number
- */
-#define de_cn2bn(pmp, cn) \
- ((cn) << ((pmp)->pm_cnshift - (pmp)->pm_bnshift))
-
-/*
- * Convert file offset to cluster number
- */
-#define de_cluster(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)
-
-/*
- * Convert file offset to block number
- */
-#define de_blk(pmp, off) \
- (de_cn2bn(pmp, de_cluster((pmp), (off))))
-
-/*
- * Convert cluster number to file offset
- */
-#define de_cn2off(pmp, cn) \
- ((cn) << (pmp)->pm_cnshift)
-
-/*
- * Convert block number to file offset
- */
-#define de_bn2off(pmp, bn) \
- ((bn) << (pmp)->pm_bnshift)
-/*
- * Map a cluster number into a filesystem relative block number.
- */
-#define cntobn(pmp, cn) \
- (de_cn2bn((pmp), (cn)-CLUST_FIRST) + (pmp)->pm_firstcluster)
-
-/*
- * Calculate block number for directory entry in root dir, offset dirofs
- */
-#define roottobn(pmp, dirofs) \
- (de_blk((pmp), (dirofs)) + (pmp)->pm_rootdirblk)
-
-/*
- * Calculate block number for directory entry at cluster dirclu, offset
- * dirofs
- */
-#define detobn(pmp, dirclu, dirofs) \
- ((dirclu) == MSDOSFSROOT \
- ? roottobn((pmp), (dirofs)) \
- : cntobn((pmp), (dirclu)))
-
-/*
- * Calculate fsinfo block size
- */
-#define fsi_size(pmp) \
- (1024 << ((pmp)->pm_BlkPerSec >> 2))
-
-int msdosfs_init __P((struct vfsconf *vfsp));
-int msdosfs_uninit __P((struct vfsconf *vfsp));
-int msdosfs_mountroot __P((void));
-
-#endif /* _KERNEL */
-
-/*
- * Arguments to mount MSDOS filesystems.
- */
-struct msdosfs_args {
- char *fspec; /* blocks special holding the fs to mount */
- struct export_args export; /* network export information */
- uid_t uid; /* uid that owns msdosfs files */
- gid_t gid; /* gid that owns msdosfs files */
- mode_t mask; /* mask to be applied for msdosfs perms */
- int flags; /* see below */
- int magic; /* version number */
- u_int16_t u2w[128]; /* Local->Unicode table */
- u_int8_t ul[128]; /* Local upper->lower table */
- u_int8_t lu[128]; /* Local lower->upper table */
- u_int8_t d2u[128]; /* DOS->local table */
- u_int8_t u2d[128]; /* Local->DOS table */
-};
-
-/*
- * Msdosfs mount options:
- */
-#define MSDOSFSMNT_SHORTNAME 1 /* Force old DOS short names only */
-#define MSDOSFSMNT_LONGNAME 2 /* Force Win'95 long names */
-#define MSDOSFSMNT_NOWIN95 4 /* Completely ignore Win95 entries */
-#ifndef __FreeBSD__
-#define MSDOSFSMNT_GEMDOSFS 8 /* This is a gemdos-flavour */
-#endif
-#define MSDOSFSMNT_U2WTABLE 0x10 /* Local->Unicode and local<->DOS */
- /* tables loaded */
-#define MSDOSFSMNT_ULTABLE 0x20 /* Local upper<->lower table loaded */
-/* All flags above: */
-#define MSDOSFSMNT_MNTOPT \
- (MSDOSFSMNT_SHORTNAME|MSDOSFSMNT_LONGNAME|MSDOSFSMNT_NOWIN95 \
- /*|MSDOSFSMNT_GEMDOSFS*/|MSDOSFSMNT_U2WTABLE|MSDOSFSMNT_ULTABLE)
-#define MSDOSFSMNT_RONLY 0x80000000 /* mounted read-only */
-#define MSDOSFSMNT_WAITONFAT 0x40000000 /* mounted synchronous */
-#define MSDOSFS_FATMIRROR 0x20000000 /* FAT is mirrored */
-
-#define MSDOSFS_ARGSMAGIC 0xe4eff300
-
-#endif /* !_MSDOSFS_MSDOSFSMOUNT_H_ */
diff --git a/usr.bin/fstat/msdosfs.c b/usr.bin/fstat/msdosfs.c
index 809477d..0c9c161 100644
--- a/usr.bin/fstat/msdosfs.c
+++ b/usr.bin/fstat/msdosfs.c
@@ -43,13 +43,13 @@
#define _KERNEL
#include <sys/mount.h>
-#include <msdosfs/bpb.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/bpb.h>
+#include <fs/msdosfs/msdosfsmount.h>
#undef _KERNEL
-#include <msdosfs/denode.h>
-#include <msdosfs/direntry.h>
-#include <msdosfs/fat.h>
+#include <fs/msdosfs/denode.h>
+#include <fs/msdosfs/direntry.h>
+#include <fs/msdosfs/fat.h>
#include <err.h>
#include <kvm.h>
diff --git a/usr.sbin/amd/include/config.h b/usr.sbin/amd/include/config.h
index 2456edd..8766a5c 100644
--- a/usr.sbin/amd/include/config.h
+++ b/usr.sbin/amd/include/config.h
@@ -1572,7 +1572,10 @@
/* #undef HAVE_MOUNT_H */
/* Define if you have the <msdosfs/msdosfsmount.h> header file. */
-#define HAVE_MSDOSFS_MSDOSFSMOUNT_H 1
+/* #undef HAVE_MSDOSFS_MSDOSFSMOUNT_H */
+
+/* Define if you have the <fs/msdosfs/msdosfsmount.h> header file. */
+#define HAVE_FS_MSDOSFS_MSDOSFSMOUNT_H 1
/* Define if you have the <ndbm.h> header file. */
#define HAVE_NDBM_H 1
diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index cab8bc0..2d198e6 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -63,7 +63,7 @@ static const char rcsid[] =
#include <nfs/nfsproto.h>
#include <nfs/nfs.h>
#include <ufs/ufs/ufsmount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#include <ntfs/ntfsmount.h>
#include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */
diff --git a/usr.sbin/sade/install.c b/usr.sbin/sade/install.c
index 9b4b088..a30634e 100644
--- a/usr.sbin/sade/install.c
+++ b/usr.sbin/sade/install.c
@@ -45,7 +45,7 @@
#define MSDOSFS
#include <sys/mount.h>
#include <ufs/ufs/ufsmount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#undef MSDOSFS
#include <sys/stat.h>
#include <sys/sysctl.h>
diff --git a/usr.sbin/sysinstall/dos.c b/usr.sbin/sysinstall/dos.c
index ae6eb1e..bada228 100644
--- a/usr.sbin/sysinstall/dos.c
+++ b/usr.sbin/sysinstall/dos.c
@@ -46,7 +46,7 @@
#include <grp.h>
#define MSDOSFS
#include <sys/mount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#undef MSDOSFS
static Boolean DOSMounted;
diff --git a/usr.sbin/sysinstall/floppy.c b/usr.sbin/sysinstall/floppy.c
index b37f513..4a42c61 100644
--- a/usr.sbin/sysinstall/floppy.c
+++ b/usr.sbin/sysinstall/floppy.c
@@ -49,7 +49,7 @@
#define MSDOSFS
#include <sys/mount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#undef MSDOSFS
#include <ufs/ufs/ufsmount.h>
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index 9b4b088..a30634e 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -45,7 +45,7 @@
#define MSDOSFS
#include <sys/mount.h>
#include <ufs/ufs/ufsmount.h>
-#include <msdosfs/msdosfsmount.h>
+#include <fs/msdosfs/msdosfsmount.h>
#undef MSDOSFS
#include <sys/stat.h>
#include <sys/sysctl.h>
OpenPOWER on IntegriCloud