Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144407611
D16438.id45840.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
97 KB
Referenced Files
None
Subscribers
None
D16438.id45840.diff
View Options
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
@@ -200,7 +200,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
@@ -229,6 +231,19 @@
Set the size of the file system image to
.Ar image-size
bytes.
+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.
@@ -251,6 +266,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.
@@ -411,6 +428,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
@@ -74,8 +74,9 @@
# name, name ## _prep_opts, name ## _parse_opts, \
name ## _cleanup_opts, name ## _makefs \
}
- ENTRY(ffs),
ENTRY(cd9660),
+ ENTRY(ffs),
+ ENTRY(msdos),
{ .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.
*/
-struct vnode;
+#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 denode;
+struct fsnode;
+struct msdosfsmount;
+struct vnode;
-struct msdosfsmount *msdosfs_mount(struct vnode *, int);
+struct componentname {
+ char *cn_nameptr;
+ size_t cn_namelen;
+};
+
+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,12 @@
+# $NetBSD: Makefile.inc,v 1.7 2016/02/06 10:40:58 mlelstv Exp $
+#
+
+MSDOS_NEWFS= ${SRCTOP}/sbin/newfs_msdos
+
+.PATH: ${SRCDIR}/msdos ${MSDOS_NEWFS}
+
+CFLAGS+= -I${MSDOS_NEWFS}
+
+SRCS+= msdosfs_denode.c msdosfs_vnops.c msdosfs_vfsops.c msdosfs_conv.c
+SRCS+= msdosfs_fat.c msdosfs_lookup.c
+SRCS+= mkfs_msdos.c
Index: usr.sbin/makefs/msdos/denode.h
===================================================================
--- usr.sbin/makefs/msdos/denode.h
+++ usr.sbin/makefs/msdos/denode.h
@@ -161,7 +161,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) */
};
@@ -174,6 +173,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.
@@ -211,75 +212,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_ */
\ No newline at end of file
Index: usr.sbin/makefs/msdos/direntry.h
===================================================================
--- usr.sbin/makefs/msdos/direntry.h
+++ usr.sbin/makefs/msdos/direntry.h
@@ -135,31 +135,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
@@ -82,7 +82,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().
@@ -96,6 +95,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);
@@ -103,7 +106,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,508 @@
+/*-
+ * 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
@@ -51,18 +51,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,
@@ -92,7 +101,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;
@@ -138,9 +147,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;
/*
@@ -161,7 +168,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 */
@@ -262,8 +269,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) {
@@ -287,8 +292,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)
@@ -343,7 +346,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);
@@ -353,7 +356,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);
@@ -382,17 +385,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;
}
@@ -401,17 +400,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));
}
@@ -429,9 +424,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);
@@ -642,8 +635,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;
@@ -699,9 +690,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++);
@@ -743,9 +732,7 @@
{
int error;
- MSDOSFS_LOCK_MP(pmp);
error = clusteralloc1(pmp, start, count, fillwith, retcluster, got);
- MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
@@ -758,11 +745,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));
@@ -833,7 +817,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);
@@ -843,7 +826,6 @@
error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
if (error) {
brelse(bp);
- MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
lbn = bn;
@@ -879,7 +861,6 @@
}
if (bp)
updatefats(pmp, bp, bn);
- MSDOSFS_UNLOCK_MP(pmp);
return (0);
}
@@ -894,9 +875,7 @@
u_long bn, bo, bsize, byteoffset, cn, readcn;
int error;
- MSDOSFS_ASSERT_MP_LOCKED(pmp);
bp = NULL;
-
/*
* Mark all clusters in use, we mark the free ones in the FAT scan
* loop further down.
@@ -979,7 +958,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
@@ -1057,117 +1035,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;
- }
+ 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
@@ -51,540 +51,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);
- }
+#include <stdio.h>
+#include <string.h>
- /*
- * 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);
-
- /*
- * 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
@@ -605,10 +87,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
@@ -624,7 +104,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;
}
@@ -665,9 +145,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);
@@ -690,14 +168,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;
/*
@@ -719,170 +195,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
@@ -924,81 +236,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
*/
@@ -1013,17 +250,17 @@
daddr_t bn;
struct buf *bp;
int error;
-
+
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
return (unix2dosfn((const u_char *)cnp->cn_nameptr, cp,
- cnp->cn_namelen, 0, pmp) ? 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;
/*
@@ -1041,7 +278,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, <);
+
+ 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
@@ -51,38 +51,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 */
@@ -106,29 +89,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))
@@ -215,33 +180,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
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 7:06 AM (19 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28550848
Default Alt Text
D16438.id45840.diff (97 KB)
Attached To
Mode
D16438: makefs: add msdosfs support
Attached
Detach File
Event Timeline
Log In to Comment