Page MenuHomeFreeBSD

D16438.id61014.diff
No OneTemporary

D16438.id61014.diff

Index: usr.sbin/makefs/Makefile
===================================================================
--- usr.sbin/makefs/Makefile
+++ usr.sbin/makefs/Makefile
@@ -8,7 +8,7 @@
CFLAGS+=-I${SRCDIR}
-SRCS= cd9660.c ffs.c \
+SRCS= cd9660.c ffs.c msdos.c \
makefs.c \
mtree.c \
walk.c
@@ -18,6 +18,7 @@
.include "${SRCDIR}/cd9660/Makefile.inc"
.include "${SRCDIR}/ffs/Makefile.inc"
+.include "${SRCDIR}/msdos/Makefile.inc"
CFLAGS+=-DHAVE_STRUCT_STAT_ST_FLAGS=1
Index: usr.sbin/makefs/makefs.h
===================================================================
--- usr.sbin/makefs/makefs.h
+++ usr.sbin/makefs/makefs.h
@@ -185,6 +185,7 @@
DECLARE_FUN(ffs);
DECLARE_FUN(cd9660);
+DECLARE_FUN(msdos);
extern u_int debug;
extern int dupsok;
@@ -225,7 +226,7 @@
#define DEBUG_APPLY_SPECFILE 0x04000000
#define DEBUG_APPLY_SPECENTRY 0x08000000
#define DEBUG_APPLY_SPECONLY 0x10000000
-
+#define DEBUG_MSDOSFS 0x20000000
#define TIMER_START(x) \
if (debug & DEBUG_TIME) \
Index: usr.sbin/makefs/makefs.8
===================================================================
--- usr.sbin/makefs/makefs.8
+++ usr.sbin/makefs/makefs.8
@@ -198,7 +198,9 @@
Instead of creating the filesystem at the beginning of the file, start
at offset.
Valid only for
-.Sy ffs .
+.Sy ffs
+and
+.Sy msdos .
.It Fl o Ar fs-options
Set file system specific options.
.Ar fs-options
@@ -225,6 +227,19 @@
.It Fl s Ar image-size
Set the size of the file system image to
.Ar image-size .
+This is equivalent of setting both the minimum
+.Fl ( m )
+and the maximum
+.Fl ( M )
+sizes to
+.Ar image-size .
+For
+.Sy ffs
+and
+.Sy msdos
+the
+.Ar offset
+is not included on that size.
.It Fl T Ar timestamp
Specify a timestamp to be set for all filesystem files and directories
created so that repeatable builds are possible.
@@ -247,6 +262,8 @@
BSD fast file system (default).
.It Sy cd9660
ISO 9660 file system.
+.It Sy msdos
+FAT12, FAT16, or FAT32 file system.
.El
.It Fl x
Exclude file system nodes not explicitly listed in the specfile.
@@ -407,6 +424,66 @@
.It Sy volumeid
Volume set identifier of the image.
.El
+.Ss msdos-specific options
+.Sy msdos
+images have MS-DOS-specific optional parameters that may be
+provided.
+The arguments consist of a keyword, an equal sign
+.Pq Ql = ,
+and a value.
+The following keywords are supported (see
+.Xr newfs_msdos 8
+for more details):
+.Pp
+.Bl -tag -width omit-trailing-period -offset indent -compact
+.It Cm backup_sector
+Location of the backup boot sector.
+.It Cm block_size
+Block size.
+.It Cm bootstrap
+Bootstrap file.
+.It Cm bytes_per_sector
+Bytes per sector.
+.It Cm create_size
+Create file size.
+.It Cm directory_entries
+Directory entries.
+.It Cm drive_heads
+Drive heads.
+.It Cm fat_type
+FAT type (12, 16, or 32).
+.It Cm floppy
+Preset drive parameters for standard format floppy disks
+(160, 180, 320, 360, 640, 720, 1200, 1232, 1440, or 2880).
+.It Cm hidden_sectors
+Hidden sectors.
+.It Cm info_sector
+Location of the info sector.
+.It Cm media_descriptor
+Media descriptor.
+.It Cm num_FAT
+Number of FATs.
+.It Cm OEM_string
+OEM string.
+.It Cm offset
+Offset in device. This option will be ignored if
+.Fl O
+is set to a positive number.
+.It Cm reserved_sectors
+Reserved sectors.
+.It Cm sectors_per_cluster
+Sectors per cluster.
+.It Cm sectors_per_fat
+Sectors per FAT.
+.It Cm sectors_per_track
+Sectors per track.
+.It Cm size
+File System size.
+.It Cm volume_id
+Volume ID.
+.It Cm volume_label
+Volume Label.
+.El
.Sh SEE ALSO
.Xr mtree 5 ,
.Xr mtree 8 ,
Index: usr.sbin/makefs/makefs.c
===================================================================
--- usr.sbin/makefs/makefs.c
+++ usr.sbin/makefs/makefs.c
@@ -75,6 +75,7 @@
name ## _cleanup_opts, name ## _makefs \
}
ENTRY(ffs),
+ ENTRY(msdos),
ENTRY(cd9660),
{ .type = NULL },
};
Index: usr.sbin/makefs/msdos.h
===================================================================
--- usr.sbin/makefs/msdos.h
+++ usr.sbin/makefs/msdos.h
@@ -30,11 +30,31 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _MAKEFS_MSDOS_H
+#define _MAKEFS_MSDOS_H
+
+#define NOCRED NULL
+
+#define MSDOSFS_DPRINTF(args) do { \
+ if (debug & DEBUG_MSDOSFS) \
+ printf args; \
+} while (0);
+
+
struct vnode;
struct denode;
+struct fsnode;
+struct msdosfsmount;
+
+struct componentname {
+ char *cn_nameptr;
+ size_t cn_namelen;
+};
-struct msdosfsmount *msdosfs_mount(struct vnode *, int);
+struct msdosfsmount *msdosfs_mount(struct vnode *);
int msdosfs_root(struct msdosfsmount *, struct vnode *);
struct denode *msdosfs_mkfile(const char *, struct denode *, fsnode *);
struct denode *msdosfs_mkdire(const char *, struct denode *, fsnode *);
+
+#endif
Index: usr.sbin/makefs/msdos.c
===================================================================
--- usr.sbin/makefs/msdos.c
+++ usr.sbin/makefs/msdos.c
@@ -28,20 +28,13 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__FBSDID("$FreeBSD$");
#endif /* !__lint */
#include <sys/param.h>
-
-#if !HAVE_NBTOOL_CONFIG_H
#include <sys/mount.h>
-#endif
#include <assert.h>
#include <errno.h>
@@ -50,31 +43,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include <unistd.h>
#include <dirent.h>
#include <util.h>
-#include <ffs/buf.h>
-#include <fs/msdosfs/bpb.h>
-#include <fs/msdosfs/denode.h>
-#include <fs/msdosfs/msdosfsmount.h>
#include "makefs.h"
#include "msdos.h"
-#include "mkfs_msdos.h"
+
+#include <mkfs_msdos.h>
+#include <fs/msdosfs/bpb.h>
+
+#include "ffs/buf.h"
+
+#include "msdos/msdosfsmount.h"
+#include "msdos/direntry.h"
+#include "msdos/denode.h"
static int msdos_populate_dir(const char *, struct denode *, fsnode *,
fsnode *, fsinfo_t *);
-struct msdos_options_ex {
- struct msdos_options options;
- bool utf8;
-};
-
void
msdos_prep_opts(fsinfo_t *fsopts)
{
- struct msdos_options_ex *msdos_opt = ecalloc(1, sizeof(*msdos_opt));
- const option_t msdos_options[] = {
+ struct msdos_options *msdos_spec = ecalloc(1, sizeof(*msdos_spec));
+ const option_t msdos_opts[] = {
#define AOPT(_opt, _type, _name, _min, _desc) { \
.letter = _opt, \
.name = # _name, \
@@ -83,22 +76,20 @@
(sizeof(_type) == 1 ? OPT_INT8 : \
(sizeof(_type) == 2 ? OPT_INT16 : \
(sizeof(_type) == 4 ? OPT_INT32 : OPT_INT64)))), \
- .value = &msdos_opt->options._name, \
+ .value = &msdos_spec->_name, \
.minimum = _min, \
- .maximum = sizeof(_type) == 1 ? 0xff : \
- (sizeof(_type) == 2 ? 0xffff : \
- (sizeof(_type) == 4 ? 0xffffffff : 0xffffffffffffffffLL)), \
- .desc = _desc, \
+ .maximum = sizeof(_type) == 1 ? UINT8_MAX : \
+ (sizeof(_type) == 2 ? UINT16_MAX : \
+ (sizeof(_type) == 4 ? UINT32_MAX : INT64_MAX)), \
+ .desc = _desc, \
},
ALLOPTS
#undef AOPT
- { 'U', "utf8", &msdos_opt->utf8, OPT_BOOL,
- 0, 1, "Use UTF8 names" },
{ .name = NULL }
};
- fsopts->fs_specific = msdos_opt;
- fsopts->fs_options = copy_opts(msdos_options);
+ fsopts->fs_specific = msdos_spec;
+ fsopts->fs_options = copy_opts(msdos_opts);
}
void
@@ -111,32 +102,31 @@
int
msdos_parse_opts(const char *option, fsinfo_t *fsopts)
{
- struct msdos_options *msdos_opt = fsopts->fs_specific;
- option_t *msdos_options = fsopts->fs_options;
-
+ struct msdos_options *msdos_spec = fsopts->fs_specific;
+ option_t *msdos_opts = fsopts->fs_options;
int rv;
assert(option != NULL);
assert(fsopts != NULL);
- assert(msdos_opt != NULL);
+ assert(msdos_spec != NULL);
if (debug & DEBUG_FS_PARSE_OPTS)
- printf("msdos_parse_opts: got `%s'\n", option);
+ printf("msdos_parse_opts: got '%s'\n", option);
- rv = set_option(msdos_options, option, NULL, 0);
+ rv = set_option(msdos_opts, option, NULL, 0);
if (rv == -1)
return rv;
- if (strcmp(msdos_options[rv].name, "volume_id") == 0)
- msdos_opt->volume_id_set = 1;
- else if (strcmp(msdos_options[rv].name, "media_descriptor") == 0)
- msdos_opt->media_descriptor_set = 1;
- else if (strcmp(msdos_options[rv].name, "hidden_sectors") == 0)
- msdos_opt->hidden_sectors_set = 1;
+ if (strcmp(msdos_opts[rv].name, "volume_id") == 0)
+ msdos_spec->volume_id_set = 1;
+ else if (strcmp(msdos_opts[rv].name, "media_descriptor") == 0)
+ msdos_spec->media_descriptor_set = 1;
+ else if (strcmp(msdos_opts[rv].name, "hidden_sectors") == 0)
+ msdos_spec->hidden_sectors_set = 1;
if (stampst.st_ino) {
- msdos_opt->timestamp_set = 1;
- msdos_opt->timestamp = stampst.st_mtime;
+ msdos_spec->timestamp_set = 1;
+ msdos_spec->timestamp = stampst.st_mtime;
}
return 1;
@@ -146,9 +136,9 @@
void
msdos_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
{
- struct msdos_options_ex *msdos_opt = fsopts->fs_specific;
+ struct msdos_options *msdos_spec = fsopts->fs_specific;
struct vnode vp, rootvp;
- struct timeval start;
+ struct timeval start;
struct msdosfsmount *pmp;
uint32_t flags;
@@ -158,25 +148,26 @@
assert(fsopts != NULL);
fsopts->size = fsopts->maxsize;
- msdos_opt->options.create_size = MAX(msdos_opt->options.create_size,
+ msdos_spec->create_size = MAX(msdos_spec->create_size,
fsopts->offset + fsopts->size);
- msdos_opt->options.offset = fsopts->offset;
- if (msdos_opt->options.bytes_per_sector == 0) {
+ if (fsopts->offset > 0)
+ msdos_spec->offset = fsopts->offset;
+ if (msdos_spec->bytes_per_sector == 0) {
if (fsopts->sectorsize == -1)
fsopts->sectorsize = 512;
- msdos_opt->options.bytes_per_sector = fsopts->sectorsize;
+ msdos_spec->bytes_per_sector = fsopts->sectorsize;
} else if (fsopts->sectorsize == -1) {
- fsopts->sectorsize = msdos_opt->options.bytes_per_sector;
- } else if (fsopts->sectorsize != msdos_opt->options.bytes_per_sector) {
+ fsopts->sectorsize = msdos_spec->bytes_per_sector;
+ } else if (fsopts->sectorsize != msdos_spec->bytes_per_sector) {
err(1, "inconsistent sectorsize -S %u"
"!= -o bytes_per_sector %u",
- fsopts->sectorsize, msdos_opt->options.bytes_per_sector);
+ fsopts->sectorsize, msdos_spec->bytes_per_sector);
}
- /* create image */
- printf("Creating `%s'\n", image);
+ /* create image */
+ printf("Creating '%s'\n", image);
TIMER_START(start);
- if (mkfs_msdos(image, NULL, &msdos_opt->options) == -1)
+ if (mkfs_msdos(image, NULL, msdos_spec) == -1)
return;
TIMER_RESULTS(start, "mkfs_msdos");
@@ -184,10 +175,7 @@
vp.fs = fsopts;
flags = 0;
- if (msdos_opt->utf8)
- flags |= MSDOSFSMNT_UTF8;
-
- if ((pmp = msdosfs_mount(&vp, flags)) == NULL)
+ if ((pmp = msdosfs_mount(&vp)) == NULL)
err(1, "msdosfs_mount");
if (msdosfs_root(pmp, &rootvp) != 0)
@@ -197,21 +185,22 @@
printf("msdos_makefs: image %s directory %s root %p\n",
image, dir, root);
- /* populate image */
- printf("Populating `%s'\n", image);
+ /* populate image */
+ printf("Populating '%s'\n", image);
TIMER_START(start);
- if (msdos_populate_dir(dir, VTODE(&rootvp), root, root, fsopts) == -1)
- errx(1, "Image file `%s' not created.", image);
+ if (msdos_populate_dir(dir, VTODE(&rootvp), root,
+ root, fsopts) == -1)
+ errx(1, "Image file '%s' not created.", image);
TIMER_RESULTS(start, "msdos_populate_dir");
if (debug & DEBUG_FS_MAKEFS)
putchar('\n');
- /* ensure no outstanding buffers remain */
+ /* ensure no outstanding buffers remain */
if (debug & DEBUG_FS_MAKEFS)
bcleanup();
- printf("Image `%s' complete\n", image);
+ printf("Image '%s' complete\n", image);
}
static int
Index: usr.sbin/makefs/msdos/Makefile.inc
===================================================================
--- /dev/null
+++ usr.sbin/makefs/msdos/Makefile.inc
@@ -0,0 +1,13 @@
+# $FreeBSD$
+#
+
+MSDOS= ${SRCTOP}/sys/fs/msdosfs
+MSDOS_NEWFS= ${SRCTOP}/sbin/newfs_msdos
+
+.PATH: ${SRCDIR}/msdos ${MSDOS} ${MSDOS_NEWFS}
+
+CFLAGS+= -I${MSDOS} -I${MSDOS_NEWFS}
+
+SRCS+= mkfs_msdos.c
+SRCS+= msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c msdosfs_lookup.c
+SRCS+= msdosfs_vnops.c msdosfs_vfsops.c
Index: usr.sbin/makefs/msdos/denode.h
===================================================================
--- usr.sbin/makefs/msdos/denode.h
+++ usr.sbin/makefs/msdos/denode.h
@@ -159,7 +159,6 @@
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. */
uint64_t de_inode; /* Inode number (really byte offset of direntry) */
};
@@ -172,6 +171,8 @@
#define DE_MODIFIED 0x0020 /* Denode has been modified */
#define DE_RENAME 0x0040 /* Denode is in the process of being renamed */
+/* Maximum size of a file on a FAT filesystem */
+#define MSDOSFS_FILESIZE_MAX 0xFFFFFFFFLL
/*
* Transfer directory entries between internal and external form.
@@ -209,76 +210,27 @@
((dep)->de_Attributes & ATTR_DIRECTORY) ? 0 : (dep)->de_FileSize), \
putushort((dp)->deHighClust, (dep)->de_StartCluster >> 16))
-#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; \
- timespec2fattime((mod), 0, &(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) { \
- uint16_t adate; \
- \
- timespec2fattime((acc), 0, &adate, NULL, NULL); \
- if (adate != (dep)->de_ADate) { \
- (dep)->de_flag |= DE_MODIFIED; \
- (dep)->de_ADate = adate; \
- } \
- } \
- if ((dep)->de_flag & DE_CREATE) { \
- timespec2fattime((cre), 0, &(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 */
-
- uint32_t defid_dirclust; /* cluster this dir entry came from */
- uint32_t defid_dirofs; /* offset of entry within the cluster */
-#if 0
- uint32_t defid_gen; /* generation number */
-#endif
-};
-
-extern struct vop_vector msdosfs_vnodeops;
-
-int msdosfs_lookup(struct vop_cachedlookup_args *);
-int msdosfs_inactive(struct vop_inactive_args *);
-int msdosfs_reclaim(struct vop_reclaim_args *);
+struct buf;
+struct msdosfsmount;
+struct direntry;
+struct componentname;
+struct denode;
/*
* Internal service routine prototypes.
*/
int deget(struct msdosfsmount *, u_long, u_long, struct denode **);
int uniqdosname(struct denode *, struct componentname *, u_char *);
-
-int readep(struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp);
+int readep(struct msdosfsmount *pmp, u_long dirclu, u_long dirofs, struct buf **bpp, struct direntry **epp);
int readde(struct denode *dep, struct buf **bpp, struct direntry **epp);
-int deextend(struct denode *dep, u_long length, struct ucred *cred);
+int deextend(struct denode *dep, u_long length);
int fillinusemap(struct msdosfsmount *pmp);
-void reinsert(struct denode *dep);
-int dosdirempty(struct denode *dep);
int createde(struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp);
-int deupdat(struct denode *dep, int waitfor);
int removede(struct denode *pdep, struct denode *dep);
-int detrunc(struct denode *dep, u_long length, int flags, struct ucred *cred);
-int doscheckpath( struct denode *source, struct denode *target);
-#endif /* _KERNEL */
-#endif /* !_FS_MSDOSFS_DENODE_H_ */
+int detrunc(struct denode *dep, u_long length, int flags);
+#endif /* !_FS_MSDOSFS_DENODE_H_ */
Index: usr.sbin/makefs/msdos/direntry.h
===================================================================
--- usr.sbin/makefs/msdos/direntry.h
+++ usr.sbin/makefs/msdos/direntry.h
@@ -133,31 +133,12 @@
#define DD_YEAR_MASK 0xFE00 /* year - 1980 */
#define DD_YEAR_SHIFT 9
-#ifdef _KERNEL
-struct mbnambuf {
- size_t nb_len;
- int nb_last_id;
- char nb_buf[WIN_MAXLEN + 1];
-};
-
-struct dirent;
-struct msdosfsmount;
-
-char *mbnambuf_flush(struct mbnambuf *nbp, struct dirent *dp);
-void mbnambuf_init(struct mbnambuf *nbp);
-int mbnambuf_write(struct mbnambuf *nbp, char *name, int id);
-int dos2unixfn(u_char dn[11], u_char *un, int lower,
- struct msdosfsmount *pmp);
-int unix2dosfn(const u_char *un, u_char dn[12], size_t unlen, u_int gen,
- struct msdosfsmount *pmp);
-int unix2winfn(const u_char *un, size_t unlen, struct winentry *wep, int cnt,
- int chksum, struct msdosfsmount *pmp);
-int winChkName(struct mbnambuf *nbp, const u_char *un, size_t unlen,
- int chksum, struct msdosfsmount *pmp);
-int win2unixfn(struct mbnambuf *nbp, struct winentry *wep, int chksum,
- struct msdosfsmount *pmp);
uint8_t winChksum(uint8_t *name);
-int winSlotCnt(const u_char *un, size_t unlen, struct msdosfsmount *pmp);
-size_t winLenFixup(const u_char *un, size_t unlen);
-#endif /* _KERNEL */
+int winSlotCnt(const u_char *un, size_t unlen);
+int unix2dosfn(const u_char *un, u_char dn[12], size_t unlen, u_int gen);
+int winChkName(const u_char *un, size_t unlen, struct winentry *wep,
+ int chksum);
+int unix2winfn(const u_char *un, size_t unlen, struct winentry *wep, int cnt,
+ int chksum);
+
#endif /* !_FS_MSDOSFS_DIRENTRY_H_ */
Index: usr.sbin/makefs/msdos/fat.h
===================================================================
--- usr.sbin/makefs/msdos/fat.h
+++ usr.sbin/makefs/msdos/fat.h
@@ -80,7 +80,6 @@
#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().
@@ -94,6 +93,10 @@
*/
#define DE_CLEAR 1 /* Zero out the blocks allocated */
+struct buf;
+struct denode;
+struct msdosfsmount;
+
int pcbmap(struct denode *dep, u_long findcn, daddr_t *bnp, u_long *cnp, int* sp);
int clusterfree(struct msdosfsmount *pmp, u_long cn, u_long *oldcnp);
int clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, u_long *got);
@@ -101,7 +104,5 @@
int freeclusterchain(struct msdosfsmount *pmp, u_long startchain);
int extendfile(struct denode *dep, u_long count, struct buf **bpp, u_long *ncp, int flags);
void fc_purge(struct denode *dep, u_int frcn);
-int markvoldirty(struct msdosfsmount *pmp, int dirty);
-#endif /* _KERNEL */
#endif /* !_FS_MSDOSFS_FAT_H_ */
Index: usr.sbin/makefs/msdos/msdosfs_conv.c
===================================================================
--- /dev/null
+++ usr.sbin/makefs/msdos/msdosfs_conv.c
@@ -0,0 +1,511 @@
+/*-
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fs/msdosfs/bpb.h>
+
+#include "makefs.h"
+#include "msdos.h"
+
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
+
+static int char8ucs2str(const uint8_t *in, int n, uint16_t *out, int m);
+static void ucs2pad(uint16_t *buf, int len, int size);
+static int char8match(uint16_t *w1, uint16_t *w2, int n);
+
+static const 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 */
+ 0, '!', 0, '#', '$', '%', '&', '\'', /* 20-27 */
+ '(', ')', 0, '+', 0, '-', 0, 0, /* 28-2f */
+ '0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
+ '8', '9', 0, 0, 0, 0, 0, 0, /* 38-3f */
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40-47 */
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 48-4f */
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 50-57 */
+ 'X', 'Y', 'Z', 0, 0, 0, '^', '_', /* 58-5f */
+ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 60-67 */
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 68-6f */
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 70-77 */
+ 'X', 'Y', 'Z', '{', 0, '}', '~', 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 const 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 */
+ ' ', '!', '"', '#', '$', '%', '&', '\'', /* 20-27 */
+ '(', ')', '*', '+', ',', '-', '.', '/', /* 28-2f */
+ '0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
+ '8', '9', ':', ';', '<', '=', '>', '?', /* 38-3f */
+ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 40-47 */
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 48-4f */
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 50-57 */
+ 'x', 'y', 'z', '[', '\\', ']', '^', '_', /* 58-5f */
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 60-67 */
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 68-6f */
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 70-77 */
+ 'x', 'y', 'z', '{', '|', '}', '~', 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 */
+};
+
+/*
+ * Determine the number of slots necessary for Win95 names
+ */
+int
+winSlotCnt(const u_char *un, size_t unlen)
+{
+ const u_char *cp;
+
+ /*
+ * Drop trailing blanks and dots
+ */
+ for (cp = un + unlen; unlen > 0; unlen--)
+ if (*--cp != ' ' && *cp != '.')
+ break;
+
+ return howmany(unlen, WIN_CHARS);
+}
+
+/*
+ * Compare our filename to the one in the Win95 entry
+ * Returns the checksum or -1 if no match
+ */
+int
+winChkName(const u_char *un, size_t unlen, struct winentry *wep, int chksum)
+{
+ uint16_t wn[WIN_MAXLEN], *p;
+ uint16_t buf[WIN_CHARS];
+ int i, len;
+
+ /*
+ * 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;
+
+ /*
+ * Translate UNIX name to ucs-2
+ */
+ len = char8ucs2str(un, unlen, wn, WIN_MAXLEN);
+ ucs2pad(wn, len, WIN_MAXLEN);
+
+ if (i >= len + 1)
+ return -1;
+ if ((wep->weCnt & WIN_LAST) && (len - i > WIN_CHARS))
+ return -1;
+
+ /*
+ * Fetch name segment from directory entry
+ */
+ p = &buf[0];
+ memcpy(p, wep->wePart1, sizeof(wep->wePart1));
+ p += sizeof(wep->wePart1) / sizeof(*p);
+ memcpy(p, wep->wePart2, sizeof(wep->wePart2));
+ p += sizeof(wep->wePart2) / sizeof(*p);
+ memcpy(p, wep->wePart3, sizeof(wep->wePart3));
+
+ /*
+ * And compare name segment
+ */
+ if (!(char8match(&wn[i], buf, WIN_CHARS)))
+ return -1;
+
+ return chksum;
+}
+
+/*
+ * Compute the checksum of a DOS filename for Win95 use
+ */
+uint8_t
+winChksum(uint8_t *name)
+{
+ int i;
+ uint8_t s;
+
+ for (s = 0, i = 11; --i >= 0; s += *name++)
+ s = (s << 7) | (s >> 1);
+ return s;
+}
+
+/*
+ * 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(const u_char *un, size_t unlen, struct winentry *wep, int cnt,
+ int chksum)
+{
+ uint16_t wn[WIN_MAXLEN], *p;
+ int i, len;
+ const u_char *cp;
+
+ /*
+ * Drop trailing blanks and dots
+ */
+ for (cp = un + unlen; unlen > 0; unlen--)
+ if (*--cp != ' ' && *cp != '.')
+ break;
+
+ /*
+ * Offset of this entry
+ */
+ i = (cnt - 1) * WIN_CHARS;
+
+ /*
+ * Translate UNIX name to ucs-2
+ */
+ len = char8ucs2str(un, unlen, wn, WIN_MAXLEN);
+ ucs2pad(wn, len, WIN_MAXLEN);
+
+ /*
+ * Initialize winentry to some useful default
+ */
+ memset(wep, 0xff, sizeof(*wep));
+ wep->weCnt = cnt;
+ wep->weAttributes = ATTR_WIN95;
+ wep->weReserved1 = 0;
+ wep->weChksum = chksum;
+ wep->weReserved2 = 0;
+
+ /*
+ * Store name segment into directory entry
+ */
+ p = &wn[i];
+ memcpy(wep->wePart1, p, sizeof(wep->wePart1));
+ p += sizeof(wep->wePart1) / sizeof(*p);
+ memcpy(wep->wePart2, p, sizeof(wep->wePart2));
+ p += sizeof(wep->wePart2) / sizeof(*p);
+ memcpy(wep->wePart3, p, sizeof(wep->wePart3));
+
+ if (len > i + WIN_CHARS)
+ return 1;
+
+ wep->weCnt |= WIN_LAST;
+ return 0;
+}
+
+
+/*
+ * 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(const u_char *un, u_char dn[12], size_t unlen, u_int gen)
+{
+ int i, j, l;
+ int conv = 1;
+ const u_char *cp, *dp, *dp1;
+ u_char gentext[6], *wcp;
+ int shortlen;
+
+ /*
+ * 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;
+
+ /*
+ * 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++) {
+ if (dp[i] != (dn[j] = unix2dos[dp[i]])
+ && conv != 3)
+ conv = 2;
+ if (!dn[j]) {
+ conv = 3;
+ dn[j--] = ' ';
+ }
+ }
+ if (i < l)
+ conv = 3;
+ dp--;
+ } else {
+ for (dp = cp; *--dp == ' ' || *dp == '.';);
+ dp++;
+ }
+
+ shortlen = (dp - un) <= 8;
+
+ /*
+ * Now convert the rest of the name
+ */
+ for (i = j = 0; un < dp && j < 8; i++, j++, un++) {
+ if ((*un == ' ') && shortlen)
+ dn[j] = ' ';
+ else
+ dn[j] = unix2dos[*un];
+ if ((*un != dn[j])
+ && conv != 3)
+ conv = 2;
+ if (!dn[j]) {
+ 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
+ */
+ 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;
+}
+
+
+/*
+ * Convert 8bit character string into UCS-2 string
+ * return total number of output chacters
+ */
+static int
+char8ucs2str(const uint8_t *in, int n, uint16_t *out, int m)
+{
+ uint16_t *p;
+
+ p = out;
+ while (n > 0 && in[0] != 0) {
+ if (m < 1)
+ break;
+ if (p)
+ p[0] = htole16(in[0]);
+ p += 1;
+ m -= 1;
+ in += 1;
+ n -= 1;
+ }
+
+ return p - out;
+}
+
+static void
+ucs2pad(uint16_t *buf, int len, int size)
+{
+
+ if (len < size-1)
+ buf[len++] = 0x0000;
+ while (len < size)
+ buf[len++] = 0xffff;
+}
+
+/*
+ * Compare two 8bit char conversions case-insensitive
+ *
+ * uses the DOS case folding table
+ */
+static int
+char8match(uint16_t *w1, uint16_t *w2, int n)
+{
+ uint16_t u1, u2;
+
+ while (n > 0) {
+ u1 = le16toh(*w1);
+ u2 = le16toh(*w2);
+ if (u1 == 0 || u2 == 0)
+ return u1 == u2;
+ if (u1 > 255 || u2 > 255)
+ return 0;
+ u1 = u2l[u1 & 0xff];
+ u2 = u2l[u2 & 0xff];
+ if (u1 != u2)
+ return 0;
+ ++w1;
+ ++w2;
+ --n;
+ }
+
+ return 1;
+}
Index: usr.sbin/makefs/msdos/msdosfs_denode.c
===================================================================
--- usr.sbin/makefs/msdos/msdosfs_denode.c
+++ usr.sbin/makefs/msdos/msdosfs_denode.c
@@ -47,24 +47,29 @@
* October 1992
*/
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/vnode.h>
-#include <ffs/buf.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <util.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>
-#include <util.h>
+#include "makefs.h"
+#include "msdos.h"
+
+#include "ffs/buf.h"
+
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
/*
* If deget() succeeds it returns with the gotten denode locked().
@@ -81,20 +86,15 @@
int
deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
struct denode **depp)
- /* pmp: so we know the maj/min number */
- /* dirclust: cluster this dir entry came from */
- /* diroffset: index of entry within the cluster */
- /* depp: returns the addr of the gotten denode */
{
int error;
+ uint64_t inode;
struct direntry *direntptr;
struct denode *ldep;
struct buf *bp;
-#ifdef MSDOSFS_DEBUG
- printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n",
- pmp, dirclust, diroffset, depp);
-#endif
+ MSDOSFS_DPRINTF(("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n",
+ pmp, dirclust, diroffset, depp));
/*
* On FAT32 filesystems, root is a (more or less) normal
@@ -103,18 +103,17 @@
if (FAT32(pmp) && dirclust == MSDOSFSROOT)
dirclust = pmp->pm_rootdirblk;
+ inode = (uint64_t)pmp->pm_bpcluster * dirclust + diroffset;
+
ldep = ecalloc(1, sizeof(*ldep));
ldep->de_vnode = NULL;
ldep->de_flag = 0;
- ldep->de_devvp = 0;
- ldep->de_lockf = 0;
- ldep->de_dev = pmp->pm_dev;
ldep->de_dirclust = dirclust;
ldep->de_diroffset = diroffset;
+ ldep->de_inode = inode;
ldep->de_pmp = pmp;
- ldep->de_devvp = pmp->pm_devvp;
ldep->de_refcnt = 1;
- fc_purge(ldep, 0);
+ fc_purge(ldep, 0); /* init the FAT cache for this denode */
/*
* Copy the directory entry into the denode area of the vnode.
*/
@@ -131,12 +130,13 @@
ldep->de_vnode = (struct vnode *)-1;
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 * pmp->pm_BytesPerSec;
+ ldep->de_FileSize = pmp->pm_rootdirsize * DEV_BSIZE;
}
/*
* fill in time and date so that dos2unixtime() doesn't
@@ -155,11 +155,12 @@
} else {
error = readep(pmp, dirclust, diroffset, &bp, &direntptr);
if (error) {
- ldep->de_devvp = NULL;
ldep->de_Name[0] = SLOT_DELETED;
+
+ *depp = NULL;
return (error);
}
- DE_INTERNALIZE(ldep, direntptr);
+ (void)DE_INTERNALIZE(ldep, direntptr);
brelse(bp);
}
@@ -176,13 +177,27 @@
*/
u_long size;
+ /*
+ * XXX it sometimes happens that the "." entry has cluster
+ * number 0 when it shouldn't. Use the actual cluster number
+ * instead of what is written in directory entry.
+ */
+ if (diroffset == 0 && ldep->de_StartCluster != dirclust) {
+ MSDOSFS_DPRINTF(("deget(): \".\" entry at clust %lu != %lu\n",
+ dirclust, ldep->de_StartCluster));
+
+ ldep->de_StartCluster = dirclust;
+ }
+
if (ldep->de_StartCluster != MSDOSFSROOT) {
- error = pcbmap(ldep, CLUST_END, 0, &size, 0);
+ 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 {
+ MSDOSFS_DPRINTF(("deget(): pcbmap returned %d\n",
+ error));
+ }
}
}
*depp = ldep;
@@ -193,21 +208,20 @@
* Truncate the file described by dep to the length specified by length.
*/
int
-detrunc(struct denode *dep, u_long length, int flags, struct kauth_cred *cred)
+detrunc(struct denode *dep, u_long length, int flags)
{
int error;
- int allerror = 0;
+ int allerror;
u_long eofentry;
- u_long chaintofree = 0;
- daddr_t bn, lastblock;
+ 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
+ MSDOSFS_DPRINTF(("detrunc(): file %s, length %lu, flags %x\n",
+ dep->de_Name, length, flags));
/*
* Disallow attempts to truncate the root directory since it is of
@@ -218,14 +232,15 @@
* directory's life.
*/
if (dep->de_vnode != NULL && !FAT32(pmp)) {
- printf("detrunc(): can't truncate root directory, clust %ld, offset %ld\n",
- dep->de_dirclust, dep->de_diroffset);
+ MSDOSFS_DPRINTF(("detrunc(): can't truncate root directory, "
+ "clust %ld, offset %ld\n",
+ dep->de_dirclust, dep->de_diroffset));
+
return (EINVAL);
}
if (dep->de_FileSize < length)
- return (deextend(dep, length, cred));
- lastblock = de_clcount(pmp, length) - 1;
+ return deextend(dep, length);
/*
* If the desired length is 0 then remember the starting cluster of
@@ -241,15 +256,17 @@
dep->de_StartCluster = 0;
eofentry = ~0;
} else {
- error = pcbmap(dep, lastblock, 0, &eofentry, 0);
+ 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);
+ MSDOSFS_DPRINTF(("detrunc(): pcbmap fails %d\n",
+ error));
+ 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
@@ -258,13 +275,14 @@
if ((boff = length & pmp->pm_crbomask) != 0) {
if (isadir) {
bn = cntobn(pmp, eofentry);
- error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn),
- pmp->pm_bpcluster, B_MODIFY, &bp);
+ error = bread(pmp->pm_devvp, bn, pmp->pm_bpcluster,
+ 0, &bp);
if (error) {
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): bread fails %d\n", error);
-#endif
- return (error);
+ brelse(bp);
+ MSDOSFS_DPRINTF(("detrunc(): bread fails %d\n",
+ error));
+
+ return error;
}
memset((char *)bp->b_data + boff, 0,
pmp->pm_bpcluster - boff);
@@ -282,41 +300,40 @@
dep->de_FileSize = length;
if (!isadir)
dep->de_flag |= DE_UPDATE|DE_MODIFIED;
-#ifdef MSDOSFS_DEBUG
- printf("detrunc(): allerror %d, eofentry %lu\n",
- allerror, eofentry);
-#endif
+ MSDOSFS_DPRINTF(("detrunc(): allerror %d, eofentry %lu\n",
+ allerror, eofentry));
/*
* If we need to break the cluster chain for the file then do it
* now.
*/
- if (eofentry != (u_long)~0) {
+ 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
+ MSDOSFS_DPRINTF(("detrunc(): fatentry errors %d\n",
+ error));
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(chaintofree, pmp->pm_fatmask))
+ if (chaintofree != 0 && !MSDOSFSEOF(pmp, chaintofree))
freeclusterchain(pmp, chaintofree);
- return (allerror);
+ return allerror;
}
/*
* Extend the file described by dep to length specified by length.
*/
int
-deextend(struct denode *dep, u_long length, struct kauth_cred *cred)
+deextend(struct denode *dep, u_long length)
{
struct msdosfsmount *pmp = dep->de_pmp;
u_long count;
@@ -347,7 +364,7 @@
error = extendfile(dep, count, NULL, NULL, DE_CLEAR);
if (error) {
/* truncate the added clusters away again */
- (void) detrunc(dep, dep->de_FileSize, 0, cred);
+ (void) detrunc(dep, dep->de_FileSize, 0);
return (error);
}
}
@@ -358,6 +375,6 @@
* is zero'd later.
*/
dep->de_FileSize = length;
- dep->de_flag |= DE_UPDATE|DE_MODIFIED;
+ dep->de_flag |= DE_UPDATE | DE_MODIFIED;
return 0;
}
Index: usr.sbin/makefs/msdos/msdosfs_fat.c
===================================================================
--- usr.sbin/makefs/msdos/msdosfs_fat.c
+++ usr.sbin/makefs/msdos/msdosfs_fat.c
@@ -49,18 +49,27 @@
*/
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
+#include <sys/errno.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
#include <fs/msdosfs/bpb.h>
-#include <fs/msdosfs/direntry.h>
-#include <fs/msdosfs/denode.h>
-#include <fs/msdosfs/fat.h>
-#include <fs/msdosfs/msdosfsmount.h>
-#define FULL_RUN ((u_int)0xffffffff)
+#include "ffs/buf.h"
+
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
+
+#include "makefs.h"
+#include "msdos.h"
+
+#define FULL_RUN ((u_int)0xffffffff)
+#define SYNCHRONOUS_WRITES(pmp) 1
static int chainalloc(struct msdosfsmount *pmp, u_long start,
u_long count, u_long fillwith, u_long *retcluster,
@@ -90,7 +99,7 @@
u_long bn, size;
bn = ofs / pmp->pm_fatblocksize * pmp->pm_fatblocksec;
- size = min(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn)
+ size = MIN(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn)
* DEV_BSIZE;
bn += pmp->pm_fatblk + pmp->pm_curfat * pmp->pm_FATsecs;
@@ -136,9 +145,7 @@
struct msdosfsmount *pmp = dep->de_pmp;
u_long bsize;
- KASSERT(bnp != NULL || cnp != NULL || sp != NULL,
- ("pcbmap: extra call"));
- ASSERT_VOP_ELOCKED(DETOV(dep), "pcbmap");
+ assert(bnp != NULL || cnp != NULL || sp != NULL);
cn = dep->de_StartCluster;
/*
@@ -159,7 +166,7 @@
if (cnp)
*cnp = MSDOSFSROOT;
if (sp)
- *sp = min(pmp->pm_bpcluster,
+ *sp = MIN(pmp->pm_bpcluster,
dep->de_FileSize - de_cn2off(pmp, findcn));
return (0);
} else { /* just an empty file */
@@ -260,8 +267,6 @@
u_long cn;
struct fatcache *closest = NULL;
- ASSERT_VOP_LOCKED(DETOV(dep), "fc_lookup");
-
for (i = 0; i < FC_SIZE; i++) {
cn = dep->de_fc[i].fc_frcn;
if (cn != FCE_EMPTY && cn <= findcn) {
@@ -285,8 +290,6 @@
int i;
struct fatcache *fcp;
- ASSERT_VOP_ELOCKED(DETOV(dep), "fc_purge");
-
fcp = dep->de_fc;
for (i = 0; i < FC_SIZE; i++, fcp++) {
if (fcp->fc_frcn >= frcn)
@@ -341,7 +344,7 @@
((uint8_t *)bpn->b_data)[3] |= 0x80;
else if (cleanfat == 32)
((uint8_t *)bpn->b_data)[7] |= 0x08;
- if (pmp->pm_mountp->mnt_flag & MNT_SYNCHRONOUS)
+ if (SYNCHRONOUS_WRITES(pmp))
bwrite(bpn);
else
bdwrite(bpn);
@@ -351,7 +354,7 @@
/*
* Write out the first (or current) FAT last.
*/
- if (pmp->pm_mountp->mnt_flag & MNT_SYNCHRONOUS)
+ if (SYNCHRONOUS_WRITES(pmp))
bwrite(bp);
else
bdwrite(bp);
@@ -380,17 +383,13 @@
usemap_alloc(struct msdosfsmount *pmp, u_long cn)
{
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
+ assert(cn <= pmp->pm_maxcluster);
+ assert((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0);
+ assert((pmp->pm_inusemap[cn / N_INUSEBITS] &
+ (1 << (cn % N_INUSEBITS))) == 0);
+ assert(pmp->pm_freeclustercount > 0);
- KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
- pmp->pm_maxcluster));
- KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
- ("usemap_alloc on ro msdosfs mount"));
- KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
- == 0, ("Allocating used sector %ld %ld %x", cn, cn % N_INUSEBITS,
- (unsigned)pmp->pm_inusemap[cn / N_INUSEBITS]));
pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
- KASSERT(pmp->pm_freeclustercount > 0, ("usemap_alloc: too little"));
pmp->pm_freeclustercount--;
pmp->pm_flags |= MSDOSFS_FSIMOD;
}
@@ -399,17 +398,13 @@
usemap_free(struct msdosfsmount *pmp, u_long cn)
{
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
+ assert(cn <= pmp->pm_maxcluster);
+ assert((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0);
+ assert((pmp->pm_inusemap[cn / N_INUSEBITS] &
+ (1 << (cn % N_INUSEBITS))) != 0);
- KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
- pmp->pm_maxcluster));
- KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
- ("usemap_free on ro msdosfs mount"));
pmp->pm_freeclustercount++;
pmp->pm_flags |= MSDOSFS_FSIMOD;
- KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
- != 0, ("Freeing unused sector %ld %ld %x", cn, cn % N_INUSEBITS,
- (unsigned)pmp->pm_inusemap[cn / N_INUSEBITS]));
pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
}
@@ -427,9 +422,7 @@
* the count of free clusters, and turn off the "allocated"
* bit in the "in use" cluster bit map.
*/
- MSDOSFS_LOCK_MP(pmp);
usemap_free(pmp, cluster);
- MSDOSFS_UNLOCK_MP(pmp);
if (oldcnp)
*oldcnp = oldcn;
return (0);
@@ -640,8 +633,6 @@
u_int map;
u_long len;
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
-
if (start > pmp->pm_maxcluster)
return (0);
max_idx = pmp->pm_maxcluster / N_INUSEBITS;
@@ -697,9 +688,7 @@
int error;
u_long cl, n;
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
- KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
- ("chainalloc on ro msdosfs mount"));
+ assert((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0);
for (cl = start, n = count; n-- > 0;)
usemap_alloc(pmp, cl++);
@@ -741,9 +730,7 @@
{
int error;
- MSDOSFS_LOCK_MP(pmp);
error = clusteralloc1(pmp, start, count, fillwith, retcluster, got);
- MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
@@ -756,11 +743,8 @@
u_long foundcn = 0; /* XXX: foundcn could be used unititialized */
u_int map;
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
+ MSDOSFS_DPRINTF(("clusteralloc(): find %lu clusters\n", count));
-#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));
@@ -831,7 +815,6 @@
u_long bn, bo, bsize, byteoffset;
u_long readcn, lbn = -1;
- MSDOSFS_LOCK_MP(pmp);
while (cluster >= CLUST_FIRST && cluster <= pmp->pm_maxcluster) {
byteoffset = FATOFS(pmp, cluster);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
@@ -841,7 +824,6 @@
error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
if (error) {
brelse(bp);
- MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
lbn = bn;
@@ -877,7 +859,6 @@
}
if (bp)
updatefats(pmp, bp, bn);
- MSDOSFS_UNLOCK_MP(pmp);
return (0);
}
@@ -893,8 +874,6 @@
int error;
u_long bn, bo, bsize, byteoffset;
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
-
/*
* Mark all clusters in use, we mark the free ones in the FAT scan
* loop further down.
@@ -967,7 +946,6 @@
u_long cn, got;
struct msdosfsmount *pmp = dep->de_pmp;
struct buf *bp;
- daddr_t blkno;
/*
* Don't try to extend the root directory
@@ -1045,117 +1023,22 @@
*/
fc_setcache(dep, FC_LASTFC, frcn + got - 1, cn + got - 1);
- if (flags & DE_CLEAR) {
+ if ((flags & DE_CLEAR) &&
+ (dep->de_Attributes & ATTR_DIRECTORY)) {
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, 0);
- else {
- bp = getblk(DETOV(dep),
- frcn++,
- pmp->pm_bpcluster, 0, 0, 0);
- /*
- * Do the bmap now, as in msdosfs_write
- */
- if (pcbmap(dep,
- bp->b_lblkno,
- &blkno, 0, 0))
- bp->b_blkno = -1;
- if (bp->b_blkno == -1)
- panic("extendfile: pcbmap");
- else
- bp->b_blkno = blkno;
- }
- vfs_bio_clrbuf(bp);
+ bp = getblk(pmp->pm_devvp,
+ cntobn(pmp, cn++),
+ pmp->pm_bpcluster, 0, 0, 0);
+ clrbuf(bp);
if (bpp) {
*bpp = bp;
bpp = NULL;
- } else
+ } else {
bdwrite(bp);
+ }
}
}
}
return (0);
}
-
-/*-
- * Routine to mark a FAT16 or FAT32 volume as "clean" or "dirty" by
- * manipulating the upper bit of the FAT entry for cluster 1. Note that
- * this bit is not defined for FAT12 volumes, which are always assumed to
- * be clean.
- *
- * The fatentry() routine only works on cluster numbers that a file could
- * occupy, so it won't manipulate the entry for cluster 1. So we have to do
- * it here. The code was stolen from fatentry() and tailored for cluster 1.
- *
- * Inputs:
- * pmp The MS-DOS volume to mark
- * dirty Non-zero if the volume should be marked dirty; zero if it
- * should be marked clean
- *
- * Result:
- * 0 Success
- * EROFS Volume is read-only
- * ? (other errors from called routines)
- */
-int
-markvoldirty(struct msdosfsmount *pmp, int dirty)
-{
- struct buf *bp;
- u_long bn, bo, bsize, byteoffset, fatval;
- int error;
-
- /*
- * FAT12 does not support a "clean" bit, so don't do anything for
- * FAT12.
- */
- if (FAT12(pmp))
- return (0);
-
- /* Can't change the bit on a read-only filesystem. */
- if (pmp->pm_flags & MSDOSFSMNT_RONLY)
- return (EROFS);
-
- /*
- * Fetch the block containing the FAT entry. It is given by the
- * pseudo-cluster 1.
- */
- byteoffset = FATOFS(pmp, 1);
- fatblock(pmp, byteoffset, &bn, &bsize, &bo);
- error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
-
- /*
- * Get the current value of the FAT entry and set/clear the relevant
- * bit. Dirty means clear the "clean" bit; clean means set the
- * "clean" bit.
- */
- if (FAT32(pmp)) {
- /* FAT32 uses bit 27. */
- fatval = getulong(&bp->b_data[bo]);
- if (dirty)
- fatval &= 0xF7FFFFFF;
- else
- fatval |= 0x08000000;
- putulong(&bp->b_data[bo], fatval);
- } else {
- /* Must be FAT16; use bit 15. */
- fatval = getushort(&bp->b_data[bo]);
- if (dirty)
- fatval &= 0x7FFF;
- else
- fatval |= 0x8000;
- putushort(&bp->b_data[bo], fatval);
- }
-
- /* Write out the modified FAT block synchronously. */
- return (bwrite(bp));
-}
Index: usr.sbin/makefs/msdos/msdosfs_lookup.c
===================================================================
--- usr.sbin/makefs/msdos/msdosfs_lookup.c
+++ usr.sbin/makefs/msdos/msdosfs_lookup.c
@@ -49,540 +49,22 @@
*/
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/vnode.h>
+#include <sys/errno.h>
-#include <fs/msdosfs/bpb.h>
-#include <fs/msdosfs/direntry.h>
-#include <fs/msdosfs/denode.h>
-#include <fs/msdosfs/fat.h>
-#include <fs/msdosfs/msdosfsmount.h>
-
-static int msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
- struct componentname *cnp, uint64_t *inum);
-
-int
-msdosfs_lookup(struct vop_cachedlookup_args *ap)
-{
-
- return (msdosfs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
-}
-
-struct deget_dotdot {
- u_long cluster;
- int blkoff;
-};
-
-static int
-msdosfs_deget_dotdot(struct mount *mp, void *arg, int lkflags,
- struct vnode **rvp)
-{
- struct deget_dotdot *dd_arg;
- struct denode *rdp;
- struct msdosfsmount *pmp;
- int error;
-
- pmp = VFSTOMSDOSFS(mp);
- dd_arg = arg;
- error = deget(pmp, dd_arg->cluster, dd_arg->blkoff, &rdp);
- if (error == 0)
- *rvp = DETOV(rdp);
- return (error);
-}
-
-/*
- * 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.
- */
-static int
-msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
- struct componentname *cnp, uint64_t *dd_inum)
-{
- struct mbnambuf nb;
- daddr_t bn;
- int error;
- 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 = NULL;
- struct direntry *dep = NULL;
- struct deget_dotdot dd_arg;
- u_char dosfilename[12];
- int flags = cnp->cn_flags;
- int nameiop = cnp->cn_nameiop;
- int unlen;
- uint64_t inode1;
-
- int wincnt = 1;
- int chksum = -1, chksum_ok;
- int olddos = 1;
-
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
-#endif
- dp = VTODE(vdp);
- pmp = dp->de_pmp;
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
- vdp, dp, dp->de_Attributes);
-#endif
-
- restart:
- if (vpp != NULL)
- *vpp = NULL;
- /*
- * 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_vflag & VV_ROOT) && 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)) {
- case 0:
- return (EINVAL);
- case 1:
- break;
- case 2:
- wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen, pmp) + 1;
- break;
- case 3:
- olddos = 0;
- wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen, pmp) + 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;
- mbnambuf_init(&nb);
- /*
- * 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;
- mbnambuf_init(&nb);
-
- 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 = win2unixfn(&nb,
- (struct winentry *)dep, chksum,
- pmp);
- continue;
- }
-
- chksum = winChkName(&nb,
- (const u_char *)cnp->cn_nameptr, unlen,
- chksum, pmp);
- if (chksum == -2) {
- chksum = -1;
- 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
- */
- chksum_ok = (chksum == winChksum(dep->deName));
- if (!chksum_ok
- && (!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;
- if (chksum_ok && nameiop == RENAME) {
- /*
- * Target had correct long name
- * directory entries, reuse them
- * as needed.
- */
- dp->de_fndcnt = wincnt - 1;
- } else {
- /*
- * Long name directory entries
- * not present or corrupt, can only
- * reuse dos directory entry.
- */
- dp->de_fndcnt = 0;
- }
-
- 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_thread);
- 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;
- return (EJUSTRETURN);
- }
-#if 0
- /*
- * Insert name into cache (as non-existent) if appropriate.
- *
- * XXX Negative caching is broken for msdosfs because the name
- * cache doesn't understand peculiarities such as case insensitivity
- * and 8.3 filenames. Hence, it may not invalidate all negative
- * entries if a file with this name is later created.
- */
- if ((cnp->cn_flags & MAKEENTRY) != 0)
- cache_enter(vdp, *vpp, cnp);
-#endif
- 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 = NULL;
-
-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 (dd_inum != NULL) {
- *dd_inum = (uint64_t)pmp->pm_bpcluster * scn + blkoff;
- return (0);
- }
-
- /*
- * If deleting, and at end of pathname, return
- * parameters which can be used to remove file.
- */
- if (nameiop == DELETE && (flags & ISLASTCN)) {
- /*
- * Don't allow deleting the root.
- */
- if (blkoff == MSDOSFSROOT_OFS)
- return (EBUSY);
+#include <stdio.h>
+#include <string.h>
- /*
- * Write access to directory required to delete files.
- */
- error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_thread);
- 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);
- 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 && (flags & ISLASTCN)) {
- if (blkoff == MSDOSFSROOT_OFS)
- return (EBUSY);
-
- error = VOP_ACCESS(vdp, VWRITE, cnp->cn_cred, cnp->cn_thread);
- 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);
+#include <fs/msdosfs/bpb.h>
- if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
- return (error);
- *vpp = DETOV(tdp);
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
+#include "ffs/buf.h"
- /*
- * 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.
- */
- pdp = vdp;
- if (flags & ISDOTDOT) {
- dd_arg.cluster = cluster;
- dd_arg.blkoff = blkoff;
- error = vn_vget_ino_gen(vdp, msdosfs_deget_dotdot,
- &dd_arg, cnp->cn_lkflags, vpp);
- if (error != 0) {
- *vpp = NULL;
- return (error);
- }
- /*
- * Recheck that ".." still points to the inode we
- * looked up before pdp lock was dropped.
- */
- error = msdosfs_lookup_(pdp, NULL, cnp, &inode1);
- if (error) {
- vput(*vpp);
- *vpp = NULL;
- return (error);
- }
- if (VTODE(*vpp)->de_inode != inode1) {
- vput(*vpp);
- goto restart;
- }
- } 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);
- *vpp = DETOV(tdp);
- }
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
- /*
- * Insert name into cache if appropriate.
- */
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(vdp, *vpp, cnp);
- return (0);
-}
+#include "makefs.h"
+#include "msdos.h"
/*
* dep - directory entry to copy into the directory
@@ -603,10 +85,8 @@
daddr_t bn;
int blsize;
-#ifdef MSDOSFS_DEBUG
- printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n",
- dep, ddep, depp, cnp);
-#endif
+ MSDOSFS_DPRINTF(("createde(dep %p, ddep %p, depp %p, cnp %p)\n",
+ dep, ddep, depp, cnp));
/*
* If no space left in the directory then allocate another cluster
@@ -622,7 +102,7 @@
dirclust = de_clcount(pmp, diroffset);
error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR);
if (error) {
- (void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED);
+ (void)detrunc(ddep, ddep->de_FileSize, 0);
return error;
}
@@ -663,9 +143,7 @@
while (--ddep->de_fndcnt >= 0) {
if (!(ddep->de_fndoffset & pmp->pm_crbomask)) {
- if (DOINGASYNC(DETOV(ddep)))
- bdwrite(bp);
- else if ((error = bwrite(bp)) != 0)
+ if ((error = bwrite(bp)) != 0)
return error;
ddep->de_fndoffset -= sizeof(struct direntry);
@@ -688,14 +166,12 @@
ddep->de_fndoffset -= sizeof(struct direntry);
}
if (!unix2winfn(un, unlen, (struct winentry *)ndep,
- cnt++, chksum, pmp))
+ cnt++, chksum))
break;
}
}
- if (DOINGASYNC(DETOV(ddep)))
- bdwrite(bp);
- else if ((error = bwrite(bp)) != 0)
+ if ((error = bwrite(bp)) != 0)
return error;
/*
@@ -717,170 +193,6 @@
return 0;
}
-/*
- * Be sure a directory is empty except for "." and "..". Return 1 if empty,
- * return 0 if not empty or error.
- */
-int
-dosdirempty(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(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);
-#ifdef MSDOSFS_DEBUG
- if (error == ENOTDIR)
- printf("doscheckpath(): .. not a directory?\n");
-#endif
- 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
@@ -922,81 +234,6 @@
bpp, epp));
}
-/*
- * Remove a directory entry. At this point the file represented by the
- * directory entry to be removed is still full length until no one 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.
- *
- * pdep directory where the entry is removed
- * dep file to be removed
- */
-int
-removede(struct denode *pdep, struct denode *dep)
-{
- 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 aggressive 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 (DOINGASYNC(DETOV(pdep)))
- bdwrite(bp);
- else 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
*/
@@ -1014,14 +251,14 @@
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
return (unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
- cnp->cn_namelen, 0, pmp) ? 0 : EINVAL);
+ cnp->cn_namelen, 0) ? 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))
+ cnp->cn_namelen, gen))
return gen == 1 ? EINVAL : EEXIST;
/*
@@ -1039,7 +276,7 @@
return error;
}
for (dentp = (struct direntry *)bp->b_data;
- (char *)dentp < bp->b_data + blsize;
+ (char *)dentp < (char *)bp->b_data + blsize;
dentp++) {
if (dentp->deName[0] == SLOT_EMPTY) {
/*
Index: usr.sbin/makefs/msdos/msdosfs_vfsops.c
===================================================================
--- usr.sbin/makefs/msdos/msdosfs_vfsops.c
+++ usr.sbin/makefs/msdos/msdosfs_vfsops.c
@@ -45,43 +45,35 @@
* October 1992
*/
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
#include <sys/cdefs.h>
-/* $NetBSD: msdosfs_vfsops.c,v 1.10 2016/01/30 09:59:27 mlelstv Exp $ */
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/mount.h>
-#include <ffs/buf.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>
-
-#include <stdio.h>
#include <errno.h>
-#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <util.h>
+#include <fs/msdosfs/bootsect.h>
+#include <fs/msdosfs/bpb.h>
+
+#include <mkfs_msdos.h>
+
#include "makefs.h"
#include "msdos.h"
-#include "mkfs_msdos.h"
-#ifdef MSDOSFS_DEBUG
-#define DPRINTF(a) printf a
-#else
-#define DPRINTF(a)
-#endif
+#include "ffs/buf.h"
+
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
struct msdosfsmount *
-msdosfs_mount(struct vnode *devvp, int flags)
+msdosfs_mount(struct vnode *devvp)
{
struct msdosfsmount *pmp = NULL;
struct buf *bp;
@@ -90,13 +82,11 @@
struct byte_bpb50 *b50;
struct byte_bpb710 *b710;
uint8_t SecPerClust;
- int ronly = 0, error, tmp;
+ int ronly = 0, error;
int bsize;
- struct msdos_options *m = devvp->fs->fs_specific;
- uint64_t psize = m->create_size;
unsigned secsize = 512;
- DPRINTF(("%s(bread 0)\n", __func__));
+ MSDOSFS_DPRINTF(("%s(bread 0)\n", __func__));
if ((error = bread(devvp, 0, secsize, 0, &bp)) != 0)
goto error_exit;
@@ -105,20 +95,17 @@
b50 = (struct byte_bpb50 *)bsp->bs50.bsBPB;
b710 = (struct byte_bpb710 *)bsp->bs710.bsBPB;
- if (!(flags & MSDOSFSMNT_GEMDOSFS)) {
- if (bsp->bs50.bsBootSectSig0 != BOOTSIG0
- || bsp->bs50.bsBootSectSig1 != BOOTSIG1) {
- DPRINTF(("bootsig0 %d bootsig1 %d\n",
- bsp->bs50.bsBootSectSig0,
- bsp->bs50.bsBootSectSig1));
- error = EINVAL;
- goto error_exit;
- }
- bsize = 0;
- } else
- bsize = 512;
+ if (bsp->bs50.bsBootSectSig0 != BOOTSIG0 ||
+ bsp->bs50.bsBootSectSig1 != BOOTSIG1) {
+ MSDOSFS_DPRINTF(("bootsig0 %d bootsig1 %d\n",
+ bsp->bs50.bsBootSectSig0,
+ bsp->bs50.bsBootSectSig1));
+ error = EINVAL;
+ goto error_exit;
+ }
+ bsize = 0;
- pmp = ecalloc(1, sizeof *pmp);
+ pmp = ecalloc(1, sizeof(*pmp));
/*
* Compute several useful quantities from the bpb in the
* bootsector. Copy in the dos 5 variant of the bpb then fix up
@@ -135,30 +122,24 @@
pmp->pm_Heads = getushort(b50->bpbHeads);
pmp->pm_Media = b50->bpbMedia;
- DPRINTF(("%s(BytesPerSec=%u, ResSectors=%u, FATs=%d, RootDirEnts=%u, "
- "Sectors=%u, FATsecs=%lu, SecPerTrack=%u, Heads=%u, Media=%u)\n",
- __func__, pmp->pm_BytesPerSec, pmp->pm_ResSectors, pmp->pm_FATs,
- pmp->pm_RootDirEnts, pmp->pm_Sectors, pmp->pm_FATsecs,
- pmp->pm_SecPerTrack, pmp->pm_Heads, pmp->pm_Media));
- if (!(flags & MSDOSFSMNT_GEMDOSFS)) {
- /* XXX - We should probably check more values here */
- if (!pmp->pm_BytesPerSec || !SecPerClust
- || pmp->pm_SecPerTrack > 63) {
- DPRINTF(("bytespersec %d secperclust %d "
- "secpertrack %d\n",
- pmp->pm_BytesPerSec, SecPerClust,
- pmp->pm_SecPerTrack));
- error = EINVAL;
- goto error_exit;
- }
+ MSDOSFS_DPRINTF(("%s(BytesPerSec=%u, ResSectors=%u, FATs=%d, "
+ "RootDirEnts=%u, Sectors=%u, FATsecs=%lu, SecPerTrack=%u, "
+ "Heads=%u, Media=%u)\n",
+ __func__, pmp->pm_BytesPerSec, pmp->pm_ResSectors,
+ pmp->pm_FATs, pmp->pm_RootDirEnts, pmp->pm_Sectors,
+ pmp->pm_FATsecs, pmp->pm_SecPerTrack, pmp->pm_Heads,
+ pmp->pm_Media));
+
+ /* XXX - We should probably check more values here */
+ if (!pmp->pm_BytesPerSec || !SecPerClust
+ || pmp->pm_SecPerTrack > 63) {
+ MSDOSFS_DPRINTF(("bytespersec %d secperclust %d "
+ "secpertrack %d\n", pmp->pm_BytesPerSec,
+ SecPerClust, pmp->pm_SecPerTrack));
+ error = EINVAL;
+ goto error_exit;
}
- pmp->pm_flags = flags & MSDOSFSMNT_MNTOPT;
- if (pmp->pm_flags & MSDOSFSMNT_GEMDOSFS)
- pmp->pm_flags |= MSDOSFSMNT_NOWIN95;
- if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
- pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
-
if (pmp->pm_Sectors == 0) {
pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs);
pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors);
@@ -167,6 +148,7 @@
pmp->pm_HugeSectors = pmp->pm_Sectors;
}
+ pmp->pm_flags = 0;
if (pmp->pm_RootDirEnts == 0) {
unsigned short vers = getushort(b710->bpbFSVers);
/*
@@ -175,7 +157,7 @@
* do not set these to zero. Therefore, do not insist.
*/
if (pmp->pm_Sectors || pmp->pm_FATsecs || vers) {
- DPRINTF(("sectors %d fatsecs %lu vers %d\n",
+ MSDOSFS_DPRINTF(("sectors %d fatsecs %lu vers %d\n",
pmp->pm_Sectors, pmp->pm_FATsecs, vers));
error = EINVAL;
goto error_exit;
@@ -193,52 +175,9 @@
} else
pmp->pm_flags |= MSDOSFS_FATMIRROR;
- if (flags & MSDOSFSMNT_GEMDOSFS) {
- if (FAT32(pmp)) {
- DPRINTF(("FAT32 for GEMDOS\n"));
- /*
- * GEMDOS doesn't know FAT32.
- */
- error = EINVAL;
- goto error_exit;
- }
-
- /*
- * 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 < bsize)
- || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1))
- || (pmp->pm_HugeSectors == 0)
- || (pmp->pm_HugeSectors * (pmp->pm_BytesPerSec / bsize)
- > psize)) {
- DPRINTF(("consistency checks for GEMDOS\n"));
- error = EINVAL;
- goto error_exit;
- }
- /*
- * XXX - Many parts of the msdosfs driver seem to assume that
- * the number of bytes per logical sector (BytesPerSec) will
- * always be the same as the number of bytes per disk block
- * Let's pretend it is.
- */
- tmp = pmp->pm_BytesPerSec / bsize;
- pmp->pm_BytesPerSec = bsize;
- pmp->pm_HugeSectors *= tmp;
- pmp->pm_HiddenSects *= tmp;
- pmp->pm_ResSectors *= tmp;
- pmp->pm_Sectors *= tmp;
- pmp->pm_FATsecs *= tmp;
- SecPerClust *= tmp;
- }
-
/* Check that fs has nonzero FAT size */
if (pmp->pm_FATsecs == 0) {
- DPRINTF(("FATsecs is 0\n"));
+ MSDOSFS_DPRINTF(("FATsecs is 0\n"));
error = EINVAL;
goto error_exit;
}
@@ -258,22 +197,11 @@
pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize;
}
- pmp->pm_nmbrofclusters = (pmp->pm_HugeSectors - pmp->pm_firstcluster) /
- SecPerClust;
- pmp->pm_maxcluster = pmp->pm_nmbrofclusters + 1;
+ pmp->pm_maxcluster = ((pmp->pm_HugeSectors - pmp->pm_firstcluster) /
+ SecPerClust) + 1;
pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec;
- if (flags & MSDOSFSMNT_GEMDOSFS) {
- if (pmp->pm_nmbrofclusters <= (0xff0 - 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 if (pmp->pm_fatmask == 0) {
+ if (pmp->pm_fatmask == 0) {
if (pmp->pm_maxcluster
<= ((CLUST_RSRVD - CLUST_FIRST) & FAT12_MASK)) {
/*
@@ -306,18 +234,19 @@
pmp->pm_crbomask = pmp->pm_bpcluster - 1;
pmp->pm_cnshift = ffs(pmp->pm_bpcluster) - 1;
- DPRINTF(("%s(fatmask=%lu, fatmult=%u, fatdiv=%u, fatblocksize=%lu, "
- "fatblocksec=%lu, bnshift=%lu, pbcluster=%lu, crbomask=%lu, "
- "cnshift=%lu)\n",
- __func__, pmp->pm_fatmask, pmp->pm_fatmult, pmp->pm_fatdiv,
- pmp->pm_fatblocksize, pmp->pm_fatblocksec, pmp->pm_bnshift,
- pmp->pm_bpcluster, pmp->pm_crbomask, pmp->pm_cnshift));
+ MSDOSFS_DPRINTF(("%s(fatmask=%lu, fatmult=%u, fatdiv=%u, "
+ "fatblocksize=%lu, fatblocksec=%lu, bnshift=%lu, pbcluster=%lu, "
+ "crbomask=%lu, cnshift=%lu)\n",
+ __func__, (unsigned long)pmp->pm_fatmask, pmp->pm_fatmult,
+ pmp->pm_fatdiv, pmp->pm_fatblocksize, pmp->pm_fatblocksec,
+ pmp->pm_bnshift, pmp->pm_bpcluster, pmp->pm_crbomask,
+ pmp->pm_cnshift));
/*
* Check for valid cluster size
* must be a power of 2
*/
if (pmp->pm_bpcluster ^ (1 << pmp->pm_cnshift)) {
- DPRINTF(("bpcluster %lu cnshift %lu\n",
+ MSDOSFS_DPRINTF(("bpcluster %lu cnshift %lu\n",
pmp->pm_bpcluster, pmp->pm_cnshift));
error = EINVAL;
goto error_exit;
@@ -340,16 +269,13 @@
* 2KB or larger sectors, is the fsinfo structure
* padded at the end or in the middle?
*/
- DPRINTF(("%s(bread %lu)\n", __func__,
- (unsigned long)de_bn2kb(pmp, pmp->pm_fsinfo)));
- if ((error = bread(devvp, de_bn2kb(pmp, pmp->pm_fsinfo),
- pmp->pm_BytesPerSec, 0, &bp)) != 0)
+ if ((error = bread(devvp, pmp->pm_fsinfo, pmp->pm_BytesPerSec,
+ 0, &bp)) != 0)
goto error_exit;
fp = (struct fsinfo *)bp->b_data;
if (!memcmp(fp->fsisig1, "RRaA", 4)
&& !memcmp(fp->fsisig2, "rrAa", 4)
- && !memcmp(fp->fsisig3, "\0\0\125\252", 4)
- && !memcmp(fp->fsisig4, "\0\0\125\252", 4))
+ && !memcmp(fp->fsisig3, "\0\0\125\252", 4))
pmp->pm_nxtfree = getulong(fp->fsinxtfree);
else
pmp->pm_fsinfo = 0;
@@ -383,7 +309,7 @@
* Have the inuse map filled in.
*/
if ((error = fillinusemap(pmp)) != 0) {
- DPRINTF(("fillinusemap %d\n", error));
+ MSDOSFS_DPRINTF(("fillinusemap %d\n", error));
goto error_exit;
}
@@ -407,7 +333,7 @@
error_exit:
if (bp)
- brelse(bp, BC_AGE);
+ brelse(bp);
if (pmp) {
if (pmp->pm_inusemap)
free(pmp->pm_inusemap);
Index: usr.sbin/makefs/msdos/msdosfs_vnops.c
===================================================================
--- usr.sbin/makefs/msdos/msdosfs_vnops.c
+++ usr.sbin/makefs/msdos/msdosfs_vnops.c
@@ -46,34 +46,34 @@
*
* October 1992
*/
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/clock.h>
+#include <sys/time.h>
+
#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
#include <unistd.h>
-#include <ffs/buf.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>
#include "makefs.h"
#include "msdos.h"
-#ifdef MSDOSFS_DEBUG
-#define DPRINTF(a) printf a
-#else
-#define DPRINTF(a)
-#endif
+#include "ffs/buf.h"
+
+#include "msdos/denode.h"
+#include "msdos/direntry.h"
+#include "msdos/fat.h"
+#include "msdos/msdosfsmount.h"
+
/*
* Some general notes:
*
@@ -93,28 +93,40 @@
*/
static int msdosfs_wfile(const char *, struct denode *, fsnode *);
+static void unix2fattime(const struct timespec *tsp, uint16_t *ddp,
+ uint16_t *dtp);
static void
-msdosfs_times(struct msdosfsmount *pmp, struct denode *dep,
- const struct stat *st)
+msdosfs_times(struct denode *dep, const struct stat *st)
{
- struct timespec at;
- struct timespec mt;
-
if (stampst.st_ino)
- st = &stampst;
-
-#ifndef HAVE_NBTOOL_CONFIG_H
- at = st->st_atimespec;
- mt = st->st_mtimespec;
-#else
- at.tv_sec = st->st_atime;
- at.tv_nsec = 0;
- mt.tv_sec = st->st_mtime;
- mt.tv_nsec = 0;
-#endif
- unix2dostime(&at, pmp->pm_gmtoff, &dep->de_ADate, NULL, NULL);
- unix2dostime(&mt, pmp->pm_gmtoff, &dep->de_MDate, &dep->de_MTime, NULL);
+ st = &stampst;
+
+ unix2fattime(&st->st_birthtim, &dep->de_CDate, &dep->de_CTime);
+ unix2fattime(&st->st_atim, &dep->de_ADate, NULL);
+ unix2fattime(&st->st_mtim, &dep->de_MDate, &dep->de_MTime);
+}
+
+static void
+unix2fattime(const struct timespec *tsp, uint16_t *ddp, uint16_t *dtp)
+{
+ time_t t1;
+ struct tm lt = {0};
+
+ t1 = tsp->tv_sec;
+ localtime_r(&t1, &lt);
+
+ unsigned long fat_time = ((lt.tm_year - 80) << 25) |
+ ((lt.tm_mon + 1) << 21) |
+ (lt.tm_mday << 16) |
+ (lt.tm_hour << 11) |
+ (lt.tm_min << 5) |
+ (lt.tm_sec >> 1);
+
+ if (ddp != NULL)
+ *ddp = (uint16_t)(fat_time >> 16);
+ if (dtp != NULL)
+ *dtp = (uint16_t)fat_time;
}
/*
@@ -162,12 +174,12 @@
break;
case 2:
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
+ cnp->cn_namelen) + 1;
break;
case 3:
olddos = 0;
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
+ cnp->cn_namelen) + 1;
break;
}
@@ -181,7 +193,7 @@
* case it doesn't already exist.
*/
slotcount = 0;
- DPRINTF(("%s(): dos filename: %s\n", __func__, dosfilename));
+ MSDOSFS_DPRINTF(("%s(): dos filename: %s\n", __func__, dosfilename));
/*
* Search the directory pointed at by vdp for the name pointed at
* by cnp->cn_nameptr.
@@ -200,8 +212,7 @@
break;
return (error);
}
- error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
- 0, &bp);
+ error = bread(pmp->pm_devvp, bn, blsize, 0, &bp);
if (error) {
return (error);
}
@@ -248,11 +259,10 @@
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
continue;
- chksum = winChkName((const u_char *)cnp->cn_nameptr,
- cnp->cn_namelen,
- (struct winentry *)dep,
- chksum,
- pmp->pm_flags & MSDOSFSMNT_UTF8);
+ chksum = winChkName(
+ (const u_char *)cnp->cn_nameptr,
+ cnp->cn_namelen,
+ (struct winentry *)dep, chksum);
continue;
}
@@ -274,7 +284,7 @@
chksum = -1;
continue;
}
- DPRINTF(("%s(): match blkoff %d, diroff %d\n",
+ MSDOSFS_DPRINTF(("%s(): match blkoff %d, diroff %u\n",
__func__, blkoff, diroff));
/*
* Remember where this directory
@@ -304,7 +314,7 @@
* that's ok if we are creating or renaming and are at the end of
* the pathname and the directory hasn't been removed.
*/
- DPRINTF(("%s(): refcnt %ld, slotcount %d, slotoffset %d\n",
+ MSDOSFS_DPRINTF(("%s(): refcnt %ld, slotcount %d, slotoffset %d\n",
__func__, dp->de_refcnt, slotcount, slotoffset));
/*
* Fixup the slot description to point to the place where
@@ -352,13 +362,12 @@
struct denode *dep;
int error;
struct stat *st = &node->inode->st;
- struct msdosfsmount *pmp = pdep->de_pmp;
cn.cn_nameptr = node->name;
cn.cn_namelen = strlen(node->name);
- DPRINTF(("%s(name %s, mode 0%o size %zu)\n", __func__, node->name,
- st->st_mode, (size_t)st->st_size));
+ MSDOSFS_DPRINTF(("%s(name %s, mode 0%o size %zu)\n",
+ __func__, node->name, st->st_mode, (size_t)st->st_size));
/*
* If this is the root directory and there is no space left we
@@ -385,11 +394,10 @@
ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY;
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;
- msdosfs_times(pmp, &ndirent, st);
+ msdosfs_times(&ndirent, &node->inode->st);
+
if ((error = msdosfs_findslot(pdep, &cn)) != 0)
goto bad;
if ((error = createde(&ndirent, pdep, &dep, &cn)) != 0)
@@ -434,8 +442,9 @@
u_long cn = 0;
error = 0; /* XXX: gcc/vax */
- DPRINTF(("%s(diroff %lu, dirclust %lu, startcluster %lu)\n", __func__,
- dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster));
+ MSDOSFS_DPRINTF(("%s(diroff %lu, dirclust %lu, startcluster %lu)\n",
+ __func__, dep->de_diroffset, dep->de_dirclust,
+ dep->de_StartCluster));
if (st->st_size == 0)
return 0;
@@ -444,9 +453,9 @@
return EFBIG;
nsize = st->st_size;
- DPRINTF(("%s(nsize=%zu, osize=%zu)\n", __func__, nsize, osize));
+ MSDOSFS_DPRINTF(("%s(nsize=%zu, osize=%zu)\n", __func__, nsize, osize));
if (nsize > osize) {
- if ((error = deextend(dep, nsize, NULL)) != 0)
+ if ((error = deextend(dep, nsize)) != 0)
return error;
if ((error = msdosfs_updatede(dep)) != 0)
return error;
@@ -454,14 +463,14 @@
if ((fd = open(path, O_RDONLY)) == -1) {
error = errno;
- DPRINTF((1, "open %s: %s", path, strerror(error)));
+ MSDOSFS_DPRINTF(("open %s: %s", path, strerror(error)));
return error;
}
if ((dat = mmap(0, nsize, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0))
== MAP_FAILED) {
error = errno;
- DPRINTF(("%s: mmap %s: %s", __func__, node->name,
+ MSDOSFS_DPRINTF(("%s: mmap %s: %s", __func__, node->name,
strerror(error)));
close(fd);
goto out;
@@ -472,27 +481,17 @@
int blsize, cpsize;
daddr_t bn;
u_long on = offs & pmp->pm_crbomask;
-#ifdef HACK
- cn = dep->de_StartCluster;
- if (cn == MSDOSFSROOT) {
- DPRINTF(("%s: bad lbn %lu", __func__, cn));
- error = EINVAL;
- goto out;
- }
- bn = cntobn(pmp, cn);
- blsize = pmp->pm_bpcluster;
-#else
+
if ((error = pcbmap(dep, cn++, &bn, NULL, &blsize)) != 0) {
- DPRINTF(("%s: pcbmap %lu", __func__, bn));
+ MSDOSFS_DPRINTF(("%s: pcbmap %lu",
+ __func__, (unsigned long)bn));
goto out;
}
-#endif
- DPRINTF(("%s(cn=%lu, bn=%llu/%llu, blsize=%d)\n", __func__,
- cn, (unsigned long long)bn,
- (unsigned long long)de_bn2kb(pmp, bn), blsize));
- if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize,
- 0, &bp)) != 0) {
- DPRINTF(("bread %d\n", error));
+
+ MSDOSFS_DPRINTF(("%s(cn=%lu, bn=%llu, blsize=%d)\n",
+ __func__, cn, (unsigned long long)bn, blsize));
+ if ((error = bread(pmp->pm_devvp, bn, blsize, 0, &bp)) != 0) {
+ MSDOSFS_DPRINTF(("bread %d\n", error));
goto out;
}
cpsize = MIN((nsize - offs), blsize - on);
@@ -508,12 +507,11 @@
return error;
}
-
static const struct {
struct direntry dot;
struct direntry dotdot;
} dosdirtemplate = {
- { ". ", " ", /* the . entry */
+ { ". ", /* the . entry */
ATTR_DIRECTORY, /* file attribute */
0, /* reserved */
0, { 0, 0 }, { 0, 0 }, /* create time & date */
@@ -523,7 +521,7 @@
{ 0, 0 }, /* startcluster */
{ 0, 0, 0, 0 } /* filesize */
},
- { ".. ", " ", /* the .. entry */
+ { ".. ", /* the .. entry */
ATTR_DIRECTORY, /* file attribute */
0, /* reserved */
0, { 0, 0 }, { 0, 0 }, /* create time & date */
@@ -540,11 +538,9 @@
struct denode ndirent;
struct denode *dep;
struct componentname cn;
- struct stat *st = &node->inode->st;
struct msdosfsmount *pmp = pdep->de_pmp;
int error;
u_long newcluster, pcl, bn;
- daddr_t lbn;
struct direntry *denp;
struct buf *bp;
@@ -564,14 +560,14 @@
/*
* Allocate a cluster to hold the about to be created directory.
*/
- error = clusteralloc(pmp, 0, 1, &newcluster, NULL);
+ error = clusteralloc(pmp, 0, 1, CLUST_EOFE, &newcluster, NULL);
if (error)
goto bad2;
memset(&ndirent, 0, sizeof(ndirent));
ndirent.de_pmp = pmp;
ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
- msdosfs_times(pmp, &ndirent, st);
+ msdosfs_times(&ndirent, &node->inode->st);
/*
* Now fill the cluster with the "." and ".." entries. And write
@@ -579,11 +575,10 @@
* directory to be pointing at if there were a crash.
*/
bn = cntobn(pmp, newcluster);
- lbn = de_bn2kb(pmp, bn);
- DPRINTF(("%s(newcluster %lu, bn=%lu, lbn=%lu)\n", __func__, newcluster,
- bn, lbn));
+ MSDOSFS_DPRINTF(("%s(newcluster %lu, bn=%lu)\n",
+ __func__, newcluster, bn));
/* always succeeds */
- bp = getblk(pmp->pm_devvp, lbn, pmp->pm_bpcluster, 0, 0);
+ bp = getblk(pmp->pm_devvp, bn, pmp->pm_bpcluster, 0, 0, 0);
memset(bp->b_data, 0, pmp->pm_bpcluster);
memcpy(bp->b_data, &dosdirtemplate, sizeof dosdirtemplate);
denp = (struct direntry *)bp->b_data;
@@ -595,7 +590,7 @@
putushort(denp[0].deMDate, ndirent.de_MDate);
putushort(denp[0].deMTime, ndirent.de_MTime);
pcl = pdep->de_StartCluster;
- DPRINTF(("%s(pcl %lu, rootdirblk=%lu)\n", __func__, pcl,
+ MSDOSFS_DPRINTF(("%s(pcl %lu, rootdirblk=%lu)\n", __func__, pcl,
pmp->pm_rootdirblk));
if (FAT32(pmp) && pcl == pmp->pm_rootdirblk)
pcl = 0;
@@ -628,8 +623,6 @@
ndirent.de_Attributes = ATTR_DIRECTORY;
ndirent.de_StartCluster = newcluster;
ndirent.de_FileSize = 0;
- ndirent.de_dev = pdep->de_dev;
- ndirent.de_devvp = pdep->de_devvp;
ndirent.de_pmp = pdep->de_pmp;
if ((error = msdosfs_findslot(pdep, &cn)) != 0)
goto bad;
Index: usr.sbin/makefs/msdos/msdosfsmount.h
===================================================================
--- usr.sbin/makefs/msdos/msdosfsmount.h
+++ usr.sbin/makefs/msdos/msdosfsmount.h
@@ -49,38 +49,21 @@
*/
#ifndef _MSDOSFS_MSDOSFSMOUNT_H_
-#define _MSDOSFS_MSDOSFSMOUNT_H_
-
-#ifdef _KERNEL
+#define _MSDOSFS_MSDOSFSMOUNT_H_
#include <sys/types.h>
-#include <sys/lock.h>
-#include <sys/lockmgr.h>
-#include <sys/tree.h>
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_MSDOSFSMNT);
-#endif
-struct msdosfs_fileno;
+struct vnode;
+struct cdev;
+struct bpb50;
/*
* Layout of the mount control block for a MSDOSFS filesystem.
*/
struct msdosfsmount {
- struct mount *pm_mountp;/* vfs mount struct for this fs */
- struct g_consumer *pm_cp;
- struct bufobj *pm_bo;
- 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
- for files */
- mode_t pm_dirmask; /* mask to and with file protection bits
- for directories */
struct vnode *pm_devvp; /* vnode for character device mounted */
struct cdev *pm_dev; /* character device mounted */
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 */
@@ -104,29 +87,11 @@
u_int pm_curfat; /* current FAT for FAT32 (0 otherwise) */
u_int *pm_inusemap; /* ptr to bitmap of in-use clusters */
uint64_t pm_flags; /* see below */
- void *pm_u2w; /* Local->Unicode iconv handle */
- void *pm_w2u; /* Unicode->Local iconv handle */
- void *pm_u2d; /* Unicode->DOS iconv handle */
- void *pm_d2u; /* DOS->Local iconv handle */
- struct lock pm_fatlock; /* lockmgr protecting allocations */
-};
-
-/*
- * A 64-bit file number and the 32-bit file number to which it is mapped,
- * in a red-black tree node.
- */
-struct msdosfs_fileno {
- RB_ENTRY(msdosfs_fileno) mf_tree;
- uint32_t mf_fileno32;
- uint64_t mf_fileno64;
};
/* 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))
@@ -213,33 +178,6 @@
? roottobn((pmp), (dirofs)) \
: cntobn((pmp), (dirclu)))
-#define MSDOSFS_LOCK_MP(pmp) \
- lockmgr(&(pmp)->pm_fatlock, LK_EXCLUSIVE, NULL)
-#define MSDOSFS_UNLOCK_MP(pmp) \
- lockmgr(&(pmp)->pm_fatlock, LK_RELEASE, NULL)
-#define MSDOSFS_ASSERT_MP_LOCKED(pmp) \
- lockmgr_assert(&(pmp)->pm_fatlock, KA_XLOCKED)
-
-#endif /* _KERNEL */
-
-/*
- * Arguments to mount MSDOS filesystems.
- */
-struct msdosfs_args {
- char *fspec; /* blocks special holding the fs to mount */
- struct oexport_args export; /* network export information */
- uid_t uid; /* uid that owns msdosfs files */
- gid_t gid; /* gid that owns msdosfs files */
- mode_t mask; /* file mask to be applied for msdosfs perms */
- int flags; /* see below */
- int unused1; /* unused, was version number */
- uint16_t unused2[128]; /* no longer used, was Local->Unicode table */
- char *cs_win; /* Windows(Unicode) Charset */
- char *cs_dos; /* DOS Charset */
- char *cs_local; /* Local Charset */
- mode_t dirmask; /* dir mask to be applied for msdosfs perms */
-};
-
/*
* Msdosfs mount options:
*/

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 2:31 AM (15 h, 6 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28526740
Default Alt Text
D16438.id61014.diff (97 KB)

Event Timeline