usr.sbin/makefs: Synchronize on NetBSD-current (30/03/2021 16:09 UTC)

This commit is contained in:
Marcelo Alencar 2021-03-31 11:30:25 -03:00
parent fd1285b2ec
commit ba797217b8
58 changed files with 2734 additions and 1079 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2014/03/18 18:20:39 riastradh Exp $
# $NetBSD: Makefile,v 1.7 2020/09/06 07:20:27 mrg Exp $
.include <bsd.own.mk>
@ -14,4 +14,9 @@ CPPFLAGS+= -I${MOUNT} -I${KUDF} -I${NETBSDSRCDIR}/sys
DPADD+=${LIBUTIL}
LDADD+=-lutil
.if !defined(__MINIX)
CWARNFLAGS.clang+= -Wno-error=address-of-packed-member
.endif # !defined(__MINIX)
CWARNFLAGS.gcc+= ${GCC_NO_ADDR_OF_PACKED_MEMBER}
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs_udf.c,v 1.18 2013/08/09 15:11:08 reinoud Exp $ */
/* $NetBSD: newfs_udf.c,v 1.20 2020/04/05 15:25:40 joerg Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
@ -72,7 +72,6 @@
int newfs_udf(int argc, char **argv);
static void usage(void) __attribute__((__noreturn__));
/* queue for temporary storage of sectors to be written out */
struct wrsect {
uint64_t sectornr;
@ -121,11 +120,13 @@ udf_write_sector(void *sector, uint64_t location)
if ((seekpos == NULL) || (seekpos->sectornr != location)) {
pos = calloc(1, sizeof(struct wrsect));
if (pos == NULL)
return ENOMEM;
return errno;
/* allocate space for copy of sector data */
pos->sector_data = calloc(1, context.sector_size);
if (pos->sector_data == NULL)
return ENOMEM;
if (pos->sector_data == NULL) {
free(pos);
return errno;
}
pos->sectornr = location;
if (seekpos) {

View File

@ -1,3 +1,5 @@
/* $NetBSD: newfs_udf.h,v 1.7 2020/04/05 15:25:40 joerg Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
* All rights reserved.
@ -53,8 +55,8 @@ extern float meta_fract;
/* shared structure between udf_create.c users */
struct udf_create_context context;
struct udf_disclayout layout;
extern struct udf_create_context context;
extern struct udf_disclayout layout;
/* prototypes */
int udf_write_sector(void *sector, uint64_t location);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $ */
/* $NetBSD: udf_create.c,v 1.28 2020/05/14 08:34:18 msaitoh Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -30,7 +30,7 @@
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $");
__RCSID("$NetBSD: udf_create.c,v 1.28 2020/05/14 08:34:18 msaitoh Exp $");
#include <stdio.h>
#include <stdlib.h>
@ -52,6 +52,9 @@ __RCSID("$NetBSD: udf_create.c,v 1.25 2015/06/16 23:18:55 christos Exp $");
# endif
#endif
struct udf_create_context context;
struct udf_disclayout layout;
/*
* NOTE that there is some overlap between this code and the udf kernel fs.
* This is intentially though it might better be factored out one day.
@ -339,7 +342,7 @@ udf_calculate_disc_layout(int format_flags, int min_udf,
if (format_flags & FORMAT_META) {
/* note: all in backing partition space */
layout.meta_file = pos++;
layout.meta_bitmap = pos++;;
layout.meta_bitmap = pos++;
layout.meta_mirror = layout.part_size_lba-1;
layout.meta_alignment = MAX(blockingnr, sparable_blockingnr);
layout.meta_blockingnr = MAX(layout.meta_alignment, 32);
@ -1720,10 +1723,10 @@ udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr)
struct extfile_entry *efe;
struct extattrhdr_desc *extattrhdr;
struct impl_extattr_entry *implext;
uint32_t impl_attr_loc, appl_attr_loc, l_ea, a_l, exthdr_len;
uint32_t *l_eap, l_ad;
uint32_t impl_attr_loc, appl_attr_loc, l_ea, l_ad, a_l;
uint16_t *spos;
uint8_t *bpos, *data;
void *l_eap;
if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
fe = &dscr->fe;
@ -1741,27 +1744,22 @@ udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr)
/* should have a header! */
extattrhdr = (struct extattrhdr_desc *) data;
l_ea = udf_rw32(*l_eap);
memcpy(&l_ea, l_eap, sizeof(l_ea));
l_ea = udf_rw32(l_ea);
if (l_ea == 0) {
#if !defined(NDEBUG) && defined(__minix)
uint32_t exthdr_len;
assert(l_ad == 0);
#else
if (l_ad != 0) {
printf("%s:%d: l_ad != 0\n", __func__, __LINE__);
abort();
}
#endif /* !defined(NDEBUG) && defined(__minix) */
/* create empty extended attribute header */
exthdr_len = sizeof(struct extattrhdr_desc);
l_ea = sizeof(struct extattrhdr_desc);
exthdr_len = udf_rw32(l_ea);
udf_inittag(&extattrhdr->tag, TAGID_EXTATTR_HDR, /* loc */ 0);
extattrhdr->impl_attr_loc = udf_rw32(exthdr_len);
extattrhdr->appl_attr_loc = udf_rw32(exthdr_len);
extattrhdr->impl_attr_loc = exthdr_len;
extattrhdr->appl_attr_loc = exthdr_len;
extattrhdr->tag.desc_crc_len = udf_rw16(8);
/* record extended attribute header length */
l_ea = exthdr_len;
*l_eap = udf_rw32(l_ea);
memcpy(l_eap, &exthdr_len, sizeof(exthdr_len));
}
/* extract locations */
@ -1794,7 +1792,7 @@ udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr)
assert(appl_attr_loc == l_ea);
/* append the attribute at the end of the current space */
bpos = data + udf_rw32(*l_eap);
bpos = data + l_ea;
a_l = udf_rw32(extattr->a_l);
/* update impl. attribute locations */
@ -1809,7 +1807,8 @@ udf_extattr_append_internal(union dscrptr *dscr, struct extattr_entry *extattr)
/* copy and advance */
memcpy(bpos, extattr, a_l);
l_ea += a_l;
*l_eap = udf_rw32(l_ea);
l_ea = udf_rw32(l_ea);
memcpy(l_eap, &l_ea, sizeof(l_ea));
/* do the `dance` again backwards */
if (context.dscrver != 2) {
@ -2164,10 +2163,6 @@ udf_create_new_rootdir(union dscrptr **dscr)
struct long_ad root_icb;
int filetype, error;
#if defined(__minix)
/* LSC: -Werror=maybe-uninitialized when compiling with -O3 */
fe = NULL;
#endif /*defined(__minix) */
memset(&root_icb, 0, sizeof(root_icb));
root_icb.len = udf_rw32(context.sector_size);
root_icb.loc.lb_num = udf_rw32(layout.rootdir);

View File

@ -1,4 +1,4 @@
/* $NetBSD: bootsect.h,v 1.5 2012/11/04 17:57:59 jakllsch Exp $ */
/* $NetBSD: bootsect.h,v 1.6 2016/01/22 22:48:18 dholland Exp $ */
/*
* Written by Paul Popelka (paulp@uts.amdahl.com)
@ -24,13 +24,13 @@
* first sector of a partitioned hard disk.
*/
struct bootsector33 {
u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
uint8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
int8_t bsOemName[8]; /* OEM name and version */
int8_t bsBPB[19]; /* BIOS parameter block */
int8_t bsDriveNumber; /* drive number (0x80) */
int8_t bsBootCode[479]; /* pad so struct is 512b */
u_int8_t bsBootSectSig0;
u_int8_t bsBootSectSig1;
uint8_t bsBootSectSig0;
uint8_t bsBootSectSig1;
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
@ -46,25 +46,25 @@ struct extboot {
};
struct bootsector50 {
u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
uint8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
int8_t bsOemName[8]; /* OEM name and version */
int8_t bsBPB[25]; /* BIOS parameter block */
int8_t bsExt[26]; /* Bootsector Extension */
int8_t bsBootCode[448]; /* pad so structure is 512b */
u_int8_t bsBootSectSig0;
u_int8_t bsBootSectSig1;
uint8_t bsBootSectSig0;
uint8_t bsBootSectSig1;
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
struct bootsector710 {
u_int8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
uint8_t bsJump[3]; /* jump inst E9xxxx or EBxx90 */
int8_t bsOEMName[8]; /* OEM name and version */
int8_t bsBPB[53]; /* BIOS parameter block */
int8_t bsExt[26]; /* Bootsector Extension */
int8_t bsBootCode[420]; /* pad so structure is 512b */
u_int8_t bsBootSectSig0;
u_int8_t bsBootSectSig1;
uint8_t bsBootSectSig0;
uint8_t bsBootSectSig1;
#define BOOTSIG0 0x55
#define BOOTSIG1 0xaa
};
@ -76,7 +76,7 @@ struct bootsector710 {
*/
#if 0
struct bootsec_atari {
u_int8_t bsBranch[2]; /* branch inst if auto-boot */
uint8_t bsBranch[2]; /* branch inst if auto-boot */
int8_t bsFiller[6]; /* anything or nothing */
int8_t bsSerial[3]; /* serial no. for mediachange */
int8_t bsBPB[19]; /* BIOS parameter block */

View File

@ -1,4 +1,4 @@
/* $NetBSD: bpb.h,v 1.7 2012/11/04 17:57:59 jakllsch Exp $ */
/* $NetBSD: bpb.h,v 1.8 2016/01/22 22:53:36 dholland Exp $ */
/*
* Written by Paul Popelka (paulp@uts.amdahl.com)
@ -23,17 +23,17 @@
* BIOS Parameter Block (BPB) for DOS 3.3
*/
struct bpb33 {
u_int16_t bpbBytesPerSec; /* bytes per sector */
u_int8_t bpbSecPerClust; /* sectors per cluster */
u_int16_t bpbResSectors; /* number of reserved sectors */
u_int8_t bpbFATs; /* number of FATs */
u_int16_t bpbRootDirEnts; /* number of root directory entries */
u_int16_t bpbSectors; /* total number of sectors */
u_int8_t bpbMedia; /* media descriptor */
u_int16_t bpbFATsecs; /* number of sectors per FAT */
u_int16_t bpbSecPerTrack; /* sectors per track */
u_int16_t bpbHeads; /* number of heads */
u_int16_t bpbHiddenSecs; /* number of hidden sectors */
uint16_t bpbBytesPerSec; /* bytes per sector */
uint8_t bpbSecPerClust; /* sectors per cluster */
uint16_t bpbResSectors; /* number of reserved sectors */
uint8_t bpbFATs; /* number of FATs */
uint16_t bpbRootDirEnts; /* number of root directory entries */
uint16_t bpbSectors; /* total number of sectors */
uint8_t bpbMedia; /* media descriptor */
uint16_t bpbFATsecs; /* number of sectors per FAT */
uint16_t bpbSecPerTrack; /* sectors per track */
uint16_t bpbHeads; /* number of heads */
uint16_t bpbHiddenSecs; /* number of hidden sectors */
};
/*
@ -41,46 +41,46 @@ struct bpb33 {
* and bpbHugeSectors is not in the 3.3 bpb.
*/
struct bpb50 {
u_int16_t bpbBytesPerSec; /* bytes per sector */
u_int8_t bpbSecPerClust; /* sectors per cluster */
u_int16_t bpbResSectors; /* number of reserved sectors */
u_int8_t bpbFATs; /* number of FATs */
u_int16_t bpbRootDirEnts; /* number of root directory entries */
u_int16_t bpbSectors; /* total number of sectors */
u_int8_t bpbMedia; /* media descriptor */
u_int16_t bpbFATsecs; /* number of sectors per FAT */
u_int16_t bpbSecPerTrack; /* sectors per track */
u_int16_t bpbHeads; /* number of heads */
u_int32_t bpbHiddenSecs; /* # of hidden sectors */
u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
uint16_t bpbBytesPerSec; /* bytes per sector */
uint8_t bpbSecPerClust; /* sectors per cluster */
uint16_t bpbResSectors; /* number of reserved sectors */
uint8_t bpbFATs; /* number of FATs */
uint16_t bpbRootDirEnts; /* number of root directory entries */
uint16_t bpbSectors; /* total number of sectors */
uint8_t bpbMedia; /* media descriptor */
uint16_t bpbFATsecs; /* number of sectors per FAT */
uint16_t bpbSecPerTrack; /* sectors per track */
uint16_t bpbHeads; /* number of heads */
uint32_t bpbHiddenSecs; /* # of hidden sectors */
uint32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
};
/*
* BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
*/
struct bpb710 {
u_int16_t bpbBytesPerSec; /* bytes per sector */
u_int8_t bpbSecPerClust; /* sectors per cluster */
u_int16_t bpbResSectors; /* number of reserved sectors */
u_int8_t bpbFATs; /* number of FATs */
u_int16_t bpbRootDirEnts; /* number of root directory entries */
u_int16_t bpbSectors; /* total number of sectors */
u_int8_t bpbMedia; /* media descriptor */
u_int16_t bpbFATsecs; /* number of sectors per FAT */
u_int16_t bpbSecPerTrack; /* sectors per track */
u_int16_t bpbHeads; /* number of heads */
u_int32_t bpbHiddenSecs; /* # of hidden sectors */
u_int32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
u_int32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */
u_int16_t bpbExtFlags; /* extended flags: */
uint16_t bpbBytesPerSec; /* bytes per sector */
uint8_t bpbSecPerClust; /* sectors per cluster */
uint16_t bpbResSectors; /* number of reserved sectors */
uint8_t bpbFATs; /* number of FATs */
uint16_t bpbRootDirEnts; /* number of root directory entries */
uint16_t bpbSectors; /* total number of sectors */
uint8_t bpbMedia; /* media descriptor */
uint16_t bpbFATsecs; /* number of sectors per FAT */
uint16_t bpbSecPerTrack; /* sectors per track */
uint16_t bpbHeads; /* number of heads */
uint32_t bpbHiddenSecs; /* # of hidden sectors */
uint32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
uint32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */
uint16_t bpbExtFlags; /* extended flags: */
#define FATNUM 0xf /* mask for numbering active FAT */
#define FATMIRROR 0x80 /* FAT is mirrored (like it always was) */
u_int16_t bpbFSVers; /* filesystem version */
uint16_t bpbFSVers; /* filesystem version */
#define FSVERS 0 /* currently only 0 is understood */
u_int32_t bpbRootClust; /* start cluster for root directory */
u_int16_t bpbFSInfo; /* filesystem info structure sector */
u_int16_t bpbBackup; /* backup boot sector */
u_int8_t bpbReserved[12]; /* Reserved for future expansion */
uint32_t bpbRootClust; /* start cluster for root directory */
uint16_t bpbFSInfo; /* filesystem info structure sector */
uint16_t bpbBackup; /* backup boot sector */
uint8_t bpbReserved[12]; /* Reserved for future expansion */
};
#ifdef atari
@ -90,17 +90,17 @@ struct bpb710 {
*/
#if 0
struct bpb_a {
u_int16_t bpbBytesPerSec; /* bytes per sector */
u_int8_t bpbSecPerClust; /* sectors per cluster */
u_int16_t bpbResSectors; /* number of reserved sectors */
u_int8_t bpbFATs; /* number of FATs */
u_int16_t bpbRootDirEnts; /* number of root directory entries */
u_int16_t bpbSectors; /* total number of sectors */
u_int8_t bpbUseless1; /* meaningless on GEMDOS FS */
u_int16_t bpbFATsecs; /* number of sectors per FAT */
u_int16_t bpbUseless2; /* meaningless for harddisk fs */
u_int16_t bpbUseless3; /* meaningless for harddisk fs */
u_int16_t bpbHiddenSecs; /* the TOS-BIOS ignores this */
uint16_t bpbBytesPerSec; /* bytes per sector */
uint8_t bpbSecPerClust; /* sectors per cluster */
uint16_t bpbResSectors; /* number of reserved sectors */
uint8_t bpbFATs; /* number of FATs */
uint16_t bpbRootDirEnts; /* number of root directory entries */
uint16_t bpbSectors; /* total number of sectors */
uint8_t bpbUseless1; /* meaningless on GEMDOS FS */
uint16_t bpbFATsecs; /* number of sectors per FAT */
uint16_t bpbUseless2; /* meaningless for harddisk fs */
uint16_t bpbUseless3; /* meaningless for harddisk fs */
uint16_t bpbHiddenSecs; /* the TOS-BIOS ignores this */
};
#endif
#endif /* atari */
@ -159,39 +159,39 @@ struct byte_bpb50 {
* BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50.
*/
struct byte_bpb710 {
u_int8_t bpbBytesPerSec[2]; /* bytes per sector */
u_int8_t bpbSecPerClust; /* sectors per cluster */
u_int8_t bpbResSectors[2]; /* number of reserved sectors */
u_int8_t bpbFATs; /* number of FATs */
u_int8_t bpbRootDirEnts[2]; /* number of root directory entries */
u_int8_t bpbSectors[2]; /* total number of sectors */
u_int8_t bpbMedia; /* media descriptor */
u_int8_t bpbFATsecs[2]; /* number of sectors per FAT */
u_int8_t bpbSecPerTrack[2]; /* sectors per track */
u_int8_t bpbHeads[2]; /* number of heads */
u_int8_t bpbHiddenSecs[4]; /* # of hidden sectors */
u_int8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
u_int8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */
u_int8_t bpbExtFlags[2]; /* extended flags: */
u_int8_t bpbFSVers[2]; /* filesystem version */
u_int8_t bpbRootClust[4]; /* start cluster for root directory */
u_int8_t bpbFSInfo[2]; /* filesystem info structure sector */
u_int8_t bpbBackup[2]; /* backup boot sector */
u_int8_t bpbReserved[12]; /* Reserved for future expansion */
uint8_t bpbBytesPerSec[2]; /* bytes per sector */
uint8_t bpbSecPerClust; /* sectors per cluster */
uint8_t bpbResSectors[2]; /* number of reserved sectors */
uint8_t bpbFATs; /* number of FATs */
uint8_t bpbRootDirEnts[2]; /* number of root directory entries */
uint8_t bpbSectors[2]; /* total number of sectors */
uint8_t bpbMedia; /* media descriptor */
uint8_t bpbFATsecs[2]; /* number of sectors per FAT */
uint8_t bpbSecPerTrack[2]; /* sectors per track */
uint8_t bpbHeads[2]; /* number of heads */
uint8_t bpbHiddenSecs[4]; /* # of hidden sectors */
uint8_t bpbHugeSectors[4]; /* # of sectors if bpbSectors == 0 */
uint8_t bpbBigFATsecs[4]; /* like bpbFATsecs for FAT32 */
uint8_t bpbExtFlags[2]; /* extended flags: */
uint8_t bpbFSVers[2]; /* filesystem version */
uint8_t bpbRootClust[4]; /* start cluster for root directory */
uint8_t bpbFSInfo[2]; /* filesystem info structure sector */
uint8_t bpbBackup[2]; /* backup boot sector */
uint8_t bpbReserved[12]; /* Reserved for future expansion */
};
/*
* FAT32 FSInfo block.
*/
struct fsinfo {
u_int8_t fsisig1[4];
u_int8_t fsifill1[480];
u_int8_t fsisig2[4];
u_int8_t fsinfree[4];
u_int8_t fsinxtfree[4];
u_int8_t fsifill2[12];
u_int8_t fsisig3[4];
u_int8_t fsifill3[508];
u_int8_t fsisig4[4];
uint8_t fsisig1[4];
uint8_t fsifill1[480];
uint8_t fsisig2[4];
uint8_t fsinfree[4];
uint8_t fsinxtfree[4];
uint8_t fsifill2[12];
uint8_t fsisig3[4];
uint8_t fsifill3[508];
uint8_t fsisig4[4];
};
#endif /* _MSDOSFS_BPB_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: denode.h,v 1.24 2014/07/08 09:21:52 hannken Exp $ */
/* $NetBSD: denode.h,v 1.25 2017/01/14 17:17:53 maya Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -212,7 +212,8 @@ struct denode {
#define DE_INTERNALIZE32(dep, dp) \
((dep)->de_StartCluster |= getushort((dp)->deHighClust) << 16)
#define DE_INTERNALIZE(dep, dp) \
(memcpy((dep)->de_Name, (dp)->deName, 11), \
(memcpy((dep)->de_Name, (dp)->deName, 8), \
memcpy((dep)->de_Name+8, (dp)->deExtension, 3),\
(dep)->de_Attributes = (dp)->deAttributes, \
(dep)->de_CHun = (dp)->deCHundredth, \
(dep)->de_CTime = getushort((dp)->deCTime), \
@ -229,7 +230,8 @@ struct denode {
#define DE_EXTERNALIZE16(dp, dep) \
putushort((dp)->deHighClust, 0)
#define DE_EXTERNALIZE(dp, dep) \
(memcpy((dp)->deName, (dep)->de_Name, 11), \
(memcpy((dp)->deName, (dep)->de_Name, 8), \
memcpy((dp)->deExtension, (dep)->de_Name+8, 3),\
(dp)->deAttributes = (dep)->de_Attributes, \
(dp)->deCHundredth = (dep)->de_CHun, \
putushort((dp)->deCTime, (dep)->de_CTime), \

View File

@ -1,4 +1,4 @@
/* $NetBSD: direntry.h,v 1.7 2013/10/20 00:01:55 christos Exp $ */
/* $NetBSD: direntry.h,v 1.11 2016/02/01 02:59:33 christos Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -53,12 +53,12 @@
* Structure of a dos directory entry.
*/
struct direntry {
u_int8_t deName[8]; /* filename, blank filled */
uint8_t deName[8]; /* filename, blank filled */
#define SLOT_EMPTY 0x00 /* slot has never been used */
#define SLOT_E5 0x05 /* the real value is 0xe5 */
#define SLOT_DELETED 0xe5 /* file in this slot deleted */
u_int8_t deExtension[3]; /* extension, blank filled */
u_int8_t deAttributes; /* file attributes */
uint8_t deExtension[3]; /* extension, blank filled */
uint8_t deAttributes; /* file attributes */
#define ATTR_NORMAL 0x00 /* normal file */
#define ATTR_READONLY 0x01 /* file is readonly */
#define ATTR_HIDDEN 0x02 /* file is hidden */
@ -66,16 +66,16 @@ struct direntry {
#define ATTR_VOLUME 0x08 /* entry is a volume label */
#define ATTR_DIRECTORY 0x10 /* entry is a directory name */
#define ATTR_ARCHIVE 0x20 /* file is new or modified */
u_int8_t deReserved; /* reserved */
u_int8_t deCHundredth; /* hundredth of seconds in CTime */
u_int8_t deCTime[2]; /* create time */
u_int8_t deCDate[2]; /* create date */
u_int8_t deADate[2]; /* access date */
u_int8_t deHighClust[2]; /* high bytes of cluster number */
u_int8_t deMTime[2]; /* last update time */
u_int8_t deMDate[2]; /* last update date */
u_int8_t deStartCluster[2]; /* starting cluster of file */
u_int8_t deFileSize[4]; /* size of file in bytes */
uint8_t deReserved; /* reserved */
uint8_t deCHundredth; /* hundredth of seconds in CTime */
uint8_t deCTime[2]; /* create time */
uint8_t deCDate[2]; /* create date */
uint8_t deADate[2]; /* access date */
uint8_t deHighClust[2]; /* high bytes of cluster number */
uint8_t deMTime[2]; /* last update time */
uint8_t deMDate[2]; /* last update date */
uint8_t deStartCluster[2]; /* starting cluster of file */
uint8_t deFileSize[4]; /* size of file in bytes */
};
static __inline uint8_t
@ -88,17 +88,17 @@ msdos_dirchar(const struct direntry *de, size_t i) {
* Structure of a Win95 long name directory entry
*/
struct winentry {
u_int8_t weCnt;
uint8_t weCnt;
#define WIN_LAST 0x40
#define WIN_CNT 0x3f
u_int8_t wePart1[10];
u_int8_t weAttributes;
uint8_t wePart1[10];
uint8_t weAttributes;
#define ATTR_WIN95 0x0f
u_int8_t weReserved1;
u_int8_t weChksum;
u_int8_t wePart2[12];
u_int16_t weReserved2;
u_int8_t wePart3[4];
uint8_t weReserved1;
uint8_t weChksum;
uint8_t wePart2[12];
uint16_t weReserved2;
uint8_t wePart3[4];
};
#define WIN_CHARS 13 /* Number of chars per winentry */
@ -128,19 +128,20 @@ struct winentry {
#if defined(_KERNEL) || defined(MAKEFS)
struct dirent;
void unix2dostime(const struct timespec *tsp, int gmtoff, u_int16_t *ddp,
u_int16_t *dtp, u_int8_t *dhp);
void dos2unixtime(u_int dd, u_int dt, u_int dh, int gmtoff,
struct timespec *tsp);
int dos2unixfn(u_char dn[11], u_char *un, int lower);
int unix2dosfn(const u_char *un, u_char dn[12], int unlen,
u_int gen);
int unix2winfn(const u_char *un, int unlen, struct winentry *wep,
int cnt, int chksum);
int winChkName(const u_char *un, int unlen, struct winentry *wep,
int chksum);
int win2unixfn(struct winentry *wep, struct dirent *dp, int chksum);
u_int8_t winChksum(u_int8_t *name);
int winSlotCnt(const u_char *un, int unlen);
void unix2dostime(const struct timespec *tsp, int gmtoff, uint16_t *ddp,
uint16_t *dtp, uint8_t *dhp);
void dos2unixtime(unsigned int dd, unsigned int dt, unsigned int dh,
int gmtoff, struct timespec *tsp);
int dos2unixfn(unsigned char dn[11], unsigned char *un, int lower);
int unix2dosfn(const unsigned char *un, unsigned char dn[12], int unlen,
unsigned int gen);
int unix2winfn(const unsigned char *un, int unlen, struct winentry *wep,
int cnt, int chksum, int utf8);
int winChkName(const unsigned char *un, int unlen, struct winentry *wep,
int chksum, int utf8);
int win2unixfn(struct winentry *wep, struct dirent *dp, int chksum,
uint16_t *namlen, int utf8);
uint8_t winChksum(uint8_t *name);
int winSlotCnt(const unsigned char *un, int unlen, int utf8);
#endif /* _KERNEL || MAKEFS */
#endif /* _MSDOSFS_DIRENTRY_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.msdosfs,v 1.2 2014/10/11 06:42:18 uebayasi Exp $
# $NetBSD: files.msdosfs,v 1.3 2016/02/06 10:40:58 mlelstv Exp $
deffs MSDOSFS
@ -9,3 +9,4 @@ file fs/msdosfs/msdosfs_fat.c msdosfs
file fs/msdosfs/msdosfs_lookup.c msdosfs
file fs/msdosfs/msdosfs_vfsops.c msdosfs
file fs/msdosfs/msdosfs_vnops.c msdosfs
file fs/msdosfs/msdosfs_unicode.c msdosfs

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_conv.c,v 1.10 2014/09/01 09:09:47 martin Exp $ */
/* $NetBSD: msdosfs_conv.c,v 1.17 2016/06/30 09:34:01 nonaka Exp $ */
/*-
* Copyright (C) 1995, 1997 Wolfgang Solfrank.
@ -45,20 +45,27 @@
* any damages caused by this software.
*
* October 1992
*
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#ifndef _KERNEL
#include <assert.h>
#define KASSERT(x) assert(x)
#endif
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.10 2014/09/01 09:09:47 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.17 2016/06/30 09:34:01 nonaka Exp $");
/*
* System include files.
*/
#include <sys/param.h>
#include <sys/time.h>
#include <sys/endian.h>
#ifdef _KERNEL
#include <sys/dirent.h>
#include <sys/systm.h>
@ -78,6 +85,22 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.10 2014/09/01 09:09:47 martin Exp
#include <fs/msdosfs/direntry.h>
#include <fs/msdosfs/denode.h>
static int invalidname(const u_int16_t *, int);
static int ucs2utf8(const u_int16_t *, u_int8_t *, int);
static int utf8ucs2(const u_int8_t *, int, u_int16_t *);
static int ucs2utf8str(const u_int16_t *, int, u_int8_t *, int);
static int utf8ucs2str(const u_int8_t *, int, u_int16_t *, int);
static int ucs2char8str(const u_int16_t *, int, u_int8_t *, int);
static int char8ucs2str(const u_int8_t *, int, u_int16_t *, int);
static void ucs2pad(u_int16_t *, int, int);
static u_int16_t ucs2fold(u_int16_t);
static int ucs2match(u_int16_t *, u_int16_t *, int n);
static int char8match(u_int16_t *, u_int16_t *, int n);
/*
* The number of seconds between Jan 1, 1970 and Jan 1, 1980. In that
* interval there were 8 regular years and 2 leap years.
@ -513,24 +536,34 @@ unix2dosfn(const u_char *un, u_char dn[12], int unlen, u_int gen)
* i.e. doesn't consist solely of blanks and dots
*/
int
unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum)
unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksum, int utf8)
{
const u_int8_t *cp;
u_int8_t *wcp;
int i;
u_int16_t wn[WIN_MAXLEN], *p;
int i, len;
const u_char *cp;
/*
* Drop trailing blanks and dots
*/
for (cp = un + unlen; *--cp == ' ' || *cp == '.'; unlen--);
for (cp = un + unlen; unlen > 0; unlen--)
if (*--cp != ' ' && *cp != '.')
break;
un += (cnt - 1) * WIN_CHARS;
unlen -= (cnt - 1) * WIN_CHARS;
/*
* Offset of this entry
*/
i = (cnt - 1) * WIN_CHARS;
/*
* Translate UNIX name to ucs-2
*/
len = utf8 ? utf8ucs2str(un, unlen, wn, WIN_MAXLEN) : char8ucs2str(un, unlen, wn, WIN_MAXLEN);
ucs2pad(wn, len, WIN_MAXLEN);
/*
* Initialize winentry to some useful default
*/
for (wcp = (u_int8_t *)wep, i = sizeof(*wep); --i >= 0; *wcp++ = 0xff);
memset(wep, 0xff, sizeof(*wep));
wep->weCnt = cnt;
wep->weAttributes = ATTR_WIN95;
wep->weReserved1 = 0;
@ -538,33 +571,18 @@ unix2winfn(const u_char *un, int unlen, struct winentry *wep, int cnt, int chksu
wep->weReserved2 = 0;
/*
* Now convert the filename parts
* Store name segment into directory entry
*/
for (wcp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
if (--unlen < 0)
goto done;
*wcp++ = *un++;
*wcp++ = 0;
}
for (wcp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
if (--unlen < 0)
goto done;
*wcp++ = *un++;
*wcp++ = 0;
}
for (wcp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
if (--unlen < 0)
goto done;
*wcp++ = *un++;
*wcp++ = 0;
}
if (!unlen)
wep->weCnt |= WIN_LAST;
return unlen;
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;
done:
*wcp++ = 0;
*wcp++ = 0;
wep->weCnt |= WIN_LAST;
return 0;
}
@ -574,15 +592,16 @@ done:
* Returns the checksum or -1 if no match
*/
int
winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum)
winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum, int utf8)
{
u_int8_t *cp;
int i;
u_int16_t wn[WIN_MAXLEN], *p;
u_int16_t buf[WIN_CHARS];
int i, len;
/*
* First compare checksums
*/
if (wep->weCnt&WIN_LAST)
if (wep->weCnt & WIN_LAST)
chksum = wep->weChksum;
else if (chksum != wep->weChksum)
chksum = -1;
@ -592,56 +611,35 @@ winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum)
/*
* Offset of this entry
*/
i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS;
un += i;
if ((unlen -= i) < 0)
i = ((wep->weCnt & WIN_CNT) - 1) * WIN_CHARS;
/*
* Translate UNIX name to ucs-2
*/
len = utf8 ? utf8ucs2str(un, unlen, wn, WIN_MAXLEN) : 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;
/*
* Ignore redundant winentries (those with only \0\0 on start in them).
* An appearance of such entry is a bug; unknown if in NetBSD msdosfs
* or MS Windows.
* Fetch name segment from directory entry
*/
if (unlen == 0) {
if (wep->wePart1[0] == '\0' && wep->wePart1[1] == '\0')
return chksum;
else
return -1;
}
if ((wep->weCnt&WIN_LAST) && unlen > WIN_CHARS)
return -1;
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));
/*
* Compare the name parts
* And compare name segment
*/
for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
if (--unlen < 0) {
if (!*cp++ && !*cp)
return chksum;
return -1;
}
if (u2l[*cp++] != u2l[*un++] || *cp++)
return -1;
}
for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
if (--unlen < 0) {
if (!*cp++ && !*cp)
return chksum;
return -1;
}
if (u2l[*cp++] != u2l[*un++] || *cp++)
return -1;
}
for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
if (--unlen < 0) {
if (!*cp++ && !*cp)
return chksum;
return -1;
}
if (u2l[*cp++] != u2l[*un++] || *cp++)
return -1;
}
if (! (utf8 ? ucs2match(&wn[i], buf, WIN_CHARS) : char8match(&wn[i], buf, WIN_CHARS)))
return -1;
return chksum;
}
@ -650,110 +648,73 @@ winChkName(const u_char *un, int unlen, struct winentry *wep, int chksum)
* Returns the checksum or -1 if impossible
*/
int
win2unixfn(struct winentry *wep, struct dirent *dp, int chksum)
win2unixfn(struct winentry *wep, struct dirent *dp, int chksum,
uint16_t *namlen, int utf8)
{
u_int8_t *cp;
u_int8_t *np, *ep = (u_int8_t *)dp->d_name + WIN_MAXLEN;
int i;
u_int16_t wn[WIN_CHARS], *p;
u_int8_t buf[WIN_CHARS*3];
int len;
if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
|| !(wep->weCnt&WIN_CNT))
if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
|| !(wep->weCnt & WIN_CNT))
return -1;
/*
* First compare checksums
*/
if (wep->weCnt&WIN_LAST) {
if (wep->weCnt & WIN_LAST) {
chksum = wep->weChksum;
/*
* This works even though d_namlen is one byte!
*/
#ifdef __NetBSD__
dp->d_namlen = (wep->weCnt&WIN_CNT) * WIN_CHARS;
#endif
*namlen = 0;
} else if (chksum != wep->weChksum)
chksum = -1;
if (chksum == -1)
return -1;
/*
* Offset of this entry
* Fetch name segment from directory entry
*/
i = ((wep->weCnt&WIN_CNT) - 1) * WIN_CHARS;
np = (u_int8_t *)dp->d_name + i;
p = &wn[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));
/*
* Convert the name parts
* Don't allow slashes in UNIX names. Discard that entry.
*/
for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) {
switch (*np++ = *cp++) {
case 0:
#ifdef __NetBSD__
dp->d_namlen -= sizeof(wep->wePart2)/2
+ sizeof(wep->wePart3)/2 + i + 1;
#endif
return chksum;
case '/':
np[-1] = 0;
return -1;
}
/*
* The size comparison should result in the compiler
* optimizing the whole if away
*/
if (WIN_MAXLEN % WIN_CHARS < sizeof(wep->wePart1) / 2
&& np > ep) {
np[-1] = 0;
return -1;
}
if (*cp++)
return -1;
}
for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) {
switch (*np++ = *cp++) {
case 0:
#ifdef __NetBSD__
dp->d_namlen -= sizeof(wep->wePart3)/2 + i + 1;
#endif
return chksum;
case '/':
np[-1] = 0;
return -1;
}
/*
* The size comparisons should be optimized away
*/
if (WIN_MAXLEN % WIN_CHARS >= sizeof(wep->wePart1) / 2
&& WIN_MAXLEN % WIN_CHARS < (sizeof(wep->wePart1) + sizeof(wep->wePart2)) / 2
&& np > ep) {
np[-1] = 0;
return -1;
}
if (*cp++)
return -1;
}
for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) {
switch (*np++ = *cp++) {
case 0:
#ifdef __NetBSD__
dp->d_namlen -= i + 1;
#endif
return chksum;
case '/':
np[-1] = 0;
return -1;
}
/*
* See above
*/
if (WIN_MAXLEN % WIN_CHARS >= (sizeof(wep->wePart1) + sizeof(wep->wePart2)) / 2
&& np > ep) {
np[-1] = 0;
return -1;
}
if (*cp++)
return -1;
}
if (invalidname(wn, WIN_CHARS))
return -1;
/*
* Translate ucs-2 to UNIX name
*/
len = utf8 ? ucs2utf8str(wn, WIN_CHARS, buf, sizeof(buf))
: ucs2char8str(wn, WIN_CHARS, buf, sizeof(buf));
KASSERT(len >= 0);
KASSERT((size_t)len <= MIN(sizeof(buf), sizeof(dp->d_name)-1));
/*
* Prepend name segment to directory entry
*
* This ignores the slot number from the windows entry but
* assumes that segments are read in reverse order.
*
* The UCS-2 name (up to 255 chars) can overflow the UNIX
* directory entry (up to 511 bytes). Trailing characters
* are silently discarded. This could also end in multiple
* files using the same (truncated) name.
*/
*namlen += len;
if (*namlen > sizeof(dp->d_name) - 1)
*namlen = sizeof(dp->d_name) - 1;
KASSERT(*namlen >= len);
memmove(&dp->d_name[len], &dp->d_name[0], *namlen - len);
memcpy(dp->d_name, buf, len);
return chksum;
}
@ -767,7 +728,7 @@ winChksum(u_int8_t *name)
u_int8_t s;
for (s = 0, i = 11; --i >= 0; s += *name++)
s = (s << 7)|(s >> 1);
s = (s << 7) | (s >> 1);
return s;
}
@ -775,12 +736,304 @@ winChksum(u_int8_t *name)
* Determine the number of slots necessary for Win95 names
*/
int
winSlotCnt(const u_char *un, int unlen)
winSlotCnt(const u_char *un, int unlen, int utf8)
{
for (un += unlen; unlen > 0; unlen--)
if (*--un != ' ' && *un != '.')
const u_char *cp;
int len;
/*
* Drop trailing blanks and dots
*/
for (cp = un + unlen; unlen > 0; unlen--)
if (*--cp != ' ' && *cp != '.')
break;
if (unlen > WIN_MAXLEN)
return 0;
return howmany(unlen, WIN_CHARS);
len = utf8 ? utf8ucs2str(un, unlen, NULL, WIN_MAXLEN) : unlen;
return howmany(len, WIN_CHARS);
}
/*
* Scan windows name for characters that must not
* appear in a UNIX filename
*/
static int
invalidname(const u_int16_t *in, int n)
{
while (n-- > 0) {
if (*in++ == '/')
return 1;
}
return 0;
}
/*
* Convert UCS-2 character into UTF-8
* return number of output bytes or 0 if output
* buffer is too short
*/
static int
ucs2utf8(const u_int16_t *in, u_int8_t *out, int n)
{
uint16_t inch = le16toh(in[0]);
if (inch <= 0x007f) {
if (n < 1) return 0;
if (out)
*out++ = inch;
return 1;
} else if (inch <= 0x07ff) {
if (n < 2) return 0;
if (out) {
*out++ = 0xc0 | (inch >> 6);
*out++ = 0x80 | (inch & 0x3f);
}
return 2;
} else {
if (n < 3) return 0;
if (out) {
*out++ = 0xe0 | (inch >> 12);
*out++ = 0x80 | ((inch >> 6) & 0x3f);
*out++ = 0x80 | (inch & 0x3f);
}
return 3;
}
}
/*
* Convert UTF-8 bytes into UCS-2 character
* return number of input bytes, 0 if input
* is too short and -1 if input is invalid
*/
static int
utf8ucs2(const u_int8_t *in, int n, u_int16_t *out)
{
uint16_t outch;
if (n < 1) return 0;
if (in[0] <= 0x7f) {
outch = in[0];
if (out)
*out = htole16(outch);
return 1;
} else if (in[0] <= 0xdf) {
if (n < 2) return 0;
outch = (in[0] & 0x1f) << 6 | (in[1] & 0x3f);
if (out)
*out = htole16(outch);
return 2;
} else if (in[0] <= 0xef) {
if (n < 3) return 0;
outch = (in[0] & 0x1f) << 12 | (in[1] & 0x3f) << 6 | (in[2] & 0x3f);
if (out)
*out = htole16(outch);
return 3;
}
return -1;
}
/*
* Convert UCS-2 string into UTF-8 string
* return total number of output bytes
*/
static int
ucs2utf8str(const u_int16_t *in, int n, u_int8_t *out, int m)
{
u_int8_t *p;
int outlen;
p = out;
while (n > 0 && *in != 0) {
outlen = ucs2utf8(in, out ? p : out, m);
if (outlen == 0)
break;
p += outlen;
m -= outlen;
in += 1;
n -= 1;
}
return p - out;
}
/*
* Convert UTF8 string into UCS-2 string
* return total number of output chacters
*/
static int
utf8ucs2str(const u_int8_t *in, int n, u_int16_t *out, int m)
{
u_int16_t *p;
int inlen;
p = out;
while (n > 0 && *in != 0) {
if (m < 1)
break;
inlen = utf8ucs2(in, n, out ? p : out);
if (inlen <= 0)
break;
in += inlen;
n -= inlen;
p += 1;
m -= 1;
}
return p - out;
}
/*
* Convert UCS-2 string into 8bit character string
* return total number of output bytes
*/
static int
ucs2char8str(const u_int16_t *in, int n, u_int8_t *out, int m)
{
u_int8_t *p;
u_int16_t inch;
p = out;
while (n > 0 && in[0] != 0) {
if (m < 1)
break;
inch = le16toh(in[0]);
if (inch > 255)
break;
if (p)
p[0] = inch;
p += 1;
m -= 1;
in += 1;
n -= 1;
}
return p - out;
}
/*
* Convert 8bit character string into UCS-2 string
* return total number of output chacters
*/
static int
char8ucs2str(const u_int8_t *in, int n, u_int16_t *out, int m)
{
u_int16_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(u_int16_t *buf, int len, int size)
{
if (len < size-1)
buf[len++] = 0x0000;
while (len < size)
buf[len++] = 0xffff;
}
/*
* Fold UCS-2 character to uppercase
*/
static u_int16_t
ucs2fold(u_int16_t w)
{
int low,high,mid;
u_int16_t check;
extern const u_int16_t msdosfs_unicode_foldmap[];
extern size_t msdosfs_unicode_foldmap_entries;
w = le16toh(w);
low = 0;
high = msdosfs_unicode_foldmap_entries / 2;
while (low < high) {
mid = (low + high)/2;
check = msdosfs_unicode_foldmap[2*mid+0];
if (w == check) {
w = msdosfs_unicode_foldmap[2*mid+1];
break;
}
if (w < check)
high = mid;
else
low = mid+1;
}
w = le16toh(w);
return w;
}
/*
* Compare two UCS-2 strings case-insensitive
*
* uses the Unicode case folding table
*/
static int
ucs2match(u_int16_t *w1, u_int16_t *w2, int n)
{
u_int16_t u1, u2;
while (n > 0) {
if (*w1 == 0 || *w2 == 0)
return *w1 == *w2;
u1 = ucs2fold(*w1);
u2 = ucs2fold(*w2);
if (u1 != u2)
return 0;
++w1;
++w2;
--n;
}
return 1;
}
/*
* Compare two 8bit char conversions case-insensitive
*
* uses the DOS case folding table
*/
static int
char8match(u_int16_t *w1, u_int16_t *w2, int n)
{
u_int16_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;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_denode.c,v 1.51 2015/03/28 19:24:05 maxv Exp $ */
/* $NetBSD: msdosfs_denode.c,v 1.59 2020/04/23 21:47:07 ad Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -48,12 +48,11 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.51 2015/03/28 19:24:05 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.59 2020/04/23 21:47:07 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/fstrans.h>
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/proc.h>
@ -74,8 +73,6 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.51 2015/03/28 19:24:05 maxv Exp
struct pool msdosfs_denode_pool;
extern int prtactive;
struct fh_key {
struct msdosfsmount *fhk_mount;
uint32_t fhk_dircluster;
@ -128,6 +125,7 @@ static const struct genfs_ops msdosfs_genfsops = {
.gop_alloc = msdosfs_gop_alloc,
.gop_write = genfs_gop_write,
.gop_markupdate = msdosfs_gop_markupdate,
.gop_putrange = genfs_gop_putrange,
};
MALLOC_DECLARE(M_MSDOSFSFAT);
@ -427,7 +425,7 @@ detrunc(struct denode *dep, u_long length, int flags, kauth_cred_t cred)
} else {
ubc_zerorange(&DETOV(dep)->v_uobj, length,
pmp->pm_bpcluster - boff,
UBC_UNMAP_FLAG(DETOV(dep)));
UBC_VNODE_FLAGS(DETOV(dep)));
}
}
@ -525,7 +523,7 @@ deextend(struct denode *dep, u_long length, kauth_cred_t cred)
dep->de_flag |= DE_UPDATE|DE_MODIFIED;
ubc_zerorange(&DETOV(dep)->v_uobj, (off_t)osize,
(size_t)(round_page(dep->de_FileSize) - osize),
UBC_UNMAP_FLAG(DETOV(dep)));
UBC_VNODE_FLAGS(DETOV(dep)));
uvm_vnp_setsize(DETOV(dep), (voff_t)dep->de_FileSize);
return (deupdat(dep, 1));
}
@ -533,25 +531,19 @@ deextend(struct denode *dep, u_long length, kauth_cred_t cred)
int
msdosfs_reclaim(void *v)
{
struct vop_reclaim_args /* {
struct vop_reclaim_v2_args /* {
struct vnode *a_vp;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct mount *mp = vp->v_mount;
struct denode *dep = VTODE(vp);
fstrans_start(mp, FSTRANS_LAZY);
VOP_UNLOCK(vp);
#ifdef MSDOSFS_DEBUG
printf("msdosfs_reclaim(): dep %p, file %s, refcnt %ld\n",
dep, dep->de_Name, dep->de_refcnt);
#endif
if (prtactive && vp->v_usecount > 1)
vprint("msdosfs_reclaim(): pushing active", vp);
/*
* Remove the denode from the vnode cache.
*/
vcache_remove(vp->v_mount, &dep->de_key, sizeof(dep->de_key));
/*
* Purge old data structures associated with the denode.
*/
@ -570,19 +562,17 @@ msdosfs_reclaim(void *v)
vp->v_data = NULL;
mutex_exit(vp->v_interlock);
pool_put(&msdosfs_denode_pool, dep);
fstrans_done(mp);
return (0);
}
int
msdosfs_inactive(void *v)
{
struct vop_inactive_args /* {
struct vop_inactive_v2_args /* {
struct vnode *a_vp;
bool *a_recycle;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct mount *mp = vp->v_mount;
struct denode *dep = VTODE(vp);
int error = 0;
@ -590,7 +580,6 @@ msdosfs_inactive(void *v)
printf("msdosfs_inactive(): dep %p, de_Name[0] %x\n", dep, dep->de_Name[0]);
#endif
fstrans_start(mp, FSTRANS_LAZY);
/*
* Get rid of denodes related to stale file handles.
*/
@ -622,12 +611,11 @@ out:
* so that it can be reused immediately.
*/
#ifdef MSDOSFS_DEBUG
printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n",
vp->v_usecount, dep->de_Name[0]);
printf("msdosfs_inactive(): usecount %d, de_Name[0] %x\n",
vrefcnt(vp), dep->de_Name[0]);
#endif
*ap->a_recycle = (dep->de_Name[0] == SLOT_DELETED);
VOP_UNLOCK(vp);
fstrans_done(mp);
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_fat.c,v 1.29 2015/03/28 19:24:05 maxv Exp $ */
/* $NetBSD: msdosfs_fat.c,v 1.35 2020/09/07 01:35:25 mrg Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -52,7 +52,7 @@
#endif
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.29 2015/03/28 19:24:05 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.35 2020/09/07 01:35:25 mrg Exp $");
/*
* kernel include files.
@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.29 2015/03/28 19:24:05 maxv Exp $"
#include <sys/buf.h>
#include <sys/vnode.h> /* to define vattr structure */
#else
#include <strings.h>
#include <ffs/buf.h>
#endif
@ -143,7 +144,7 @@ fatblock(struct msdosfsmount *pmp, u_long ofs, u_long *bnp, u_long *sizep, u_lon
u_long bn, size;
bn = ofs / pmp->pm_fatblocksize * pmp->pm_fatblocksec;
size = min(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn)
size = uimin(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn)
* pmp->pm_BytesPerSec;
bn += pmp->pm_fatblk + pmp->pm_curfat * pmp->pm_FATsecs;
@ -227,7 +228,7 @@ pcbmap(struct denode *dep, u_long findcn, daddr_t *bnp, u_long *cnp, int *sp)
if (cnp)
*cnp = MSDOSFSROOT;
if (sp)
*sp = min(pmp->pm_bpcluster,
*sp = uimin(pmp->pm_bpcluster,
dep->de_FileSize - de_cn2off(pmp, findcn));
DPRINTF(("%s(root, bn=%lu, cn=%u)\n", __func__,
pmp->pm_rootdirblk + de_cn2bn(pmp, findcn),
@ -273,6 +274,18 @@ pcbmap(struct denode *dep, u_long findcn, daddr_t *bnp, u_long *cnp, int *sp)
*/
if (cn >= (CLUST_RSRVD & pmp->pm_fatmask))
goto hiteof;
/*
* Also stop when cluster is not in the filesystem
*/
if (cn < CLUST_FIRST || cn > pmp->pm_maxcluster) {
DPRINTF(("%s(cn, %lu not in %lu..%lu)\n", __func__,
cn, (u_long)CLUST_FIRST, pmp->pm_maxcluster));
if (bp)
brelse(bp, 0);
return (EINVAL);
}
byteoffset = FATOFS(pmp, cn);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
if (bn != bp_bn) {
@ -383,7 +396,7 @@ fc_purge(struct denode *dep, u_int frcn)
void
updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn)
{
int i;
int i, error;
struct buf *bpn;
DPRINTF(("%s(pmp %p, bp %p, fatbn %lu)\n", __func__, pmp, bp, fatbn));
@ -396,7 +409,7 @@ updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn)
if (pmp->pm_freeclustercount
&& (pmp->pm_inusemap[cn / N_INUSEBITS]
& (1 << (cn % N_INUSEBITS)))) {
& (1U << (cn % N_INUSEBITS)))) {
/*
* The cluster indicated in FSInfo isn't free
* any longer. Got get a new free one.
@ -448,9 +461,12 @@ updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn)
bpn = getblk(pmp->pm_devvp, de_bn2kb(pmp, fatbn),
bp->b_bcount, 0, 0);
memcpy(bpn->b_data, bp->b_data, bp->b_bcount);
if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
bwrite(bpn);
else
if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT) {
error = bwrite(bpn);
if (error)
printf("%s: copy FAT %d (error=%d)\n",
__func__, i, error);
} else
bdwrite(bpn);
}
}
@ -458,9 +474,12 @@ updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn)
/*
* Write out the first (or current) FAT last.
*/
if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
bwrite(bp);
else
if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT) {
error = bwrite(bp);
if (error)
printf("%s: write FAT (error=%d)\n",
__func__, error);
} else
bdwrite(bp);
/*
* Maybe update fsinfo sector here?
@ -490,7 +509,7 @@ static inline void
usemap_alloc(struct msdosfsmount *pmp, u_long cn)
{
pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
pmp->pm_inusemap[cn / N_INUSEBITS] |= 1U << (cn % N_INUSEBITS);
pmp->pm_freeclustercount--;
}
@ -499,7 +518,7 @@ usemap_free(struct msdosfsmount *pmp, u_long cn)
{
pmp->pm_freeclustercount++;
pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1U << (cn % N_INUSEBITS));
}
int
@ -722,7 +741,7 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count)
idx = start / N_INUSEBITS;
start %= N_INUSEBITS;
map = pmp->pm_inusemap[idx];
map &= ~((1 << start) - 1);
map &= ~((1U << start) - 1);
if (map) {
len = ffs(map) - 1 - start;
return (len > count ? count : len);
@ -818,7 +837,7 @@ clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long *retcl
for (cn = newst; cn <= pmp->pm_maxcluster;) {
idx = cn / N_INUSEBITS;
map = pmp->pm_inusemap[idx];
map |= (1 << (cn % N_INUSEBITS)) - 1;
map |= (1U << (cn % N_INUSEBITS)) - 1;
if (map != (u_int)-1) {
cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
if ((l = chainlength(pmp, cn, count)) >= count)
@ -835,7 +854,7 @@ clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long *retcl
for (cn = 0; cn < newst;) {
idx = cn / N_INUSEBITS;
map = pmp->pm_inusemap[idx];
map |= (1 << (cn % N_INUSEBITS)) - 1;
map |= (1U << (cn % N_INUSEBITS)) - 1;
if (map != (u_int)-1) {
cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
if ((l = chainlength(pmp, cn, count)) >= count)
@ -876,6 +895,7 @@ freeclusterchain(struct msdosfsmount *pmp, u_long cluster)
u_long bn, bo, bsize, byteoffset;
u_long readcn, lbn = -1;
bn = 0; /* XXXgcc */
while (cluster >= CLUST_FIRST && cluster <= pmp->pm_maxcluster) {
byteoffset = FATOFS(pmp, cluster);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_lookup.c,v 1.34 2015/03/28 19:24:05 maxv Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.36 2020/04/04 20:49:30 ad Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -52,7 +52,7 @@
#endif
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.34 2015/03/28 19:24:05 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_lookup.c,v 1.36 2020/04/04 20:49:30 ad Exp $");
#include <sys/param.h>
@ -161,6 +161,10 @@ msdosfs_lookup(void *v)
return *vpp == NULLVP ? ENOENT: 0;
}
/* May need to restart the lookup with an exclusive lock. */
if (VOP_ISLOCKED(vdp) != LK_EXCLUSIVE)
return ENOLCK;
/*
* 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
@ -187,12 +191,12 @@ msdosfs_lookup(void *v)
break;
case 2:
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen) + 1;
cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
break;
case 3:
olddos = 0;
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen) + 1;
cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
break;
}
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
@ -282,7 +286,8 @@ msdosfs_lookup(void *v)
chksum = winChkName((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen,
(struct winentry *)dep,
chksum);
chksum,
pmp->pm_flags & MSDOSFSMNT_UTF8);
continue;
}
@ -652,7 +657,8 @@ createde(struct denode *dep, struct denode *ddep, struct denode **depp, struct c
fndoffset -= sizeof(struct direntry);
}
if (!unix2winfn(un, unlen, (struct winentry *)ndep,
wcnt, chksum))
wcnt, chksum,
ddep->de_pmp->pm_flags & MSDOSFSMNT_UTF8))
break;
}
}

View File

@ -0,0 +1,965 @@
/* $NetBSD: msdosfs_unicode.c,v 1.2 2016/02/06 14:11:58 joerg Exp $ */
/*
* Unicode 5.0 case folding derived from
*
* http://www.unicode.org/Public/5.0.0/ucd/CaseFolding.txt
*/
/*
* Unicode Character Database
* Copyright (c) 1991-2006 Unicode, Inc.
* For terms of use, see http://www.unicode.org/terms_of_use.html
* For documentation, see UCD.html
*
* COPYRIGHT AND PERMISSION NOTICE
*
* Copyright © 1991-2015 Unicode, Inc. All rights reserved.
* Distributed under the Terms of Use in
* http://www.unicode.org/copyright.html.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of the Unicode data files and any associated documentation
* (the "Data Files") or Unicode software and any associated documentation
* (the "Software") to deal in the Data Files or Software
* without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, and/or sell copies of
* the Data Files or Software, and to permit persons to whom the Data Files
* or Software are furnished to do so, provided that
* (a) this copyright and permission notice appear with all copies
* of the Data Files or Software,
* (b) this copyright and permission notice appear in associated
* documentation, and
* (c) there is clear notice in each modified Data File or in the Software
* as well as in the documentation associated with the Data File(s) or
* Software that the data or software has been modified.
*
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT OF THIRD PARTY RIGHTS.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
* NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
* DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THE DATA FILES OR SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in these Data Files or Software without prior
* written authorization of the copyright holder.
*
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#include <sys/types.h>
/*
* Unicode case folding for codes 0x0000..0xffff
*
* common case folding + simple case folding only
*/
const u_int16_t
msdosfs_unicode_foldmap[] = {
0x0041, 0x0061, /* LATIN CAPITAL LETTER A */
0x0042, 0x0062, /* LATIN CAPITAL LETTER B */
0x0043, 0x0063, /* LATIN CAPITAL LETTER C */
0x0044, 0x0064, /* LATIN CAPITAL LETTER D */
0x0045, 0x0065, /* LATIN CAPITAL LETTER E */
0x0046, 0x0066, /* LATIN CAPITAL LETTER F */
0x0047, 0x0067, /* LATIN CAPITAL LETTER G */
0x0048, 0x0068, /* LATIN CAPITAL LETTER H */
0x0049, 0x0069, /* LATIN CAPITAL LETTER I */
0x004A, 0x006A, /* LATIN CAPITAL LETTER J */
0x004B, 0x006B, /* LATIN CAPITAL LETTER K */
0x004C, 0x006C, /* LATIN CAPITAL LETTER L */
0x004D, 0x006D, /* LATIN CAPITAL LETTER M */
0x004E, 0x006E, /* LATIN CAPITAL LETTER N */
0x004F, 0x006F, /* LATIN CAPITAL LETTER O */
0x0050, 0x0070, /* LATIN CAPITAL LETTER P */
0x0051, 0x0071, /* LATIN CAPITAL LETTER Q */
0x0052, 0x0072, /* LATIN CAPITAL LETTER R */
0x0053, 0x0073, /* LATIN CAPITAL LETTER S */
0x0054, 0x0074, /* LATIN CAPITAL LETTER T */
0x0055, 0x0075, /* LATIN CAPITAL LETTER U */
0x0056, 0x0076, /* LATIN CAPITAL LETTER V */
0x0057, 0x0077, /* LATIN CAPITAL LETTER W */
0x0058, 0x0078, /* LATIN CAPITAL LETTER X */
0x0059, 0x0079, /* LATIN CAPITAL LETTER Y */
0x005A, 0x007A, /* LATIN CAPITAL LETTER Z */
0x00B5, 0x03BC, /* MICRO SIGN */
0x00C0, 0x00E0, /* LATIN CAPITAL LETTER A WITH GRAVE */
0x00C1, 0x00E1, /* LATIN CAPITAL LETTER A WITH ACUTE */
0x00C2, 0x00E2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
0x00C3, 0x00E3, /* LATIN CAPITAL LETTER A WITH TILDE */
0x00C4, 0x00E4, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
0x00C5, 0x00E5, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
0x00C6, 0x00E6, /* LATIN CAPITAL LETTER AE */
0x00C7, 0x00E7, /* LATIN CAPITAL LETTER C WITH CEDILLA */
0x00C8, 0x00E8, /* LATIN CAPITAL LETTER E WITH GRAVE */
0x00C9, 0x00E9, /* LATIN CAPITAL LETTER E WITH ACUTE */
0x00CA, 0x00EA, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
0x00CB, 0x00EB, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
0x00CC, 0x00EC, /* LATIN CAPITAL LETTER I WITH GRAVE */
0x00CD, 0x00ED, /* LATIN CAPITAL LETTER I WITH ACUTE */
0x00CE, 0x00EE, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
0x00CF, 0x00EF, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
0x00D0, 0x00F0, /* LATIN CAPITAL LETTER ETH */
0x00D1, 0x00F1, /* LATIN CAPITAL LETTER N WITH TILDE */
0x00D2, 0x00F2, /* LATIN CAPITAL LETTER O WITH GRAVE */
0x00D3, 0x00F3, /* LATIN CAPITAL LETTER O WITH ACUTE */
0x00D4, 0x00F4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
0x00D5, 0x00F5, /* LATIN CAPITAL LETTER O WITH TILDE */
0x00D6, 0x00F6, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
0x00D8, 0x00F8, /* LATIN CAPITAL LETTER O WITH STROKE */
0x00D9, 0x00F9, /* LATIN CAPITAL LETTER U WITH GRAVE */
0x00DA, 0x00FA, /* LATIN CAPITAL LETTER U WITH ACUTE */
0x00DB, 0x00FB, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
0x00DC, 0x00FC, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
0x00DD, 0x00FD, /* LATIN CAPITAL LETTER Y WITH ACUTE */
0x00DE, 0x00FE, /* LATIN CAPITAL LETTER THORN */
0x0100, 0x0101, /* LATIN CAPITAL LETTER A WITH MACRON */
0x0102, 0x0103, /* LATIN CAPITAL LETTER A WITH BREVE */
0x0104, 0x0105, /* LATIN CAPITAL LETTER A WITH OGONEK */
0x0106, 0x0107, /* LATIN CAPITAL LETTER C WITH ACUTE */
0x0108, 0x0109, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
0x010A, 0x010B, /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
0x010C, 0x010D, /* LATIN CAPITAL LETTER C WITH CARON */
0x010E, 0x010F, /* LATIN CAPITAL LETTER D WITH CARON */
0x0110, 0x0111, /* LATIN CAPITAL LETTER D WITH STROKE */
0x0112, 0x0113, /* LATIN CAPITAL LETTER E WITH MACRON */
0x0114, 0x0115, /* LATIN CAPITAL LETTER E WITH BREVE */
0x0116, 0x0117, /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
0x0118, 0x0119, /* LATIN CAPITAL LETTER E WITH OGONEK */
0x011A, 0x011B, /* LATIN CAPITAL LETTER E WITH CARON */
0x011C, 0x011D, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
0x011E, 0x011F, /* LATIN CAPITAL LETTER G WITH BREVE */
0x0120, 0x0121, /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
0x0122, 0x0123, /* LATIN CAPITAL LETTER G WITH CEDILLA */
0x0124, 0x0125, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
0x0126, 0x0127, /* LATIN CAPITAL LETTER H WITH STROKE */
0x0128, 0x0129, /* LATIN CAPITAL LETTER I WITH TILDE */
0x012A, 0x012B, /* LATIN CAPITAL LETTER I WITH MACRON */
0x012C, 0x012D, /* LATIN CAPITAL LETTER I WITH BREVE */
0x012E, 0x012F, /* LATIN CAPITAL LETTER I WITH OGONEK */
0x0132, 0x0133, /* LATIN CAPITAL LIGATURE IJ */
0x0134, 0x0135, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
0x0136, 0x0137, /* LATIN CAPITAL LETTER K WITH CEDILLA */
0x0139, 0x013A, /* LATIN CAPITAL LETTER L WITH ACUTE */
0x013B, 0x013C, /* LATIN CAPITAL LETTER L WITH CEDILLA */
0x013D, 0x013E, /* LATIN CAPITAL LETTER L WITH CARON */
0x013F, 0x0140, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
0x0141, 0x0142, /* LATIN CAPITAL LETTER L WITH STROKE */
0x0143, 0x0144, /* LATIN CAPITAL LETTER N WITH ACUTE */
0x0145, 0x0146, /* LATIN CAPITAL LETTER N WITH CEDILLA */
0x0147, 0x0148, /* LATIN CAPITAL LETTER N WITH CARON */
0x014A, 0x014B, /* LATIN CAPITAL LETTER ENG */
0x014C, 0x014D, /* LATIN CAPITAL LETTER O WITH MACRON */
0x014E, 0x014F, /* LATIN CAPITAL LETTER O WITH BREVE */
0x0150, 0x0151, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
0x0152, 0x0153, /* LATIN CAPITAL LIGATURE OE */
0x0154, 0x0155, /* LATIN CAPITAL LETTER R WITH ACUTE */
0x0156, 0x0157, /* LATIN CAPITAL LETTER R WITH CEDILLA */
0x0158, 0x0159, /* LATIN CAPITAL LETTER R WITH CARON */
0x015A, 0x015B, /* LATIN CAPITAL LETTER S WITH ACUTE */
0x015C, 0x015D, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
0x015E, 0x015F, /* LATIN CAPITAL LETTER S WITH CEDILLA */
0x0160, 0x0161, /* LATIN CAPITAL LETTER S WITH CARON */
0x0162, 0x0163, /* LATIN CAPITAL LETTER T WITH CEDILLA */
0x0164, 0x0165, /* LATIN CAPITAL LETTER T WITH CARON */
0x0166, 0x0167, /* LATIN CAPITAL LETTER T WITH STROKE */
0x0168, 0x0169, /* LATIN CAPITAL LETTER U WITH TILDE */
0x016A, 0x016B, /* LATIN CAPITAL LETTER U WITH MACRON */
0x016C, 0x016D, /* LATIN CAPITAL LETTER U WITH BREVE */
0x016E, 0x016F, /* LATIN CAPITAL LETTER U WITH RING ABOVE */
0x0170, 0x0171, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
0x0172, 0x0173, /* LATIN CAPITAL LETTER U WITH OGONEK */
0x0174, 0x0175, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
0x0176, 0x0177, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
0x0178, 0x00FF, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
0x0179, 0x017A, /* LATIN CAPITAL LETTER Z WITH ACUTE */
0x017B, 0x017C, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
0x017D, 0x017E, /* LATIN CAPITAL LETTER Z WITH CARON */
0x017F, 0x0073, /* LATIN SMALL LETTER LONG S */
0x0181, 0x0253, /* LATIN CAPITAL LETTER B WITH HOOK */
0x0182, 0x0183, /* LATIN CAPITAL LETTER B WITH TOPBAR */
0x0184, 0x0185, /* LATIN CAPITAL LETTER TONE SIX */
0x0186, 0x0254, /* LATIN CAPITAL LETTER OPEN O */
0x0187, 0x0188, /* LATIN CAPITAL LETTER C WITH HOOK */
0x0189, 0x0256, /* LATIN CAPITAL LETTER AFRICAN D */
0x018A, 0x0257, /* LATIN CAPITAL LETTER D WITH HOOK */
0x018B, 0x018C, /* LATIN CAPITAL LETTER D WITH TOPBAR */
0x018E, 0x01DD, /* LATIN CAPITAL LETTER REVERSED E */
0x018F, 0x0259, /* LATIN CAPITAL LETTER SCHWA */
0x0190, 0x025B, /* LATIN CAPITAL LETTER OPEN E */
0x0191, 0x0192, /* LATIN CAPITAL LETTER F WITH HOOK */
0x0193, 0x0260, /* LATIN CAPITAL LETTER G WITH HOOK */
0x0194, 0x0263, /* LATIN CAPITAL LETTER GAMMA */
0x0196, 0x0269, /* LATIN CAPITAL LETTER IOTA */
0x0197, 0x0268, /* LATIN CAPITAL LETTER I WITH STROKE */
0x0198, 0x0199, /* LATIN CAPITAL LETTER K WITH HOOK */
0x019C, 0x026F, /* LATIN CAPITAL LETTER TURNED M */
0x019D, 0x0272, /* LATIN CAPITAL LETTER N WITH LEFT HOOK */
0x019F, 0x0275, /* LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
0x01A0, 0x01A1, /* LATIN CAPITAL LETTER O WITH HORN */
0x01A2, 0x01A3, /* LATIN CAPITAL LETTER OI */
0x01A4, 0x01A5, /* LATIN CAPITAL LETTER P WITH HOOK */
0x01A6, 0x0280, /* LATIN LETTER YR */
0x01A7, 0x01A8, /* LATIN CAPITAL LETTER TONE TWO */
0x01A9, 0x0283, /* LATIN CAPITAL LETTER ESH */
0x01AC, 0x01AD, /* LATIN CAPITAL LETTER T WITH HOOK */
0x01AE, 0x0288, /* LATIN CAPITAL LETTER T WITH RETROFLEX HOOK */
0x01AF, 0x01B0, /* LATIN CAPITAL LETTER U WITH HORN */
0x01B1, 0x028A, /* LATIN CAPITAL LETTER UPSILON */
0x01B2, 0x028B, /* LATIN CAPITAL LETTER V WITH HOOK */
0x01B3, 0x01B4, /* LATIN CAPITAL LETTER Y WITH HOOK */
0x01B5, 0x01B6, /* LATIN CAPITAL LETTER Z WITH STROKE */
0x01B7, 0x0292, /* LATIN CAPITAL LETTER EZH */
0x01B8, 0x01B9, /* LATIN CAPITAL LETTER EZH REVERSED */
0x01BC, 0x01BD, /* LATIN CAPITAL LETTER TONE FIVE */
0x01C4, 0x01C6, /* LATIN CAPITAL LETTER DZ WITH CARON */
0x01C5, 0x01C6, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON */
0x01C7, 0x01C9, /* LATIN CAPITAL LETTER LJ */
0x01C8, 0x01C9, /* LATIN CAPITAL LETTER L WITH SMALL LETTER J */
0x01CA, 0x01CC, /* LATIN CAPITAL LETTER NJ */
0x01CB, 0x01CC, /* LATIN CAPITAL LETTER N WITH SMALL LETTER J */
0x01CD, 0x01CE, /* LATIN CAPITAL LETTER A WITH CARON */
0x01CF, 0x01D0, /* LATIN CAPITAL LETTER I WITH CARON */
0x01D1, 0x01D2, /* LATIN CAPITAL LETTER O WITH CARON */
0x01D3, 0x01D4, /* LATIN CAPITAL LETTER U WITH CARON */
0x01D5, 0x01D6, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON */
0x01D7, 0x01D8, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE */
0x01D9, 0x01DA, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON */
0x01DB, 0x01DC, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE */
0x01DE, 0x01DF, /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON */
0x01E0, 0x01E1, /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON */
0x01E2, 0x01E3, /* LATIN CAPITAL LETTER AE WITH MACRON */
0x01E4, 0x01E5, /* LATIN CAPITAL LETTER G WITH STROKE */
0x01E6, 0x01E7, /* LATIN CAPITAL LETTER G WITH CARON */
0x01E8, 0x01E9, /* LATIN CAPITAL LETTER K WITH CARON */
0x01EA, 0x01EB, /* LATIN CAPITAL LETTER O WITH OGONEK */
0x01EC, 0x01ED, /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON */
0x01EE, 0x01EF, /* LATIN CAPITAL LETTER EZH WITH CARON */
0x01F1, 0x01F3, /* LATIN CAPITAL LETTER DZ */
0x01F2, 0x01F3, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z */
0x01F4, 0x01F5, /* LATIN CAPITAL LETTER G WITH ACUTE */
0x01F6, 0x0195, /* LATIN CAPITAL LETTER HWAIR */
0x01F7, 0x01BF, /* LATIN CAPITAL LETTER WYNN */
0x01F8, 0x01F9, /* LATIN CAPITAL LETTER N WITH GRAVE */
0x01FA, 0x01FB, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
0x01FC, 0x01FD, /* LATIN CAPITAL LETTER AE WITH ACUTE */
0x01FE, 0x01FF, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
0x0200, 0x0201, /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE */
0x0202, 0x0203, /* LATIN CAPITAL LETTER A WITH INVERTED BREVE */
0x0204, 0x0205, /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE */
0x0206, 0x0207, /* LATIN CAPITAL LETTER E WITH INVERTED BREVE */
0x0208, 0x0209, /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE */
0x020A, 0x020B, /* LATIN CAPITAL LETTER I WITH INVERTED BREVE */
0x020C, 0x020D, /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE */
0x020E, 0x020F, /* LATIN CAPITAL LETTER O WITH INVERTED BREVE */
0x0210, 0x0211, /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE */
0x0212, 0x0213, /* LATIN CAPITAL LETTER R WITH INVERTED BREVE */
0x0214, 0x0215, /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE */
0x0216, 0x0217, /* LATIN CAPITAL LETTER U WITH INVERTED BREVE */
0x0218, 0x0219, /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
0x021A, 0x021B, /* LATIN CAPITAL LETTER T WITH COMMA BELOW */
0x021C, 0x021D, /* LATIN CAPITAL LETTER YOGH */
0x021E, 0x021F, /* LATIN CAPITAL LETTER H WITH CARON */
0x0220, 0x019E, /* LATIN CAPITAL LETTER N WITH LONG RIGHT LEG */
0x0222, 0x0223, /* LATIN CAPITAL LETTER OU */
0x0224, 0x0225, /* LATIN CAPITAL LETTER Z WITH HOOK */
0x0226, 0x0227, /* LATIN CAPITAL LETTER A WITH DOT ABOVE */
0x0228, 0x0229, /* LATIN CAPITAL LETTER E WITH CEDILLA */
0x022A, 0x022B, /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON */
0x022C, 0x022D, /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON */
0x022E, 0x022F, /* LATIN CAPITAL LETTER O WITH DOT ABOVE */
0x0230, 0x0231, /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON */
0x0232, 0x0233, /* LATIN CAPITAL LETTER Y WITH MACRON */
0x023A, 0x2C65, /* LATIN CAPITAL LETTER A WITH STROKE */
0x023B, 0x023C, /* LATIN CAPITAL LETTER C WITH STROKE */
0x023D, 0x019A, /* LATIN CAPITAL LETTER L WITH BAR */
0x023E, 0x2C66, /* LATIN CAPITAL LETTER T WITH DIAGONAL STROKE */
0x0241, 0x0242, /* LATIN CAPITAL LETTER GLOTTAL STOP */
0x0243, 0x0180, /* LATIN CAPITAL LETTER B WITH STROKE */
0x0244, 0x0289, /* LATIN CAPITAL LETTER U BAR */
0x0245, 0x028C, /* LATIN CAPITAL LETTER TURNED V */
0x0246, 0x0247, /* LATIN CAPITAL LETTER E WITH STROKE */
0x0248, 0x0249, /* LATIN CAPITAL LETTER J WITH STROKE */
0x024A, 0x024B, /* LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL */
0x024C, 0x024D, /* LATIN CAPITAL LETTER R WITH STROKE */
0x024E, 0x024F, /* LATIN CAPITAL LETTER Y WITH STROKE */
0x0345, 0x03B9, /* COMBINING GREEK YPOGEGRAMMENI */
0x0386, 0x03AC, /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
0x0388, 0x03AD, /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
0x0389, 0x03AE, /* GREEK CAPITAL LETTER ETA WITH TONOS */
0x038A, 0x03AF, /* GREEK CAPITAL LETTER IOTA WITH TONOS */
0x038C, 0x03CC, /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
0x038E, 0x03CD, /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
0x038F, 0x03CE, /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
0x0391, 0x03B1, /* GREEK CAPITAL LETTER ALPHA */
0x0392, 0x03B2, /* GREEK CAPITAL LETTER BETA */
0x0393, 0x03B3, /* GREEK CAPITAL LETTER GAMMA */
0x0394, 0x03B4, /* GREEK CAPITAL LETTER DELTA */
0x0395, 0x03B5, /* GREEK CAPITAL LETTER EPSILON */
0x0396, 0x03B6, /* GREEK CAPITAL LETTER ZETA */
0x0397, 0x03B7, /* GREEK CAPITAL LETTER ETA */
0x0398, 0x03B8, /* GREEK CAPITAL LETTER THETA */
0x0399, 0x03B9, /* GREEK CAPITAL LETTER IOTA */
0x039A, 0x03BA, /* GREEK CAPITAL LETTER KAPPA */
0x039B, 0x03BB, /* GREEK CAPITAL LETTER LAMDA */
0x039C, 0x03BC, /* GREEK CAPITAL LETTER MU */
0x039D, 0x03BD, /* GREEK CAPITAL LETTER NU */
0x039E, 0x03BE, /* GREEK CAPITAL LETTER XI */
0x039F, 0x03BF, /* GREEK CAPITAL LETTER OMICRON */
0x03A0, 0x03C0, /* GREEK CAPITAL LETTER PI */
0x03A1, 0x03C1, /* GREEK CAPITAL LETTER RHO */
0x03A3, 0x03C3, /* GREEK CAPITAL LETTER SIGMA */
0x03A4, 0x03C4, /* GREEK CAPITAL LETTER TAU */
0x03A5, 0x03C5, /* GREEK CAPITAL LETTER UPSILON */
0x03A6, 0x03C6, /* GREEK CAPITAL LETTER PHI */
0x03A7, 0x03C7, /* GREEK CAPITAL LETTER CHI */
0x03A8, 0x03C8, /* GREEK CAPITAL LETTER PSI */
0x03A9, 0x03C9, /* GREEK CAPITAL LETTER OMEGA */
0x03AA, 0x03CA, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
0x03AB, 0x03CB, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
0x03C2, 0x03C3, /* GREEK SMALL LETTER FINAL SIGMA */
0x03D0, 0x03B2, /* GREEK BETA SYMBOL */
0x03D1, 0x03B8, /* GREEK THETA SYMBOL */
0x03D5, 0x03C6, /* GREEK PHI SYMBOL */
0x03D6, 0x03C0, /* GREEK PI SYMBOL */
0x03D8, 0x03D9, /* GREEK LETTER ARCHAIC KOPPA */
0x03DA, 0x03DB, /* GREEK LETTER STIGMA */
0x03DC, 0x03DD, /* GREEK LETTER DIGAMMA */
0x03DE, 0x03DF, /* GREEK LETTER KOPPA */
0x03E0, 0x03E1, /* GREEK LETTER SAMPI */
0x03E2, 0x03E3, /* COPTIC CAPITAL LETTER SHEI */
0x03E4, 0x03E5, /* COPTIC CAPITAL LETTER FEI */
0x03E6, 0x03E7, /* COPTIC CAPITAL LETTER KHEI */
0x03E8, 0x03E9, /* COPTIC CAPITAL LETTER HORI */
0x03EA, 0x03EB, /* COPTIC CAPITAL LETTER GANGIA */
0x03EC, 0x03ED, /* COPTIC CAPITAL LETTER SHIMA */
0x03EE, 0x03EF, /* COPTIC CAPITAL LETTER DEI */
0x03F0, 0x03BA, /* GREEK KAPPA SYMBOL */
0x03F1, 0x03C1, /* GREEK RHO SYMBOL */
0x03F4, 0x03B8, /* GREEK CAPITAL THETA SYMBOL */
0x03F5, 0x03B5, /* GREEK LUNATE EPSILON SYMBOL */
0x03F7, 0x03F8, /* GREEK CAPITAL LETTER SHO */
0x03F9, 0x03F2, /* GREEK CAPITAL LUNATE SIGMA SYMBOL */
0x03FA, 0x03FB, /* GREEK CAPITAL LETTER SAN */
0x03FD, 0x037B, /* GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL */
0x03FE, 0x037C, /* GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL */
0x03FF, 0x037D, /* GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL */
0x0400, 0x0450, /* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
0x0401, 0x0451, /* CYRILLIC CAPITAL LETTER IO */
0x0402, 0x0452, /* CYRILLIC CAPITAL LETTER DJE */
0x0403, 0x0453, /* CYRILLIC CAPITAL LETTER GJE */
0x0404, 0x0454, /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */
0x0405, 0x0455, /* CYRILLIC CAPITAL LETTER DZE */
0x0406, 0x0456, /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
0x0407, 0x0457, /* CYRILLIC CAPITAL LETTER YI */
0x0408, 0x0458, /* CYRILLIC CAPITAL LETTER JE */
0x0409, 0x0459, /* CYRILLIC CAPITAL LETTER LJE */
0x040A, 0x045A, /* CYRILLIC CAPITAL LETTER NJE */
0x040B, 0x045B, /* CYRILLIC CAPITAL LETTER TSHE */
0x040C, 0x045C, /* CYRILLIC CAPITAL LETTER KJE */
0x040D, 0x045D, /* CYRILLIC CAPITAL LETTER I WITH GRAVE */
0x040E, 0x045E, /* CYRILLIC CAPITAL LETTER SHORT U */
0x040F, 0x045F, /* CYRILLIC CAPITAL LETTER DZHE */
0x0410, 0x0430, /* CYRILLIC CAPITAL LETTER A */
0x0411, 0x0431, /* CYRILLIC CAPITAL LETTER BE */
0x0412, 0x0432, /* CYRILLIC CAPITAL LETTER VE */
0x0413, 0x0433, /* CYRILLIC CAPITAL LETTER GHE */
0x0414, 0x0434, /* CYRILLIC CAPITAL LETTER DE */
0x0415, 0x0435, /* CYRILLIC CAPITAL LETTER IE */
0x0416, 0x0436, /* CYRILLIC CAPITAL LETTER ZHE */
0x0417, 0x0437, /* CYRILLIC CAPITAL LETTER ZE */
0x0418, 0x0438, /* CYRILLIC CAPITAL LETTER I */
0x0419, 0x0439, /* CYRILLIC CAPITAL LETTER SHORT I */
0x041A, 0x043A, /* CYRILLIC CAPITAL LETTER KA */
0x041B, 0x043B, /* CYRILLIC CAPITAL LETTER EL */
0x041C, 0x043C, /* CYRILLIC CAPITAL LETTER EM */
0x041D, 0x043D, /* CYRILLIC CAPITAL LETTER EN */
0x041E, 0x043E, /* CYRILLIC CAPITAL LETTER O */
0x041F, 0x043F, /* CYRILLIC CAPITAL LETTER PE */
0x0420, 0x0440, /* CYRILLIC CAPITAL LETTER ER */
0x0421, 0x0441, /* CYRILLIC CAPITAL LETTER ES */
0x0422, 0x0442, /* CYRILLIC CAPITAL LETTER TE */
0x0423, 0x0443, /* CYRILLIC CAPITAL LETTER U */
0x0424, 0x0444, /* CYRILLIC CAPITAL LETTER EF */
0x0425, 0x0445, /* CYRILLIC CAPITAL LETTER HA */
0x0426, 0x0446, /* CYRILLIC CAPITAL LETTER TSE */
0x0427, 0x0447, /* CYRILLIC CAPITAL LETTER CHE */
0x0428, 0x0448, /* CYRILLIC CAPITAL LETTER SHA */
0x0429, 0x0449, /* CYRILLIC CAPITAL LETTER SHCHA */
0x042A, 0x044A, /* CYRILLIC CAPITAL LETTER HARD SIGN */
0x042B, 0x044B, /* CYRILLIC CAPITAL LETTER YERU */
0x042C, 0x044C, /* CYRILLIC CAPITAL LETTER SOFT SIGN */
0x042D, 0x044D, /* CYRILLIC CAPITAL LETTER E */
0x042E, 0x044E, /* CYRILLIC CAPITAL LETTER YU */
0x042F, 0x044F, /* CYRILLIC CAPITAL LETTER YA */
0x0460, 0x0461, /* CYRILLIC CAPITAL LETTER OMEGA */
0x0462, 0x0463, /* CYRILLIC CAPITAL LETTER YAT */
0x0464, 0x0465, /* CYRILLIC CAPITAL LETTER IOTIFIED E */
0x0466, 0x0467, /* CYRILLIC CAPITAL LETTER LITTLE YUS */
0x0468, 0x0469, /* CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS */
0x046A, 0x046B, /* CYRILLIC CAPITAL LETTER BIG YUS */
0x046C, 0x046D, /* CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS */
0x046E, 0x046F, /* CYRILLIC CAPITAL LETTER KSI */
0x0470, 0x0471, /* CYRILLIC CAPITAL LETTER PSI */
0x0472, 0x0473, /* CYRILLIC CAPITAL LETTER FITA */
0x0474, 0x0475, /* CYRILLIC CAPITAL LETTER IZHITSA */
0x0476, 0x0477, /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
0x0478, 0x0479, /* CYRILLIC CAPITAL LETTER UK */
0x047A, 0x047B, /* CYRILLIC CAPITAL LETTER ROUND OMEGA */
0x047C, 0x047D, /* CYRILLIC CAPITAL LETTER OMEGA WITH TITLO */
0x047E, 0x047F, /* CYRILLIC CAPITAL LETTER OT */
0x0480, 0x0481, /* CYRILLIC CAPITAL LETTER KOPPA */
0x048A, 0x048B, /* CYRILLIC CAPITAL LETTER SHORT I WITH TAIL */
0x048C, 0x048D, /* CYRILLIC CAPITAL LETTER SEMISOFT SIGN */
0x048E, 0x048F, /* CYRILLIC CAPITAL LETTER ER WITH TICK */
0x0490, 0x0491, /* CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
0x0492, 0x0493, /* CYRILLIC CAPITAL LETTER GHE WITH STROKE */
0x0494, 0x0495, /* CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK */
0x0496, 0x0497, /* CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
0x0498, 0x0499, /* CYRILLIC CAPITAL LETTER ZE WITH DESCENDER */
0x049A, 0x049B, /* CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
0x049C, 0x049D, /* CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
0x049E, 0x049F, /* CYRILLIC CAPITAL LETTER KA WITH STROKE */
0x04A0, 0x04A1, /* CYRILLIC CAPITAL LETTER BASHKIR KA */
0x04A2, 0x04A3, /* CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
0x04A4, 0x04A5, /* CYRILLIC CAPITAL LIGATURE EN GHE */
0x04A6, 0x04A7, /* CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK */
0x04A8, 0x04A9, /* CYRILLIC CAPITAL LETTER ABKHASIAN HA */
0x04AA, 0x04AB, /* CYRILLIC CAPITAL LETTER ES WITH DESCENDER */
0x04AC, 0x04AD, /* CYRILLIC CAPITAL LETTER TE WITH DESCENDER */
0x04AE, 0x04AF, /* CYRILLIC CAPITAL LETTER STRAIGHT U */
0x04B0, 0x04B1, /* CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
0x04B2, 0x04B3, /* CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
0x04B4, 0x04B5, /* CYRILLIC CAPITAL LIGATURE TE TSE */
0x04B6, 0x04B7, /* CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
0x04B8, 0x04B9, /* CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
0x04BA, 0x04BB, /* CYRILLIC CAPITAL LETTER SHHA */
0x04BC, 0x04BD, /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE */
0x04BE, 0x04BF, /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER */
0x04C0, 0x04CF, /* CYRILLIC LETTER PALOCHKA */
0x04C1, 0x04C2, /* CYRILLIC CAPITAL LETTER ZHE WITH BREVE */
0x04C3, 0x04C4, /* CYRILLIC CAPITAL LETTER KA WITH HOOK */
0x04C5, 0x04C6, /* CYRILLIC CAPITAL LETTER EL WITH TAIL */
0x04C7, 0x04C8, /* CYRILLIC CAPITAL LETTER EN WITH HOOK */
0x04C9, 0x04CA, /* CYRILLIC CAPITAL LETTER EN WITH TAIL */
0x04CB, 0x04CC, /* CYRILLIC CAPITAL LETTER KHAKASSIAN CHE */
0x04CD, 0x04CE, /* CYRILLIC CAPITAL LETTER EM WITH TAIL */
0x04D0, 0x04D1, /* CYRILLIC CAPITAL LETTER A WITH BREVE */
0x04D2, 0x04D3, /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS */
0x04D4, 0x04D5, /* CYRILLIC CAPITAL LIGATURE A IE */
0x04D6, 0x04D7, /* CYRILLIC CAPITAL LETTER IE WITH BREVE */
0x04D8, 0x04D9, /* CYRILLIC CAPITAL LETTER SCHWA */
0x04DA, 0x04DB, /* CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS */
0x04DC, 0x04DD, /* CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS */
0x04DE, 0x04DF, /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS */
0x04E0, 0x04E1, /* CYRILLIC CAPITAL LETTER ABKHASIAN DZE */
0x04E2, 0x04E3, /* CYRILLIC CAPITAL LETTER I WITH MACRON */
0x04E4, 0x04E5, /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS */
0x04E6, 0x04E7, /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS */
0x04E8, 0x04E9, /* CYRILLIC CAPITAL LETTER BARRED O */
0x04EA, 0x04EB, /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS */
0x04EC, 0x04ED, /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS */
0x04EE, 0x04EF, /* CYRILLIC CAPITAL LETTER U WITH MACRON */
0x04F0, 0x04F1, /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS */
0x04F2, 0x04F3, /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE */
0x04F4, 0x04F5, /* CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS */
0x04F6, 0x04F7, /* CYRILLIC CAPITAL LETTER GHE WITH DESCENDER */
0x04F8, 0x04F9, /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS */
0x04FA, 0x04FB, /* CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK */
0x04FC, 0x04FD, /* CYRILLIC CAPITAL LETTER HA WITH HOOK */
0x04FE, 0x04FF, /* CYRILLIC CAPITAL LETTER HA WITH STROKE */
0x0500, 0x0501, /* CYRILLIC CAPITAL LETTER KOMI DE */
0x0502, 0x0503, /* CYRILLIC CAPITAL LETTER KOMI DJE */
0x0504, 0x0505, /* CYRILLIC CAPITAL LETTER KOMI ZJE */
0x0506, 0x0507, /* CYRILLIC CAPITAL LETTER KOMI DZJE */
0x0508, 0x0509, /* CYRILLIC CAPITAL LETTER KOMI LJE */
0x050A, 0x050B, /* CYRILLIC CAPITAL LETTER KOMI NJE */
0x050C, 0x050D, /* CYRILLIC CAPITAL LETTER KOMI SJE */
0x050E, 0x050F, /* CYRILLIC CAPITAL LETTER KOMI TJE */
0x0510, 0x0511, /* CYRILLIC CAPITAL LETTER REVERSED ZE */
0x0512, 0x0513, /* CYRILLIC CAPITAL LETTER EL WITH HOOK */
0x0531, 0x0561, /* ARMENIAN CAPITAL LETTER AYB */
0x0532, 0x0562, /* ARMENIAN CAPITAL LETTER BEN */
0x0533, 0x0563, /* ARMENIAN CAPITAL LETTER GIM */
0x0534, 0x0564, /* ARMENIAN CAPITAL LETTER DA */
0x0535, 0x0565, /* ARMENIAN CAPITAL LETTER ECH */
0x0536, 0x0566, /* ARMENIAN CAPITAL LETTER ZA */
0x0537, 0x0567, /* ARMENIAN CAPITAL LETTER EH */
0x0538, 0x0568, /* ARMENIAN CAPITAL LETTER ET */
0x0539, 0x0569, /* ARMENIAN CAPITAL LETTER TO */
0x053A, 0x056A, /* ARMENIAN CAPITAL LETTER ZHE */
0x053B, 0x056B, /* ARMENIAN CAPITAL LETTER INI */
0x053C, 0x056C, /* ARMENIAN CAPITAL LETTER LIWN */
0x053D, 0x056D, /* ARMENIAN CAPITAL LETTER XEH */
0x053E, 0x056E, /* ARMENIAN CAPITAL LETTER CA */
0x053F, 0x056F, /* ARMENIAN CAPITAL LETTER KEN */
0x0540, 0x0570, /* ARMENIAN CAPITAL LETTER HO */
0x0541, 0x0571, /* ARMENIAN CAPITAL LETTER JA */
0x0542, 0x0572, /* ARMENIAN CAPITAL LETTER GHAD */
0x0543, 0x0573, /* ARMENIAN CAPITAL LETTER CHEH */
0x0544, 0x0574, /* ARMENIAN CAPITAL LETTER MEN */
0x0545, 0x0575, /* ARMENIAN CAPITAL LETTER YI */
0x0546, 0x0576, /* ARMENIAN CAPITAL LETTER NOW */
0x0547, 0x0577, /* ARMENIAN CAPITAL LETTER SHA */
0x0548, 0x0578, /* ARMENIAN CAPITAL LETTER VO */
0x0549, 0x0579, /* ARMENIAN CAPITAL LETTER CHA */
0x054A, 0x057A, /* ARMENIAN CAPITAL LETTER PEH */
0x054B, 0x057B, /* ARMENIAN CAPITAL LETTER JHEH */
0x054C, 0x057C, /* ARMENIAN CAPITAL LETTER RA */
0x054D, 0x057D, /* ARMENIAN CAPITAL LETTER SEH */
0x054E, 0x057E, /* ARMENIAN CAPITAL LETTER VEW */
0x054F, 0x057F, /* ARMENIAN CAPITAL LETTER TIWN */
0x0550, 0x0580, /* ARMENIAN CAPITAL LETTER REH */
0x0551, 0x0581, /* ARMENIAN CAPITAL LETTER CO */
0x0552, 0x0582, /* ARMENIAN CAPITAL LETTER YIWN */
0x0553, 0x0583, /* ARMENIAN CAPITAL LETTER PIWR */
0x0554, 0x0584, /* ARMENIAN CAPITAL LETTER KEH */
0x0555, 0x0585, /* ARMENIAN CAPITAL LETTER OH */
0x0556, 0x0586, /* ARMENIAN CAPITAL LETTER FEH */
0x10A0, 0x2D00, /* GEORGIAN CAPITAL LETTER AN */
0x10A1, 0x2D01, /* GEORGIAN CAPITAL LETTER BAN */
0x10A2, 0x2D02, /* GEORGIAN CAPITAL LETTER GAN */
0x10A3, 0x2D03, /* GEORGIAN CAPITAL LETTER DON */
0x10A4, 0x2D04, /* GEORGIAN CAPITAL LETTER EN */
0x10A5, 0x2D05, /* GEORGIAN CAPITAL LETTER VIN */
0x10A6, 0x2D06, /* GEORGIAN CAPITAL LETTER ZEN */
0x10A7, 0x2D07, /* GEORGIAN CAPITAL LETTER TAN */
0x10A8, 0x2D08, /* GEORGIAN CAPITAL LETTER IN */
0x10A9, 0x2D09, /* GEORGIAN CAPITAL LETTER KAN */
0x10AA, 0x2D0A, /* GEORGIAN CAPITAL LETTER LAS */
0x10AB, 0x2D0B, /* GEORGIAN CAPITAL LETTER MAN */
0x10AC, 0x2D0C, /* GEORGIAN CAPITAL LETTER NAR */
0x10AD, 0x2D0D, /* GEORGIAN CAPITAL LETTER ON */
0x10AE, 0x2D0E, /* GEORGIAN CAPITAL LETTER PAR */
0x10AF, 0x2D0F, /* GEORGIAN CAPITAL LETTER ZHAR */
0x10B0, 0x2D10, /* GEORGIAN CAPITAL LETTER RAE */
0x10B1, 0x2D11, /* GEORGIAN CAPITAL LETTER SAN */
0x10B2, 0x2D12, /* GEORGIAN CAPITAL LETTER TAR */
0x10B3, 0x2D13, /* GEORGIAN CAPITAL LETTER UN */
0x10B4, 0x2D14, /* GEORGIAN CAPITAL LETTER PHAR */
0x10B5, 0x2D15, /* GEORGIAN CAPITAL LETTER KHAR */
0x10B6, 0x2D16, /* GEORGIAN CAPITAL LETTER GHAN */
0x10B7, 0x2D17, /* GEORGIAN CAPITAL LETTER QAR */
0x10B8, 0x2D18, /* GEORGIAN CAPITAL LETTER SHIN */
0x10B9, 0x2D19, /* GEORGIAN CAPITAL LETTER CHIN */
0x10BA, 0x2D1A, /* GEORGIAN CAPITAL LETTER CAN */
0x10BB, 0x2D1B, /* GEORGIAN CAPITAL LETTER JIL */
0x10BC, 0x2D1C, /* GEORGIAN CAPITAL LETTER CIL */
0x10BD, 0x2D1D, /* GEORGIAN CAPITAL LETTER CHAR */
0x10BE, 0x2D1E, /* GEORGIAN CAPITAL LETTER XAN */
0x10BF, 0x2D1F, /* GEORGIAN CAPITAL LETTER JHAN */
0x10C0, 0x2D20, /* GEORGIAN CAPITAL LETTER HAE */
0x10C1, 0x2D21, /* GEORGIAN CAPITAL LETTER HE */
0x10C2, 0x2D22, /* GEORGIAN CAPITAL LETTER HIE */
0x10C3, 0x2D23, /* GEORGIAN CAPITAL LETTER WE */
0x10C4, 0x2D24, /* GEORGIAN CAPITAL LETTER HAR */
0x10C5, 0x2D25, /* GEORGIAN CAPITAL LETTER HOE */
0x1E00, 0x1E01, /* LATIN CAPITAL LETTER A WITH RING BELOW */
0x1E02, 0x1E03, /* LATIN CAPITAL LETTER B WITH DOT ABOVE */
0x1E04, 0x1E05, /* LATIN CAPITAL LETTER B WITH DOT BELOW */
0x1E06, 0x1E07, /* LATIN CAPITAL LETTER B WITH LINE BELOW */
0x1E08, 0x1E09, /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE */
0x1E0A, 0x1E0B, /* LATIN CAPITAL LETTER D WITH DOT ABOVE */
0x1E0C, 0x1E0D, /* LATIN CAPITAL LETTER D WITH DOT BELOW */
0x1E0E, 0x1E0F, /* LATIN CAPITAL LETTER D WITH LINE BELOW */
0x1E10, 0x1E11, /* LATIN CAPITAL LETTER D WITH CEDILLA */
0x1E12, 0x1E13, /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW */
0x1E14, 0x1E15, /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE */
0x1E16, 0x1E17, /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE */
0x1E18, 0x1E19, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW */
0x1E1A, 0x1E1B, /* LATIN CAPITAL LETTER E WITH TILDE BELOW */
0x1E1C, 0x1E1D, /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE */
0x1E1E, 0x1E1F, /* LATIN CAPITAL LETTER F WITH DOT ABOVE */
0x1E20, 0x1E21, /* LATIN CAPITAL LETTER G WITH MACRON */
0x1E22, 0x1E23, /* LATIN CAPITAL LETTER H WITH DOT ABOVE */
0x1E24, 0x1E25, /* LATIN CAPITAL LETTER H WITH DOT BELOW */
0x1E26, 0x1E27, /* LATIN CAPITAL LETTER H WITH DIAERESIS */
0x1E28, 0x1E29, /* LATIN CAPITAL LETTER H WITH CEDILLA */
0x1E2A, 0x1E2B, /* LATIN CAPITAL LETTER H WITH BREVE BELOW */
0x1E2C, 0x1E2D, /* LATIN CAPITAL LETTER I WITH TILDE BELOW */
0x1E2E, 0x1E2F, /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE */
0x1E30, 0x1E31, /* LATIN CAPITAL LETTER K WITH ACUTE */
0x1E32, 0x1E33, /* LATIN CAPITAL LETTER K WITH DOT BELOW */
0x1E34, 0x1E35, /* LATIN CAPITAL LETTER K WITH LINE BELOW */
0x1E36, 0x1E37, /* LATIN CAPITAL LETTER L WITH DOT BELOW */
0x1E38, 0x1E39, /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON */
0x1E3A, 0x1E3B, /* LATIN CAPITAL LETTER L WITH LINE BELOW */
0x1E3C, 0x1E3D, /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW */
0x1E3E, 0x1E3F, /* LATIN CAPITAL LETTER M WITH ACUTE */
0x1E40, 0x1E41, /* LATIN CAPITAL LETTER M WITH DOT ABOVE */
0x1E42, 0x1E43, /* LATIN CAPITAL LETTER M WITH DOT BELOW */
0x1E44, 0x1E45, /* LATIN CAPITAL LETTER N WITH DOT ABOVE */
0x1E46, 0x1E47, /* LATIN CAPITAL LETTER N WITH DOT BELOW */
0x1E48, 0x1E49, /* LATIN CAPITAL LETTER N WITH LINE BELOW */
0x1E4A, 0x1E4B, /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW */
0x1E4C, 0x1E4D, /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE */
0x1E4E, 0x1E4F, /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS */
0x1E50, 0x1E51, /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE */
0x1E52, 0x1E53, /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE */
0x1E54, 0x1E55, /* LATIN CAPITAL LETTER P WITH ACUTE */
0x1E56, 0x1E57, /* LATIN CAPITAL LETTER P WITH DOT ABOVE */
0x1E58, 0x1E59, /* LATIN CAPITAL LETTER R WITH DOT ABOVE */
0x1E5A, 0x1E5B, /* LATIN CAPITAL LETTER R WITH DOT BELOW */
0x1E5C, 0x1E5D, /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON */
0x1E5E, 0x1E5F, /* LATIN CAPITAL LETTER R WITH LINE BELOW */
0x1E60, 0x1E61, /* LATIN CAPITAL LETTER S WITH DOT ABOVE */
0x1E62, 0x1E63, /* LATIN CAPITAL LETTER S WITH DOT BELOW */
0x1E64, 0x1E65, /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE */
0x1E66, 0x1E67, /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE */
0x1E68, 0x1E69, /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE */
0x1E6A, 0x1E6B, /* LATIN CAPITAL LETTER T WITH DOT ABOVE */
0x1E6C, 0x1E6D, /* LATIN CAPITAL LETTER T WITH DOT BELOW */
0x1E6E, 0x1E6F, /* LATIN CAPITAL LETTER T WITH LINE BELOW */
0x1E70, 0x1E71, /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW */
0x1E72, 0x1E73, /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW */
0x1E74, 0x1E75, /* LATIN CAPITAL LETTER U WITH TILDE BELOW */
0x1E76, 0x1E77, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW */
0x1E78, 0x1E79, /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE */
0x1E7A, 0x1E7B, /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS */
0x1E7C, 0x1E7D, /* LATIN CAPITAL LETTER V WITH TILDE */
0x1E7E, 0x1E7F, /* LATIN CAPITAL LETTER V WITH DOT BELOW */
0x1E80, 0x1E81, /* LATIN CAPITAL LETTER W WITH GRAVE */
0x1E82, 0x1E83, /* LATIN CAPITAL LETTER W WITH ACUTE */
0x1E84, 0x1E85, /* LATIN CAPITAL LETTER W WITH DIAERESIS */
0x1E86, 0x1E87, /* LATIN CAPITAL LETTER W WITH DOT ABOVE */
0x1E88, 0x1E89, /* LATIN CAPITAL LETTER W WITH DOT BELOW */
0x1E8A, 0x1E8B, /* LATIN CAPITAL LETTER X WITH DOT ABOVE */
0x1E8C, 0x1E8D, /* LATIN CAPITAL LETTER X WITH DIAERESIS */
0x1E8E, 0x1E8F, /* LATIN CAPITAL LETTER Y WITH DOT ABOVE */
0x1E90, 0x1E91, /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX */
0x1E92, 0x1E93, /* LATIN CAPITAL LETTER Z WITH DOT BELOW */
0x1E94, 0x1E95, /* LATIN CAPITAL LETTER Z WITH LINE BELOW */
0x1E9B, 0x1E61, /* LATIN SMALL LETTER LONG S WITH DOT ABOVE */
0x1EA0, 0x1EA1, /* LATIN CAPITAL LETTER A WITH DOT BELOW */
0x1EA2, 0x1EA3, /* LATIN CAPITAL LETTER A WITH HOOK ABOVE */
0x1EA4, 0x1EA5, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
0x1EA6, 0x1EA7, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
0x1EA8, 0x1EA9, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
0x1EAA, 0x1EAB, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
0x1EAC, 0x1EAD, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
0x1EAE, 0x1EAF, /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
0x1EB0, 0x1EB1, /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
0x1EB2, 0x1EB3, /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
0x1EB4, 0x1EB5, /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
0x1EB6, 0x1EB7, /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
0x1EB8, 0x1EB9, /* LATIN CAPITAL LETTER E WITH DOT BELOW */
0x1EBA, 0x1EBB, /* LATIN CAPITAL LETTER E WITH HOOK ABOVE */
0x1EBC, 0x1EBD, /* LATIN CAPITAL LETTER E WITH TILDE */
0x1EBE, 0x1EBF, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
0x1EC0, 0x1EC1, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
0x1EC2, 0x1EC3, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
0x1EC4, 0x1EC5, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
0x1EC6, 0x1EC7, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
0x1EC8, 0x1EC9, /* LATIN CAPITAL LETTER I WITH HOOK ABOVE */
0x1ECA, 0x1ECB, /* LATIN CAPITAL LETTER I WITH DOT BELOW */
0x1ECC, 0x1ECD, /* LATIN CAPITAL LETTER O WITH DOT BELOW */
0x1ECE, 0x1ECF, /* LATIN CAPITAL LETTER O WITH HOOK ABOVE */
0x1ED0, 0x1ED1, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
0x1ED2, 0x1ED3, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
0x1ED4, 0x1ED5, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
0x1ED6, 0x1ED7, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
0x1ED8, 0x1ED9, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
0x1EDA, 0x1EDB, /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
0x1EDC, 0x1EDD, /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
0x1EDE, 0x1EDF, /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
0x1EE0, 0x1EE1, /* LATIN CAPITAL LETTER O WITH HORN AND TILDE */
0x1EE2, 0x1EE3, /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
0x1EE4, 0x1EE5, /* LATIN CAPITAL LETTER U WITH DOT BELOW */
0x1EE6, 0x1EE7, /* LATIN CAPITAL LETTER U WITH HOOK ABOVE */
0x1EE8, 0x1EE9, /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
0x1EEA, 0x1EEB, /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
0x1EEC, 0x1EED, /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
0x1EEE, 0x1EEF, /* LATIN CAPITAL LETTER U WITH HORN AND TILDE */
0x1EF0, 0x1EF1, /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
0x1EF2, 0x1EF3, /* LATIN CAPITAL LETTER Y WITH GRAVE */
0x1EF4, 0x1EF5, /* LATIN CAPITAL LETTER Y WITH DOT BELOW */
0x1EF6, 0x1EF7, /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
0x1EF8, 0x1EF9, /* LATIN CAPITAL LETTER Y WITH TILDE */
0x1F08, 0x1F00, /* GREEK CAPITAL LETTER ALPHA WITH PSILI */
0x1F09, 0x1F01, /* GREEK CAPITAL LETTER ALPHA WITH DASIA */
0x1F0A, 0x1F02, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA */
0x1F0B, 0x1F03, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA */
0x1F0C, 0x1F04, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA */
0x1F0D, 0x1F05, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA */
0x1F0E, 0x1F06, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI */
0x1F0F, 0x1F07, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI */
0x1F18, 0x1F10, /* GREEK CAPITAL LETTER EPSILON WITH PSILI */
0x1F19, 0x1F11, /* GREEK CAPITAL LETTER EPSILON WITH DASIA */
0x1F1A, 0x1F12, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA */
0x1F1B, 0x1F13, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA */
0x1F1C, 0x1F14, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA */
0x1F1D, 0x1F15, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA */
0x1F28, 0x1F20, /* GREEK CAPITAL LETTER ETA WITH PSILI */
0x1F29, 0x1F21, /* GREEK CAPITAL LETTER ETA WITH DASIA */
0x1F2A, 0x1F22, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA */
0x1F2B, 0x1F23, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA */
0x1F2C, 0x1F24, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA */
0x1F2D, 0x1F25, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA */
0x1F2E, 0x1F26, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI */
0x1F2F, 0x1F27, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI */
0x1F38, 0x1F30, /* GREEK CAPITAL LETTER IOTA WITH PSILI */
0x1F39, 0x1F31, /* GREEK CAPITAL LETTER IOTA WITH DASIA */
0x1F3A, 0x1F32, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA */
0x1F3B, 0x1F33, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA */
0x1F3C, 0x1F34, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA */
0x1F3D, 0x1F35, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA */
0x1F3E, 0x1F36, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI */
0x1F3F, 0x1F37, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI */
0x1F48, 0x1F40, /* GREEK CAPITAL LETTER OMICRON WITH PSILI */
0x1F49, 0x1F41, /* GREEK CAPITAL LETTER OMICRON WITH DASIA */
0x1F4A, 0x1F42, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA */
0x1F4B, 0x1F43, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA */
0x1F4C, 0x1F44, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA */
0x1F4D, 0x1F45, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA */
0x1F59, 0x1F51, /* GREEK CAPITAL LETTER UPSILON WITH DASIA */
0x1F5B, 0x1F53, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA */
0x1F5D, 0x1F55, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA */
0x1F5F, 0x1F57, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI */
0x1F68, 0x1F60, /* GREEK CAPITAL LETTER OMEGA WITH PSILI */
0x1F69, 0x1F61, /* GREEK CAPITAL LETTER OMEGA WITH DASIA */
0x1F6A, 0x1F62, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA */
0x1F6B, 0x1F63, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA */
0x1F6C, 0x1F64, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA */
0x1F6D, 0x1F65, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA */
0x1F6E, 0x1F66, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI */
0x1F6F, 0x1F67, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI */
0x1F88, 0x1F80, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
0x1F89, 0x1F81, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
0x1F8A, 0x1F82, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
0x1F8B, 0x1F83, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
0x1F8C, 0x1F84, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
0x1F8D, 0x1F85, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
0x1F8E, 0x1F86, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
0x1F8F, 0x1F87, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
0x1F98, 0x1F90, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
0x1F99, 0x1F91, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
0x1F9A, 0x1F92, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
0x1F9B, 0x1F93, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
0x1F9C, 0x1F94, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
0x1F9D, 0x1F95, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
0x1F9E, 0x1F96, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
0x1F9F, 0x1F97, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
0x1FA8, 0x1FA0, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
0x1FA9, 0x1FA1, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
0x1FAA, 0x1FA2, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
0x1FAB, 0x1FA3, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
0x1FAC, 0x1FA4, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
0x1FAD, 0x1FA5, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
0x1FAE, 0x1FA6, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
0x1FAF, 0x1FA7, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
0x1FB8, 0x1FB0, /* GREEK CAPITAL LETTER ALPHA WITH VRACHY */
0x1FB9, 0x1FB1, /* GREEK CAPITAL LETTER ALPHA WITH MACRON */
0x1FBA, 0x1F70, /* GREEK CAPITAL LETTER ALPHA WITH VARIA */
0x1FBB, 0x1F71, /* GREEK CAPITAL LETTER ALPHA WITH OXIA */
0x1FBC, 0x1FB3, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
0x1FBE, 0x03B9, /* GREEK PROSGEGRAMMENI */
0x1FC8, 0x1F72, /* GREEK CAPITAL LETTER EPSILON WITH VARIA */
0x1FC9, 0x1F73, /* GREEK CAPITAL LETTER EPSILON WITH OXIA */
0x1FCA, 0x1F74, /* GREEK CAPITAL LETTER ETA WITH VARIA */
0x1FCB, 0x1F75, /* GREEK CAPITAL LETTER ETA WITH OXIA */
0x1FCC, 0x1FC3, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
0x1FD8, 0x1FD0, /* GREEK CAPITAL LETTER IOTA WITH VRACHY */
0x1FD9, 0x1FD1, /* GREEK CAPITAL LETTER IOTA WITH MACRON */
0x1FDA, 0x1F76, /* GREEK CAPITAL LETTER IOTA WITH VARIA */
0x1FDB, 0x1F77, /* GREEK CAPITAL LETTER IOTA WITH OXIA */
0x1FE8, 0x1FE0, /* GREEK CAPITAL LETTER UPSILON WITH VRACHY */
0x1FE9, 0x1FE1, /* GREEK CAPITAL LETTER UPSILON WITH MACRON */
0x1FEA, 0x1F7A, /* GREEK CAPITAL LETTER UPSILON WITH VARIA */
0x1FEB, 0x1F7B, /* GREEK CAPITAL LETTER UPSILON WITH OXIA */
0x1FEC, 0x1FE5, /* GREEK CAPITAL LETTER RHO WITH DASIA */
0x1FF8, 0x1F78, /* GREEK CAPITAL LETTER OMICRON WITH VARIA */
0x1FF9, 0x1F79, /* GREEK CAPITAL LETTER OMICRON WITH OXIA */
0x1FFA, 0x1F7C, /* GREEK CAPITAL LETTER OMEGA WITH VARIA */
0x1FFB, 0x1F7D, /* GREEK CAPITAL LETTER OMEGA WITH OXIA */
0x1FFC, 0x1FF3, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
0x2126, 0x03C9, /* OHM SIGN */
0x212A, 0x006B, /* KELVIN SIGN */
0x212B, 0x00E5, /* ANGSTROM SIGN */
0x2132, 0x214E, /* TURNED CAPITAL F */
0x2160, 0x2170, /* ROMAN NUMERAL ONE */
0x2161, 0x2171, /* ROMAN NUMERAL TWO */
0x2162, 0x2172, /* ROMAN NUMERAL THREE */
0x2163, 0x2173, /* ROMAN NUMERAL FOUR */
0x2164, 0x2174, /* ROMAN NUMERAL FIVE */
0x2165, 0x2175, /* ROMAN NUMERAL SIX */
0x2166, 0x2176, /* ROMAN NUMERAL SEVEN */
0x2167, 0x2177, /* ROMAN NUMERAL EIGHT */
0x2168, 0x2178, /* ROMAN NUMERAL NINE */
0x2169, 0x2179, /* ROMAN NUMERAL TEN */
0x216A, 0x217A, /* ROMAN NUMERAL ELEVEN */
0x216B, 0x217B, /* ROMAN NUMERAL TWELVE */
0x216C, 0x217C, /* ROMAN NUMERAL FIFTY */
0x216D, 0x217D, /* ROMAN NUMERAL ONE HUNDRED */
0x216E, 0x217E, /* ROMAN NUMERAL FIVE HUNDRED */
0x216F, 0x217F, /* ROMAN NUMERAL ONE THOUSAND */
0x2183, 0x2184, /* ROMAN NUMERAL REVERSED ONE HUNDRED */
0x24B6, 0x24D0, /* CIRCLED LATIN CAPITAL LETTER A */
0x24B7, 0x24D1, /* CIRCLED LATIN CAPITAL LETTER B */
0x24B8, 0x24D2, /* CIRCLED LATIN CAPITAL LETTER C */
0x24B9, 0x24D3, /* CIRCLED LATIN CAPITAL LETTER D */
0x24BA, 0x24D4, /* CIRCLED LATIN CAPITAL LETTER E */
0x24BB, 0x24D5, /* CIRCLED LATIN CAPITAL LETTER F */
0x24BC, 0x24D6, /* CIRCLED LATIN CAPITAL LETTER G */
0x24BD, 0x24D7, /* CIRCLED LATIN CAPITAL LETTER H */
0x24BE, 0x24D8, /* CIRCLED LATIN CAPITAL LETTER I */
0x24BF, 0x24D9, /* CIRCLED LATIN CAPITAL LETTER J */
0x24C0, 0x24DA, /* CIRCLED LATIN CAPITAL LETTER K */
0x24C1, 0x24DB, /* CIRCLED LATIN CAPITAL LETTER L */
0x24C2, 0x24DC, /* CIRCLED LATIN CAPITAL LETTER M */
0x24C3, 0x24DD, /* CIRCLED LATIN CAPITAL LETTER N */
0x24C4, 0x24DE, /* CIRCLED LATIN CAPITAL LETTER O */
0x24C5, 0x24DF, /* CIRCLED LATIN CAPITAL LETTER P */
0x24C6, 0x24E0, /* CIRCLED LATIN CAPITAL LETTER Q */
0x24C7, 0x24E1, /* CIRCLED LATIN CAPITAL LETTER R */
0x24C8, 0x24E2, /* CIRCLED LATIN CAPITAL LETTER S */
0x24C9, 0x24E3, /* CIRCLED LATIN CAPITAL LETTER T */
0x24CA, 0x24E4, /* CIRCLED LATIN CAPITAL LETTER U */
0x24CB, 0x24E5, /* CIRCLED LATIN CAPITAL LETTER V */
0x24CC, 0x24E6, /* CIRCLED LATIN CAPITAL LETTER W */
0x24CD, 0x24E7, /* CIRCLED LATIN CAPITAL LETTER X */
0x24CE, 0x24E8, /* CIRCLED LATIN CAPITAL LETTER Y */
0x24CF, 0x24E9, /* CIRCLED LATIN CAPITAL LETTER Z */
0x2C00, 0x2C30, /* GLAGOLITIC CAPITAL LETTER AZU */
0x2C01, 0x2C31, /* GLAGOLITIC CAPITAL LETTER BUKY */
0x2C02, 0x2C32, /* GLAGOLITIC CAPITAL LETTER VEDE */
0x2C03, 0x2C33, /* GLAGOLITIC CAPITAL LETTER GLAGOLI */
0x2C04, 0x2C34, /* GLAGOLITIC CAPITAL LETTER DOBRO */
0x2C05, 0x2C35, /* GLAGOLITIC CAPITAL LETTER YESTU */
0x2C06, 0x2C36, /* GLAGOLITIC CAPITAL LETTER ZHIVETE */
0x2C07, 0x2C37, /* GLAGOLITIC CAPITAL LETTER DZELO */
0x2C08, 0x2C38, /* GLAGOLITIC CAPITAL LETTER ZEMLJA */
0x2C09, 0x2C39, /* GLAGOLITIC CAPITAL LETTER IZHE */
0x2C0A, 0x2C3A, /* GLAGOLITIC CAPITAL LETTER INITIAL IZHE */
0x2C0B, 0x2C3B, /* GLAGOLITIC CAPITAL LETTER I */
0x2C0C, 0x2C3C, /* GLAGOLITIC CAPITAL LETTER DJERVI */
0x2C0D, 0x2C3D, /* GLAGOLITIC CAPITAL LETTER KAKO */
0x2C0E, 0x2C3E, /* GLAGOLITIC CAPITAL LETTER LJUDIJE */
0x2C0F, 0x2C3F, /* GLAGOLITIC CAPITAL LETTER MYSLITE */
0x2C10, 0x2C40, /* GLAGOLITIC CAPITAL LETTER NASHI */
0x2C11, 0x2C41, /* GLAGOLITIC CAPITAL LETTER ONU */
0x2C12, 0x2C42, /* GLAGOLITIC CAPITAL LETTER POKOJI */
0x2C13, 0x2C43, /* GLAGOLITIC CAPITAL LETTER RITSI */
0x2C14, 0x2C44, /* GLAGOLITIC CAPITAL LETTER SLOVO */
0x2C15, 0x2C45, /* GLAGOLITIC CAPITAL LETTER TVRIDO */
0x2C16, 0x2C46, /* GLAGOLITIC CAPITAL LETTER UKU */
0x2C17, 0x2C47, /* GLAGOLITIC CAPITAL LETTER FRITU */
0x2C18, 0x2C48, /* GLAGOLITIC CAPITAL LETTER HERU */
0x2C19, 0x2C49, /* GLAGOLITIC CAPITAL LETTER OTU */
0x2C1A, 0x2C4A, /* GLAGOLITIC CAPITAL LETTER PE */
0x2C1B, 0x2C4B, /* GLAGOLITIC CAPITAL LETTER SHTA */
0x2C1C, 0x2C4C, /* GLAGOLITIC CAPITAL LETTER TSI */
0x2C1D, 0x2C4D, /* GLAGOLITIC CAPITAL LETTER CHRIVI */
0x2C1E, 0x2C4E, /* GLAGOLITIC CAPITAL LETTER SHA */
0x2C1F, 0x2C4F, /* GLAGOLITIC CAPITAL LETTER YERU */
0x2C20, 0x2C50, /* GLAGOLITIC CAPITAL LETTER YERI */
0x2C21, 0x2C51, /* GLAGOLITIC CAPITAL LETTER YATI */
0x2C22, 0x2C52, /* GLAGOLITIC CAPITAL LETTER SPIDERY HA */
0x2C23, 0x2C53, /* GLAGOLITIC CAPITAL LETTER YU */
0x2C24, 0x2C54, /* GLAGOLITIC CAPITAL LETTER SMALL YUS */
0x2C25, 0x2C55, /* GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL */
0x2C26, 0x2C56, /* GLAGOLITIC CAPITAL LETTER YO */
0x2C27, 0x2C57, /* GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS */
0x2C28, 0x2C58, /* GLAGOLITIC CAPITAL LETTER BIG YUS */
0x2C29, 0x2C59, /* GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS */
0x2C2A, 0x2C5A, /* GLAGOLITIC CAPITAL LETTER FITA */
0x2C2B, 0x2C5B, /* GLAGOLITIC CAPITAL LETTER IZHITSA */
0x2C2C, 0x2C5C, /* GLAGOLITIC CAPITAL LETTER SHTAPIC */
0x2C2D, 0x2C5D, /* GLAGOLITIC CAPITAL LETTER TROKUTASTI A */
0x2C2E, 0x2C5E, /* GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE */
0x2C60, 0x2C61, /* LATIN CAPITAL LETTER L WITH DOUBLE BAR */
0x2C62, 0x026B, /* LATIN CAPITAL LETTER L WITH MIDDLE TILDE */
0x2C63, 0x1D7D, /* LATIN CAPITAL LETTER P WITH STROKE */
0x2C64, 0x027D, /* LATIN CAPITAL LETTER R WITH TAIL */
0x2C67, 0x2C68, /* LATIN CAPITAL LETTER H WITH DESCENDER */
0x2C69, 0x2C6A, /* LATIN CAPITAL LETTER K WITH DESCENDER */
0x2C6B, 0x2C6C, /* LATIN CAPITAL LETTER Z WITH DESCENDER */
0x2C75, 0x2C76, /* LATIN CAPITAL LETTER HALF H */
0x2C80, 0x2C81, /* COPTIC CAPITAL LETTER ALFA */
0x2C82, 0x2C83, /* COPTIC CAPITAL LETTER VIDA */
0x2C84, 0x2C85, /* COPTIC CAPITAL LETTER GAMMA */
0x2C86, 0x2C87, /* COPTIC CAPITAL LETTER DALDA */
0x2C88, 0x2C89, /* COPTIC CAPITAL LETTER EIE */
0x2C8A, 0x2C8B, /* COPTIC CAPITAL LETTER SOU */
0x2C8C, 0x2C8D, /* COPTIC CAPITAL LETTER ZATA */
0x2C8E, 0x2C8F, /* COPTIC CAPITAL LETTER HATE */
0x2C90, 0x2C91, /* COPTIC CAPITAL LETTER THETHE */
0x2C92, 0x2C93, /* COPTIC CAPITAL LETTER IAUDA */
0x2C94, 0x2C95, /* COPTIC CAPITAL LETTER KAPA */
0x2C96, 0x2C97, /* COPTIC CAPITAL LETTER LAULA */
0x2C98, 0x2C99, /* COPTIC CAPITAL LETTER MI */
0x2C9A, 0x2C9B, /* COPTIC CAPITAL LETTER NI */
0x2C9C, 0x2C9D, /* COPTIC CAPITAL LETTER KSI */
0x2C9E, 0x2C9F, /* COPTIC CAPITAL LETTER O */
0x2CA0, 0x2CA1, /* COPTIC CAPITAL LETTER PI */
0x2CA2, 0x2CA3, /* COPTIC CAPITAL LETTER RO */
0x2CA4, 0x2CA5, /* COPTIC CAPITAL LETTER SIMA */
0x2CA6, 0x2CA7, /* COPTIC CAPITAL LETTER TAU */
0x2CA8, 0x2CA9, /* COPTIC CAPITAL LETTER UA */
0x2CAA, 0x2CAB, /* COPTIC CAPITAL LETTER FI */
0x2CAC, 0x2CAD, /* COPTIC CAPITAL LETTER KHI */
0x2CAE, 0x2CAF, /* COPTIC CAPITAL LETTER PSI */
0x2CB0, 0x2CB1, /* COPTIC CAPITAL LETTER OOU */
0x2CB2, 0x2CB3, /* COPTIC CAPITAL LETTER DIALECT-P ALEF */
0x2CB4, 0x2CB5, /* COPTIC CAPITAL LETTER OLD COPTIC AIN */
0x2CB6, 0x2CB7, /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE */
0x2CB8, 0x2CB9, /* COPTIC CAPITAL LETTER DIALECT-P KAPA */
0x2CBA, 0x2CBB, /* COPTIC CAPITAL LETTER DIALECT-P NI */
0x2CBC, 0x2CBD, /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI */
0x2CBE, 0x2CBF, /* COPTIC CAPITAL LETTER OLD COPTIC OOU */
0x2CC0, 0x2CC1, /* COPTIC CAPITAL LETTER SAMPI */
0x2CC2, 0x2CC3, /* COPTIC CAPITAL LETTER CROSSED SHEI */
0x2CC4, 0x2CC5, /* COPTIC CAPITAL LETTER OLD COPTIC SHEI */
0x2CC6, 0x2CC7, /* COPTIC CAPITAL LETTER OLD COPTIC ESH */
0x2CC8, 0x2CC9, /* COPTIC CAPITAL LETTER AKHMIMIC KHEI */
0x2CCA, 0x2CCB, /* COPTIC CAPITAL LETTER DIALECT-P HORI */
0x2CCC, 0x2CCD, /* COPTIC CAPITAL LETTER OLD COPTIC HORI */
0x2CCE, 0x2CCF, /* COPTIC CAPITAL LETTER OLD COPTIC HA */
0x2CD0, 0x2CD1, /* COPTIC CAPITAL LETTER L-SHAPED HA */
0x2CD2, 0x2CD3, /* COPTIC CAPITAL LETTER OLD COPTIC HEI */
0x2CD4, 0x2CD5, /* COPTIC CAPITAL LETTER OLD COPTIC HAT */
0x2CD6, 0x2CD7, /* COPTIC CAPITAL LETTER OLD COPTIC GANGIA */
0x2CD8, 0x2CD9, /* COPTIC CAPITAL LETTER OLD COPTIC DJA */
0x2CDA, 0x2CDB, /* COPTIC CAPITAL LETTER OLD COPTIC SHIMA */
0x2CDC, 0x2CDD, /* COPTIC CAPITAL LETTER OLD NUBIAN SHIMA */
0x2CDE, 0x2CDF, /* COPTIC CAPITAL LETTER OLD NUBIAN NGI */
0x2CE0, 0x2CE1, /* COPTIC CAPITAL LETTER OLD NUBIAN NYI */
0x2CE2, 0x2CE3, /* COPTIC CAPITAL LETTER OLD NUBIAN WAU */
0xFF21, 0xFF41, /* FULLWIDTH LATIN CAPITAL LETTER A */
0xFF22, 0xFF42, /* FULLWIDTH LATIN CAPITAL LETTER B */
0xFF23, 0xFF43, /* FULLWIDTH LATIN CAPITAL LETTER C */
0xFF24, 0xFF44, /* FULLWIDTH LATIN CAPITAL LETTER D */
0xFF25, 0xFF45, /* FULLWIDTH LATIN CAPITAL LETTER E */
0xFF26, 0xFF46, /* FULLWIDTH LATIN CAPITAL LETTER F */
0xFF27, 0xFF47, /* FULLWIDTH LATIN CAPITAL LETTER G */
0xFF28, 0xFF48, /* FULLWIDTH LATIN CAPITAL LETTER H */
0xFF29, 0xFF49, /* FULLWIDTH LATIN CAPITAL LETTER I */
0xFF2A, 0xFF4A, /* FULLWIDTH LATIN CAPITAL LETTER J */
0xFF2B, 0xFF4B, /* FULLWIDTH LATIN CAPITAL LETTER K */
0xFF2C, 0xFF4C, /* FULLWIDTH LATIN CAPITAL LETTER L */
0xFF2D, 0xFF4D, /* FULLWIDTH LATIN CAPITAL LETTER M */
0xFF2E, 0xFF4E, /* FULLWIDTH LATIN CAPITAL LETTER N */
0xFF2F, 0xFF4F, /* FULLWIDTH LATIN CAPITAL LETTER O */
0xFF30, 0xFF50, /* FULLWIDTH LATIN CAPITAL LETTER P */
0xFF31, 0xFF51, /* FULLWIDTH LATIN CAPITAL LETTER Q */
0xFF32, 0xFF52, /* FULLWIDTH LATIN CAPITAL LETTER R */
0xFF33, 0xFF53, /* FULLWIDTH LATIN CAPITAL LETTER S */
0xFF34, 0xFF54, /* FULLWIDTH LATIN CAPITAL LETTER T */
0xFF35, 0xFF55, /* FULLWIDTH LATIN CAPITAL LETTER U */
0xFF36, 0xFF56, /* FULLWIDTH LATIN CAPITAL LETTER V */
0xFF37, 0xFF57, /* FULLWIDTH LATIN CAPITAL LETTER W */
0xFF38, 0xFF58, /* FULLWIDTH LATIN CAPITAL LETTER X */
0xFF39, 0xFF59, /* FULLWIDTH LATIN CAPITAL LETTER Y */
0xFF3A, 0xFF5A, /* FULLWIDTH LATIN CAPITAL LETTER Z */
};
size_t msdosfs_unicode_foldmap_entries = __arraycount(msdosfs_unicode_foldmap);

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vfsops.c,v 1.118 2015/03/28 19:24:05 maxv Exp $ */
/* $NetBSD: msdosfs_vfsops.c,v 1.136 2021/02/11 00:15:55 ryoon Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.118 2015/03/28 19:24:05 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.136 2021/02/11 00:15:55 ryoon Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@ -69,7 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.118 2015/03/28 19:24:05 maxv Ex
#include <sys/device.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#include <sys/fstrans.h>
#include <sys/ioctl.h>
#include <sys/malloc.h>
#include <sys/dirent.h>
@ -107,8 +106,6 @@ MALLOC_JUSTDEFINE(M_MSDOSFSMNT, "MSDOSFS mount", "MSDOS FS mount structure");
MALLOC_JUSTDEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOS FS FAT table");
MALLOC_JUSTDEFINE(M_MSDOSFSTMP, "MSDOSFS temp", "MSDOS FS temp. structures");
static struct sysctllog *msdosfs_sysctl_log;
extern const struct vnodeopv_desc msdosfs_vnodeop_opv_desc;
const struct vnodeopv_desc * const msdosfs_vnodeopv_descs[] = {
@ -136,13 +133,28 @@ struct vfsops msdosfs_vfsops = {
.vfs_mountroot = msdosfs_mountroot,
.vfs_snapshot = (void *)eopnotsupp,
.vfs_extattrctl = vfs_stdextattrctl,
.vfs_suspendctl = msdosfs_suspendctl,
.vfs_suspendctl = genfs_suspendctl,
.vfs_renamelock_enter = genfs_renamelock_enter,
.vfs_renamelock_exit = genfs_renamelock_exit,
.vfs_fsync = (void *)eopnotsupp,
.vfs_opv_descs = msdosfs_vnodeopv_descs
};
SYSCTL_SETUP(msdosfs_sysctl_setup, "msdosfs sysctl")
{
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "msdosfs",
SYSCTL_DESCR("MS-DOS file system"),
NULL, 0, NULL, 0,
CTL_VFS, 4, CTL_EOL);
/*
* XXX the "4" above could be dynamic, thereby eliminating one
* more instance of the "number to vfs" mapping problem, but
* "4" is the order as taken from sys/mount.h
*/
}
static int
msdos_modcmd(modcmd_t cmd, void *arg)
{
@ -153,23 +165,11 @@ msdos_modcmd(modcmd_t cmd, void *arg)
error = vfs_attach(&msdosfs_vfsops);
if (error != 0)
break;
sysctl_createv(&msdosfs_sysctl_log, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "msdosfs",
SYSCTL_DESCR("MS-DOS file system"),
NULL, 0, NULL, 0,
CTL_VFS, 4, CTL_EOL);
/*
* XXX the "4" above could be dynamic, thereby eliminating one
* more instance of the "number to vfs" mapping problem, but
* "4" is the order as taken from sys/mount.h
*/
break;
case MODULE_CMD_FINI:
error = vfs_detach(&msdosfs_vfsops);
if (error != 0)
break;
sysctl_teardown(&msdosfs_sysctl_log);
break;
default:
error = ENOTTY;
@ -210,7 +210,8 @@ update_mp(struct mount *mp, struct msdosfs_args *argp)
if (FAT32(pmp))
pmp->pm_flags |= MSDOSFSMNT_LONGNAME;
else {
if ((error = msdosfs_root(mp, &rtvp)) != 0)
error = msdosfs_root(mp, LK_EXCLUSIVE, &rtvp);
if (error != 0)
return error;
pmp->pm_flags |= findwin95(VTODE(rtvp))
? MSDOSFSMNT_LONGNAME
@ -248,22 +249,22 @@ msdosfs_mountroot(void)
args.dirmask = 0777;
if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) {
vfs_unbusy(mp, false, NULL);
vfs_destroy(mp);
vfs_unbusy(mp);
vfs_rele(mp);
return (error);
}
if ((error = update_mp(mp, &args)) != 0) {
(void)msdosfs_unmount(mp, 0);
vfs_unbusy(mp, false, NULL);
vfs_destroy(mp);
vfs_unbusy(mp);
vfs_rele(mp);
vrele(rootvp);
return (error);
}
mountlist_append(mp);
(void)msdosfs_statvfs(mp, &mp->mnt_stat);
vfs_unbusy(mp, false, NULL);
vfs_unbusy(mp);
return (0);
}
@ -468,6 +469,7 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
int ronly, error, BlkPerSec;
uint64_t psize;
unsigned secsize;
u_long fatbytes, fatblocksecs;
/* Flush out any old buffers remaining from a previous use. */
if ((error = vinvalbuf(devvp, V_SAVE, l->l_cred, l, 0, 0)) != 0)
@ -478,10 +480,6 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
bp = NULL; /* both used in error_exit */
pmp = NULL;
error = fstrans_mount(mp);
if (error)
goto error_exit;
error = getdisksize(devvp, &psize, &secsize);
if (error) {
if (argp->flags & MSDOSFSMNT_GEMDOSFS)
@ -522,6 +520,13 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
b50 = (struct byte_bpb50 *)bsp->bs50.bsBPB;
b710 = (struct byte_bpb710 *)bsp->bs710.bsBPB;
#if 0
/*
* Some FAT partition, for example Raspberry Pi Pico's
* USB mass storage, does not have exptected BOOTSIGs.
* According to FreeBSD's comment, some PC-9800/9821
* FAT floppy disks have similar problems.
*/
if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) {
if (bsp->bs50.bsBootSectSig0 != BOOTSIG0
|| bsp->bs50.bsBootSectSig1 != BOOTSIG1) {
@ -532,6 +537,7 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
goto error_exit;
}
}
#endif
pmp = malloc(sizeof(*pmp), M_MSDOSFSMNT, M_WAITOK|M_ZERO);
pmp->pm_mountp = mp;
@ -715,12 +721,40 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
pmp->pm_fatdiv = 1;
}
}
if (FAT12(pmp))
pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
else
pmp->pm_fatblocksize = MAXBSIZE;
pmp->pm_fatblocksec = pmp->pm_fatblocksize / pmp->pm_BytesPerSec;
/* validate cluster count against FAT */
if ((pmp->pm_maxcluster & pmp->pm_fatmask) != pmp->pm_maxcluster) {
DPRINTF("maxcluster %lu outside of mask %#lx\n",
pmp->pm_maxcluster, pmp->pm_fatmask);
error = EINVAL;
goto error_exit;
}
/* validate FAT size */
fatbytes = (pmp->pm_maxcluster+1) * pmp->pm_fatmult / pmp->pm_fatdiv;
fatblocksecs = howmany(fatbytes, pmp->pm_BytesPerSec);
if (pmp->pm_FATsecs < fatblocksecs) {
DPRINTF("FATsecs %lu < real %lu\n", pmp->pm_FATsecs,
fatblocksecs);
error = EINVAL;
goto error_exit;
}
if (FAT12(pmp)) {
/*
* limit block size to what is needed to read a FAT block
* to not exceed MAXBSIZE
*/
pmp->pm_fatblocksec = uimin(3, fatblocksecs);
pmp->pm_fatblocksize = pmp->pm_fatblocksec
* pmp->pm_BytesPerSec;
} else {
pmp->pm_fatblocksize = MAXBSIZE;
pmp->pm_fatblocksec = pmp->pm_fatblocksize
/ pmp->pm_BytesPerSec;
}
pmp->pm_bnshift = ffs(pmp->pm_BytesPerSec) - 1;
/*
@ -842,6 +876,7 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];
mp->mnt_stat.f_namemax = MSDOSFS_NAMEMAX(pmp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_iflag |= IMNT_SHRLOOKUP;
mp->mnt_dev_bshift = pmp->pm_bnshift;
mp->mnt_fs_bshift = pmp->pm_cnshift;
@ -858,7 +893,6 @@ msdosfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l, struct msd
return (0);
error_exit:
fstrans_unmount(mp);
if (bp)
brelse(bp, BC_AGE);
if (pmp) {
@ -900,13 +934,10 @@ msdosfs_unmount(struct mount *mp, int mntflags)
printf("msdosfs_umount(): just before calling VOP_CLOSE()\n");
printf("flag %08x, usecount %d, writecount %d, holdcnt %d\n",
vp->v_vflag | vp->v_iflag | vp->v_uflag, vp->v_usecount,
vp->v_vflag | vp->v_iflag | vp->v_uflag, vrefcnt(vp),
vp->v_writecount, vp->v_holdcnt);
printf("mount %p, op %p\n",
vp->v_mount, vp->v_op);
printf("freef %p, freeb %p, mount %p\n",
vp->v_freelist.tqe_next, vp->v_freelist.tqe_prev,
vp->v_mount);
printf("cleanblkhd %p, dirtyblkhd %p, numoutput %d, type %d\n",
vp->v_cleanblkhd.lh_first,
vp->v_dirtyblkhd.lh_first,
@ -926,12 +957,11 @@ msdosfs_unmount(struct mount *mp, int mntflags)
free(pmp, M_MSDOSFSMNT);
mp->mnt_data = NULL;
mp->mnt_flag &= ~MNT_LOCAL;
fstrans_unmount(mp);
return (0);
}
int
msdosfs_root(struct mount *mp, struct vnode **vpp)
msdosfs_root(struct mount *mp, int lktype, struct vnode **vpp)
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
int error;
@ -941,7 +971,7 @@ msdosfs_root(struct mount *mp, struct vnode **vpp)
#endif
if ((error = deget(pmp, MSDOSFSROOT, MSDOSFSROOT_OFS, vpp)) != 0)
return error;
error = vn_lock(*vpp, LK_EXCLUSIVE);
error = vn_lock(*vpp, lktype);
if (error) {
vrele(*vpp);
*vpp = NULL;
@ -981,12 +1011,14 @@ msdosfs_sync_selector(void *cl, struct vnode *vp)
struct msdosfs_sync_ctx *c = cl;
struct denode *dep;
KASSERT(mutex_owned(vp->v_interlock));
dep = VTODE(vp);
if (c->waitfor == MNT_LAZY || vp->v_type == VNON ||
dep == NULL || (((dep->de_flag &
(DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) &&
(LIST_EMPTY(&vp->v_dirtyblkhd) &&
UVM_OBJ_IS_CLEAN(&vp->v_uobj))))
(vp->v_iflag & VI_ONWORKLST) == 0)))
return false;
return true;
}
@ -1011,7 +1043,6 @@ msdosfs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
/* update FATs here */
}
}
fstrans_start(mp, FSTRANS_SHARED);
/*
* Write back each (modified) denode.
*/
@ -1035,15 +1066,16 @@ msdosfs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
/*
* Force stale file system control information to be flushed.
*/
vn_lock(pmp->pm_devvp, LK_EXCLUSIVE | LK_RETRY);
if ((error = VOP_FSYNC(pmp->pm_devvp, cred,
waitfor == MNT_WAIT ? FSYNC_WAIT : 0, 0, 0)) != 0)
allerror = error;
fstrans_done(mp);
VOP_UNLOCK(pmp->pm_devvp);
return (allerror);
}
int
msdosfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
msdosfs_fhtovp(struct mount *mp, struct fid *fhp, int lktype, struct vnode **vpp)
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct defid defh;
@ -1069,7 +1101,7 @@ msdosfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
*vpp = NULLVP;
return error;
}
error = vn_lock(*vpp, LK_EXCLUSIVE);
error = vn_lock(*vpp, lktype);
if (error) {
vrele(*vpp);
*vpp = NULLVP;
@ -1104,36 +1136,9 @@ msdosfs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size)
}
int
msdosfs_vget(struct mount *mp, ino_t ino,
msdosfs_vget(struct mount *mp, ino_t ino, int lktype,
struct vnode **vpp)
{
return (EOPNOTSUPP);
}
int
msdosfs_suspendctl(struct mount *mp, int cmd)
{
int error;
struct lwp *l = curlwp;
switch (cmd) {
case SUSPEND_SUSPEND:
if ((error = fstrans_setstate(mp, FSTRANS_SUSPENDING)) != 0)
return error;
error = msdosfs_sync(mp, MNT_WAIT, l->l_proc->p_cred);
if (error == 0)
error = fstrans_setstate(mp, FSTRANS_SUSPENDED);
if (error != 0) {
(void) fstrans_setstate(mp, FSTRANS_NORMAL);
return error;
}
return 0;
case SUSPEND_RESUME:
return fstrans_setstate(mp, FSTRANS_NORMAL);
default:
return EINVAL;
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vnops.c,v 1.93 2015/04/04 12:34:44 riastradh Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.104 2020/06/27 17:29:18 christos Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.93 2015/04/04 12:34:44 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.104 2020/06/27 17:29:18 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -60,7 +60,6 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.93 2015/04/04 12:34:44 riastradh
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/fstrans.h>
#include <sys/vnode.h>
#include <sys/signalvar.h>
#include <sys/malloc.h>
@ -120,7 +119,6 @@ msdosfs_create(void *v)
printf("msdosfs_create(cnp %p, vap %p\n", cnp, ap->a_vap);
#endif
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
/*
* If this is the root directory and there is no space left we
* can't do anything. This is because the root directory can not
@ -153,13 +151,13 @@ msdosfs_create(void *v)
DETIMES(&ndirent, NULL, NULL, NULL, pdep->de_pmp->pm_gmtoff);
if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)
goto bad;
fstrans_done(ap->a_dvp->v_mount);
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
*ap->a_vpp = DETOV(dep);
cache_enter(ap->a_dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
cnp->cn_flags);
return (0);
bad:
fstrans_done(ap->a_dvp->v_mount);
return (error);
}
@ -174,17 +172,15 @@ msdosfs_close(void *v)
struct vnode *vp = ap->a_vp;
struct denode *dep = VTODE(vp);
fstrans_start(vp->v_mount, FSTRANS_SHARED);
mutex_enter(vp->v_interlock);
if (vp->v_usecount > 1)
if (vrefcnt(vp) > 1)
DETIMES(dep, NULL, NULL, NULL, dep->de_pmp->pm_gmtoff);
mutex_exit(vp->v_interlock);
fstrans_done(vp->v_mount);
return (0);
}
static int
msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode)
msdosfs_check_possible(struct vnode *vp, struct denode *dep, accmode_t accmode)
{
/*
@ -192,7 +188,7 @@ msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode)
* unless the file is a socket, fifo, or a block or
* character device resident on the file system.
*/
if (mode & VWRITE) {
if (accmode & VWRITE) {
switch (vp->v_type) {
case VDIR:
case VLNK:
@ -208,7 +204,7 @@ msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode)
}
static int
msdosfs_check_permitted(struct vnode *vp, struct denode *dep, mode_t mode,
msdosfs_check_permitted(struct vnode *vp, struct denode *dep, accmode_t accmode,
kauth_cred_t cred)
{
struct msdosfsmount *pmp = dep->de_pmp;
@ -221,9 +217,9 @@ msdosfs_check_permitted(struct vnode *vp, struct denode *dep, mode_t mode,
file_mode &= (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask);
return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(mode,
vp->v_type, file_mode), vp, NULL, genfs_can_access(vp->v_type,
file_mode, pmp->pm_uid, pmp->pm_gid, mode, cred));
return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(accmode,
vp->v_type, file_mode), vp, NULL, genfs_can_access(vp, cred,
pmp->pm_uid, pmp->pm_gid, file_mode, NULL, accmode));
}
int
@ -231,18 +227,18 @@ msdosfs_access(void *v)
{
struct vop_access_args /* {
struct vnode *a_vp;
int a_mode;
accmode_t a_accmode;
kauth_cred_t a_cred;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct denode *dep = VTODE(vp);
int error;
error = msdosfs_check_possible(vp, dep, ap->a_mode);
error = msdosfs_check_possible(vp, dep, ap->a_accmode);
if (error)
return error;
error = msdosfs_check_permitted(vp, dep, ap->a_mode, ap->a_cred);
error = msdosfs_check_permitted(vp, dep, ap->a_accmode, ap->a_cred);
return error;
}
@ -262,7 +258,6 @@ msdosfs_getattr(void *v)
u_long dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry);
ino_t fileid;
fstrans_start(ap->a_vp->v_mount, FSTRANS_SHARED);
DETIMES(dep, NULL, NULL, NULL, pmp->pm_gmtoff);
vap->va_fsid = dep->de_dev;
/*
@ -313,7 +308,6 @@ msdosfs_getattr(void *v)
vap->va_bytes =
(dep->de_FileSize + pmp->pm_crbomask) & ~pmp->pm_crbomask;
vap->va_type = ap->a_vp->v_type;
fstrans_done(ap->a_vp->v_mount);
return (0);
}
@ -361,7 +355,6 @@ msdosfs_setattr(void *v)
if (ap->a_vp->v_type == VDIR)
return 0;
fstrans_start(vp->v_mount, FSTRANS_SHARED);
if (vap->va_size != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
error = EROFS;
@ -378,8 +371,8 @@ msdosfs_setattr(void *v)
goto bad;
}
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES,
ap->a_vp, NULL, genfs_can_chtimes(ap->a_vp, vap->va_vaflags,
pmp->pm_uid, cred));
ap->a_vp, NULL, genfs_can_chtimes(ap->a_vp, cred,
pmp->pm_uid, vap->va_vaflags));
if (error)
goto bad;
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
@ -402,7 +395,7 @@ msdosfs_setattr(void *v)
goto bad;
}
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_FLAGS, vp,
NULL, genfs_can_chflags(cred, vp->v_type, pmp->pm_uid, false));
NULL, genfs_can_chflags(vp, cred, pmp->pm_uid, false));
if (error)
goto bad;
/* We ignore the read and execute bits. */
@ -422,7 +415,7 @@ msdosfs_setattr(void *v)
goto bad;
}
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_FLAGS, vp,
NULL, genfs_can_chflags(cred, vp->v_type, pmp->pm_uid, false));
NULL, genfs_can_chflags(vp, cred, pmp->pm_uid, false));
if (error)
goto bad;
if (vap->va_flags & SF_ARCHIVED)
@ -441,7 +434,6 @@ msdosfs_setattr(void *v)
}
bad:
fstrans_done(vp->v_mount);
return error;
}
@ -478,7 +470,6 @@ msdosfs_read(void *v)
if (uio->uio_offset >= dep->de_FileSize)
return (0);
fstrans_start(vp->v_mount, FSTRANS_SHARED);
if (vp->v_type == VREG) {
const int advice = IO_ADV_DECODE(ap->a_ioflag);
@ -489,7 +480,7 @@ msdosfs_read(void *v)
if (bytelen == 0)
break;
error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
UBC_READ | UBC_PARTIALOK | UBC_VNODE_FLAGS(vp));
if (error)
break;
}
@ -503,7 +494,6 @@ msdosfs_read(void *v)
on = uio->uio_offset & pmp->pm_crbomask;
n = MIN(pmp->pm_bpcluster - on, uio->uio_resid);
if (uio->uio_offset >= dep->de_FileSize) {
fstrans_done(vp->v_mount);
return (0);
}
/* file size (and hence diff) may be up to 4GB */
@ -540,7 +530,6 @@ out:
error = uerror;
}
bad:
fstrans_done(vp->v_mount);
return (error);
}
@ -599,7 +588,6 @@ msdosfs_write(void *v)
if (uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX)
return (EFBIG);
fstrans_start(vp->v_mount, FSTRANS_SHARED);
/*
* If the offset we are starting the write at is beyond the end of
* the file, then they've done a seek. Unix filesystems allow
@ -608,7 +596,6 @@ msdosfs_write(void *v)
*/
if (uio->uio_offset > dep->de_FileSize) {
if ((error = deextend(dep, uio->uio_offset, cred)) != 0) {
fstrans_done(vp->v_mount);
return (error);
}
}
@ -637,7 +624,7 @@ msdosfs_write(void *v)
rem = round_page(dep->de_FileSize) - dep->de_FileSize;
if (rem > 0)
ubc_zerorange(&vp->v_uobj, (off_t)dep->de_FileSize,
rem, UBC_UNMAP_FLAG(vp));
rem, UBC_VNODE_FLAGS(vp));
extended = 1;
}
@ -646,7 +633,7 @@ msdosfs_write(void *v)
bytelen = uio->uio_resid;
error = ubc_uiomove(&vp->v_uobj, uio, bytelen,
IO_ADV_DECODE(ioflag), UBC_WRITE | UBC_UNMAP_FLAG(vp));
IO_ADV_DECODE(ioflag), UBC_WRITE | UBC_VNODE_FLAGS(vp));
if (error)
break;
@ -656,7 +643,7 @@ msdosfs_write(void *v)
*/
if (!async && oldoff >> 16 != uio->uio_offset >> 16) {
mutex_enter(vp->v_interlock);
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,
(uio->uio_offset >> 16) << 16,
PGO_CLEANIT | PGO_LAZY);
@ -666,7 +653,7 @@ msdosfs_write(void *v)
/* set final size */
uvm_vnp_setsize(vp, dep->de_FileSize);
if (error == 0 && ioflag & IO_SYNC) {
mutex_enter(vp->v_interlock);
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
error = VOP_PUTPAGES(vp, trunc_page(oldoff),
round_page(oldoff + bytelen), PGO_CLEANIT | PGO_SYNCIO);
}
@ -685,7 +672,6 @@ errexit:
uio->uio_resid = resid;
} else if ((ioflag & IO_SYNC) == IO_SYNC)
error = deupdat(dep, 1);
fstrans_done(vp->v_mount);
KASSERT(vp->v_size == dep->de_FileSize);
return (error);
}
@ -731,7 +717,7 @@ msdosfs_update(struct vnode *vp, const struct timespec *acc,
int
msdosfs_remove(void *v)
{
struct vop_remove_args /* {
struct vop_remove_v2_args /* {
struct vnode *a_dvp;
struct vnode *a_vp;
struct componentname *a_cnp;
@ -740,14 +726,13 @@ msdosfs_remove(void *v)
struct denode *ddep = VTODE(ap->a_dvp);
int error;
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
if (ap->a_vp->v_type == VDIR)
error = EPERM;
else
error = removede(ddep, dep);
#ifdef MSDOSFS_DEBUG
printf("msdosfs_remove(), dep %p, v_usecount %d\n",
dep, ap->a_vp->v_usecount);
printf("msdosfs_remove(), dep %p, usecount %d\n",
dep, vrefcnt(ap->a_vp));
#endif
VN_KNOTE(ap->a_vp, NOTE_DELETE);
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
@ -756,8 +741,7 @@ msdosfs_remove(void *v)
else
vput(ap->a_vp); /* causes msdosfs_inactive() to be called
* via vrele() */
vput(ap->a_dvp);
fstrans_done(ap->a_dvp->v_mount);
return (error);
}
@ -832,7 +816,6 @@ msdosfs_rename(void *v)
struct vnode *tdvp = ap->a_tdvp;
struct vnode *fvp = ap->a_fvp;
struct vnode *fdvp = ap->a_fdvp;
struct mount *mp = fdvp->v_mount;
struct componentname *tcnp = ap->a_tcnp;
struct componentname *fcnp = ap->a_fcnp;
struct denode *ip, *xp, *dp, *zp;
@ -910,7 +893,6 @@ abortit:
}
VN_KNOTE(fdvp, NOTE_WRITE); /* XXXLUKEM/XXX: right place? */
fstrans_start(mp, FSTRANS_SHARED);
/*
* When the target exists, both the directory
* and target vnodes are returned locked.
@ -997,7 +979,6 @@ abortit:
* file/directory.
*/
if ((error = uniqdosname(VTODE(tdvp), tcnp, toname)) != 0) {
fstrans_done(mp);
goto abortit;
}
@ -1013,7 +994,6 @@ abortit:
VOP_UNLOCK(fdvp);
vrele(ap->a_fvp);
vrele(tdvp);
fstrans_done(mp);
return (error);
}
if (fvp == NULL) {
@ -1025,7 +1005,6 @@ abortit:
vput(fdvp);
vrele(ap->a_fvp);
vrele(tdvp);
fstrans_done(mp);
return 0;
}
VOP_UNLOCK(fdvp);
@ -1140,7 +1119,6 @@ bad:
ip->de_flag &= ~DE_RENAME;
vrele(fdvp);
vrele(fvp);
fstrans_done(mp);
return (error);
/* XXX: uuuh */
@ -1197,7 +1175,6 @@ msdosfs_mkdir(void *v)
struct buf *bp;
int async = pdep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC;
fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
/*
* If this is the root directory and there is no space left we
* can't do anything. This is because the root directory can not
@ -1280,27 +1257,24 @@ msdosfs_mkdir(void *v)
goto bad;
VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK);
*ap->a_vpp = DETOV(dep);
fstrans_done(ap->a_dvp->v_mount);
return (0);
bad:
clusterfree(pmp, newcluster, NULL);
bad2:
fstrans_done(ap->a_dvp->v_mount);
return (error);
}
int
msdosfs_rmdir(void *v)
{
struct vop_rmdir_args /* {
struct vop_rmdir_v2_args /* {
struct vnode *a_dvp;
struct vnode *a_vp;
struct componentname *a_cnp;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct vnode *dvp = ap->a_dvp;
struct mount *mp = dvp->v_mount;
struct componentname *cnp = ap->a_cnp;
struct denode *ip, *dp;
int error;
@ -1311,11 +1285,9 @@ msdosfs_rmdir(void *v)
* No rmdir "." please.
*/
if (dp == ip) {
vrele(dvp);
vput(vp);
vrele(vp);
return (EINVAL);
}
fstrans_start(mp, FSTRANS_SHARED);
/*
* Verify the directory is empty (and valid).
* (Rmdir ".." won't be valid since
@ -1345,8 +1317,6 @@ msdosfs_rmdir(void *v)
*/
VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
cache_purge(dvp);
vput(dvp);
dvp = NULL;
/*
* Truncate the directory that is being deleted.
*/
@ -1354,10 +1324,7 @@ msdosfs_rmdir(void *v)
cache_purge(vp);
out:
VN_KNOTE(vp, NOTE_DELETE);
if (dvp)
vput(dvp);
vput(vp);
fstrans_done(mp);
return (error);
}
@ -1394,6 +1361,7 @@ msdosfs_readdir(void *v)
int ncookies = 0, nc = 0;
off_t offset, uio_off;
int chksum = -1;
uint16_t namlen;
#ifdef MSDOSFS_DEBUG
printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n",
@ -1423,7 +1391,6 @@ msdosfs_readdir(void *v)
uio->uio_resid = count;
uio_off = uio->uio_offset;
fstrans_start(ap->a_vp->v_mount, FSTRANS_SHARED);
/* Allocate a temporary dirent buffer. */
dirbuf = malloc(sizeof(struct dirent), M_MSDOSFSTMP, M_WAITOK | M_ZERO);
@ -1541,7 +1508,10 @@ msdosfs_readdir(void *v)
if (pmp->pm_flags & MSDOSFSMNT_SHORTNAME)
continue;
chksum = win2unixfn((struct winentry *)dentp,
dirbuf, chksum);
dirbuf, chksum, &namlen,
pmp->pm_flags & MSDOSFSMNT_UTF8);
if (chksum != -1)
dirbuf->d_namlen = namlen;
continue;
}
@ -1584,6 +1554,7 @@ msdosfs_readdir(void *v)
pmp->pm_flags & MSDOSFSMNT_SHORTNAME);
else
dirbuf->d_name[dirbuf->d_namlen] = 0;
namlen = dirbuf->d_namlen;
chksum = -1;
dirbuf->d_reclen = _DIRENT_SIZE(dirbuf);
if (uio->uio_resid < dirbuf->d_reclen) {
@ -1627,7 +1598,6 @@ out:
bad:
free(dirbuf, M_MSDOSFSTMP);
fstrans_done(ap->a_vp->v_mount);
return (error);
}
@ -1795,7 +1765,7 @@ msdosfs_pathconf(void *v)
*ap->a_retval = 32;
return (0);
default:
return (EINVAL);
return genfs_pathconf(ap);
}
/* NOTREACHED */
}
@ -1814,7 +1784,6 @@ msdosfs_fsync(void *v)
int wait;
int error;
fstrans_start(vp->v_mount, FSTRANS_LAZY);
wait = (ap->a_flags & FSYNC_WAIT) != 0;
error = vflushbuf(vp, ap->a_flags);
if (error == 0 && (ap->a_flags & FSYNC_DATAONLY) == 0)
@ -1828,7 +1797,6 @@ msdosfs_fsync(void *v)
error = VOP_IOCTL(devvp, DIOCCACHESYNC, &l, FWRITE,
curlwp->l_cred);
}
fstrans_done(vp->v_mount);
return (error);
}
@ -1879,6 +1847,7 @@ const struct vnodeopv_entry_desc msdosfs_vnodeop_entries[] = {
{ &vop_open_desc, genfs_nullop }, /* open */
{ &vop_close_desc, msdosfs_close }, /* close */
{ &vop_access_desc, msdosfs_access }, /* access */
{ &vop_accessx_desc, genfs_accessx }, /* accessx */
{ &vop_getattr_desc, msdosfs_getattr }, /* getattr */
{ &vop_setattr_desc, msdosfs_setattr }, /* setattr */
{ &vop_read_desc, msdosfs_read }, /* read */

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfsmount.h,v 1.20 2014/07/08 09:21:52 hannken Exp $ */
/* $NetBSD: msdosfsmount.h,v 1.21 2016/01/30 09:59:27 mlelstv Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -78,11 +78,12 @@ struct msdosfs_args {
#define MSDOSFSMNT_NOWIN95 4 /* Completely ignore Win95 entries */
#define MSDOSFSMNT_GEMDOSFS 8 /* This is a GEMDOS-flavour */
#define MSDOSFSMNT_VERSIONED 16 /* Struct is versioned */
#define MSDOSFSMNT_UTF8 32 /* Use UTF8 filenames */
/* All flags above: */
#define MSDOSFSMNT_MNTOPT \
(MSDOSFSMNT_SHORTNAME|MSDOSFSMNT_LONGNAME|MSDOSFSMNT_NOWIN95 \
|MSDOSFSMNT_GEMDOSFS|MSDOSFSMNT_VERSIONED)
|MSDOSFSMNT_GEMDOSFS|MSDOSFSMNT_VERSIONED|MSDOSFSMNT_UTF8)
#define MSDOSFSMNT_RONLY 0x80000000 /* mounted read-only */
#define MSDOSFSMNT_WAITONFAT 0x40000000 /* mounted synchronous */
@ -90,7 +91,7 @@ struct msdosfs_args {
#define MSDOSFSMNT_BITS "\177\20" \
"b\00shortname\0b\01longname\0b\02nowin95\0b\03gemdosfs\0b\04mntversioned\0" \
"b\037ronly\0b\036waitonfat\0b\035fatmirror\0"
"b\05utf8\0b\037ronly\0b\036waitonfat\0b\035fatmirror\0"
#ifdef _KERNEL
#include <sys/mallocvar.h>

View File

@ -1,8 +1,8 @@
/* $NetBSD: ecma167-udf.h,v 1.14 2011/07/07 17:45:38 reinoud Exp $ */
/* $NetBSD: ecma167-udf.h,v 1.16 2018/08/09 13:49:30 reinoud Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2008, 2009
* Reinoud Zandijk * <reinoud@NetBSD.org>
* Copyright (c) 2003, 2004, 2005, 2006, 2008, 2009, 2017, 2018
* Reinoud Zandijk <reinoud@NetBSD.org>
* Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
* All rights reserved.
*
@ -203,14 +203,14 @@ union icb {
/* short/long/ext extent have flags encoded in length */
#define UDF_EXT_ALLOCATED (0<<30)
#define UDF_EXT_FREED (1<<30)
#define UDF_EXT_ALLOCATED_BUT_NOT_USED (1<<30)
#define UDF_EXT_FREE (2<<30)
#define UDF_EXT_REDIRECT (3<<30)
#define UDF_EXT_FLAGS(len) ((len) & (3<<30))
#define UDF_EXT_LEN(len) ((len) & ((1<<30)-1))
#define UDF_EXT_MAXLEN ((1<<30)-1)
#define UDF_EXT_ALLOCATED (0U<<30)
#define UDF_EXT_FREED (1U<<30)
#define UDF_EXT_ALLOCATED_BUT_NOT_USED (1U<<30)
#define UDF_EXT_FREE (2U<<30)
#define UDF_EXT_REDIRECT (3U<<30)
#define UDF_EXT_FLAGS(len) ((len) & (3U<<30))
#define UDF_EXT_LEN(len) ((len) & ((1U<<30)-1))
#define UDF_EXT_MAXLEN ((1U<<30)-1)
/* Character set spec [1/7.2.1] */
@ -264,7 +264,10 @@ struct regid {
struct icb_tag {
uint32_t prev_num_dirs;
uint16_t strat_type;
uint8_t strat_param[2];
union {
uint8_t strat_param[2];
uint16_t strat_param16;
};
uint16_t max_num_entries;
uint8_t reserved;
uint8_t file_type;
@ -682,7 +685,10 @@ struct impl_extattr_entry {
struct extattr_entry hdr;
uint32_t iu_l;
struct regid imp_id;
uint8_t data[1];
union {
uint8_t data[1];
uint16_t data16;
};
} __packed;
@ -832,4 +838,3 @@ union dscrptr {
#endif /* !_FS_UDF_ECMA167_UDF_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf.h,v 1.50 2015/08/24 08:31:56 hannken Exp $ */
/* $NetBSD: udf.h,v 1.52 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -76,7 +76,7 @@ extern int udf_verbose;
#define UDF_DEBUG_RESERVE 0x1000000
/* initial value of udf_verbose */
#define UDF_DEBUGGING 0
#define UDF_DEBUGGING (0)
#ifdef UDF_DEBUG
#define DPRINTF(name, arg) { \
@ -252,6 +252,7 @@ struct udf_strategy {
int (*read_logvol_dscr) (struct udf_strat_args *args);
int (*write_logvol_dscr) (struct udf_strat_args *args);
void (*queuebuf) (struct udf_strat_args *args);
void (*sync_caches) (struct udf_strat_args *args);
void (*discstrat_init) (struct udf_strat_args *args);
void (*discstrat_finish) (struct udf_strat_args *args);
};
@ -417,11 +418,12 @@ struct udf_node {
#define IN_SYNCED 0x0200 /* node is being used by sync */
#define IN_CALLBACK_ULK 0x0400 /* node will be unlocked by callback */
#define IN_NODE_REBUILD 0x0800 /* node is rebuild */
#define IN_NO_DELETE 0x1000 /* node is not to be deleted */
#define IN_FLAGBITS \
"\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFY\5IN_MODIFIED" \
"\6IN_ACCESSED\7IN_RENAME\10IN_DELETED\11IN_LOCKED\12IN_SYNCED" \
"\13IN_CALLBACK_ULK\14IN_NODE_REBUILD"
"\13IN_CALLBACK_ULK\14IN_NODE_REBUILD\15IN_NO_DELETE"
#endif /* !_FS_UDF_UDF_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_allocation.c,v 1.38 2015/08/24 08:30:17 hannken Exp $ */
/* $NetBSD: udf_allocation.c,v 1.41 2020/04/23 21:47:08 ad Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.38 2015/08/24 08:30:17 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_allocation.c,v 1.41 2020/04/23 21:47:08 ad Exp $");
#endif /* not lint */
@ -1001,7 +1001,7 @@ udf_bitmap_check_trunc_free(struct udf_bitmap *bitmap, uint32_t to_trunc)
bitval = (1 << bit);
if (!(*bpos & bitval))
seq_free = 0;
offset++; to_trunc--;
to_trunc--;
bit++;
if (bit == 8) {
bpos++;
@ -1540,8 +1540,7 @@ udf_trunc_metadatapart(struct udf_mount *ump, uint32_t num_lb)
*sizepos = udf_rw32(*sizepos) - to_trunc;
/* realloc bitmap for better memory usage */
new_sbd = realloc(sbd, inf_len, M_UDFVOLD,
M_CANFAIL | M_WAITOK);
new_sbd = realloc(sbd, inf_len, M_UDFVOLD, M_WAITOK);
if (new_sbd) {
/* update pointers */
ump->metadata_unalloc_dscr = new_sbd;
@ -2679,7 +2678,7 @@ udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
#if 0
/* zero append space in buffer */
ubc_zerorange(&vp->v_uobj, old_size,
new_size - old_size, UBC_UNMAP_FLAG(vp));
new_size - old_size, UBC_VNODE_FLAGS(vp));
#endif
udf_node_sanity_check(udf_node, &new_inflen, &new_lbrec);
@ -2785,7 +2784,7 @@ udf_grow_node(struct udf_node *udf_node, uint64_t new_size)
/* TODO zero appened space in buffer! */
/* using ubc_zerorange(&vp->v_uobj, old_size, */
/* new_size - old_size, UBC_UNMAP_FLAG(vp)); ? */
/* new_size - old_size, UBC_VNODE_FLAGS(vp)); ? */
}
memset(&s_ad, 0, sizeof(struct long_ad));
@ -2956,7 +2955,7 @@ udf_shrink_node(struct udf_node *udf_node, uint64_t new_size)
/* TODO zero appened space in buffer! */
/* using ubc_zerorange(&vp->v_uobj, old_size, */
/* old_size - new_size, UBC_UNMAP_FLAG(vp)); ? */
/* old_size - new_size, UBC_VNODE_FLAGS(vp)); ? */
/* set new size for uvm */
uvm_vnp_setsize(vp, new_size);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_mount.h,v 1.3 2006/02/02 15:52:23 reinoud Exp $ */
/* $NetBSD: udf_mount.h,v 1.4 2019/10/16 21:52:22 maya Exp $ */
/*
* Copyright (c) 2006 Reinoud Zandijk
@ -12,13 +12,6 @@
* 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 for the
* NetBSD Project. See http://www.NetBSD.org/ for
* information about NetBSD.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_readwrite.c,v 1.11 2011/06/12 03:35:55 rmind Exp $ */
/* $NetBSD: udf_readwrite.c,v 1.12 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2007, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_readwrite.c,v 1.11 2011/06/12 03:35:55 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_readwrite.c,v 1.12 2016/05/24 09:55:57 reinoud Exp $");
#endif /* not lint */
@ -695,6 +695,19 @@ udf_discstrat_queuebuf(struct udf_mount *ump, struct buf *nestbuf)
}
void
udf_synchronise_caches(struct udf_mount *ump)
{
struct udf_strategy *strategy = ump->strategy;
struct udf_strat_args args;
KASSERT(strategy);
args.ump = ump;
(strategy->sync_caches)(&args);
}
void
udf_discstrat_init(struct udf_mount *ump)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_rename.c,v 1.12 2014/11/10 19:44:08 riz Exp $ */
/* $NetBSD: udf_rename.c,v 1.13 2020/01/17 20:08:08 ad Exp $ */
/*
* Copyright (c) 2013 Reinoud Zandijk
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.12 2014/11/10 19:44:08 riz Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.13 2020/01/17 20:08:08 ad Exp $");
#include <sys/param.h>
#include <sys/errno.h>
@ -465,7 +465,7 @@ udf_gro_lookup(struct mount *mp, struct vnode *dvp,
return ENOENT;
DPRINTF(LOOKUP, ("udf_gro_lookup found '%s'\n", name));
error = udf_get_node(dir_node->ump, &icb_loc, &res_node);
error = udf_get_node(dir_node->ump, &icb_loc, &res_node, LK_EXCLUSIVE);
if (error)
return error;
*vp_ret = res_node->vnode;
@ -598,7 +598,8 @@ udf_gro_genealogy(struct mount *mp, kauth_cred_t cred,
*/
DPRINTF(NODE, ("\tgetting the parent node\n"));
VOP_UNLOCK(vp);
error = udf_get_node(ump, &parent_loc, &parent_node);
error = udf_get_node(ump, &parent_loc, &parent_node,
LK_EXCLUSIVE);
vrele(vp);
if (error)
return error;

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_strat_bootstrap.c,v 1.4 2014/11/10 18:46:33 maxv Exp $ */
/* $NetBSD: udf_strat_bootstrap.c,v 1.5 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_strat_bootstrap.c,v 1.4 2014/11/10 18:46:33 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_strat_bootstrap.c,v 1.5 2016/05/24 09:55:57 reinoud Exp $");
#endif /* not lint */
@ -115,6 +115,14 @@ udf_queuebuf_bootstrap(struct udf_strat_args *args)
VOP_STRATEGY(ump->devvp, buf);
}
static void
udf_sync_caches_bootstrap(struct udf_strat_args *args)
{
/* empty */
}
static void
udf_discstrat_init_bootstrap(struct udf_strat_args *args)
{
@ -137,6 +145,7 @@ struct udf_strategy udf_strat_bootstrap =
udf_read_logvol_dscr_bootstrap,
udf_write_logvol_dscr_bootstrap,
udf_queuebuf_bootstrap,
udf_sync_caches_bootstrap,
udf_discstrat_init_bootstrap,
udf_discstrat_finish_bootstrap
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_strat_direct.c,v 1.13 2015/10/06 08:57:34 hannken Exp $ */
/* $NetBSD: udf_strat_direct.c,v 1.14 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_strat_direct.c,v 1.13 2015/10/06 08:57:34 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_strat_direct.c,v 1.14 2016/05/24 09:55:57 reinoud Exp $");
#endif /* not lint */
@ -392,6 +392,15 @@ udf_queue_buf_direct(struct udf_strat_args *args)
}
static void
udf_sync_caches_direct(struct udf_strat_args *args)
{
struct udf_mount *ump = args->ump;
udf_mmc_synchronise_caches(ump);
}
static void
udf_discstrat_init_direct(struct udf_strat_args *args)
{
@ -441,6 +450,7 @@ struct udf_strategy udf_strat_direct =
udf_read_nodedscr_direct,
udf_write_nodedscr_direct,
udf_queue_buf_direct,
udf_sync_caches_direct,
udf_discstrat_init_direct,
udf_discstrat_finish_direct
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_strat_rmw.c,v 1.27 2015/10/06 08:57:34 hannken Exp $ */
/* $NetBSD: udf_strat_rmw.c,v 1.28 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.27 2015/10/06 08:57:34 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.28 2016/05/24 09:55:57 reinoud Exp $");
#endif /* not lint */
@ -1005,6 +1005,16 @@ udf_queuebuf_rmw(struct udf_strat_args *args)
/* --------------------------------------------------------------------- */
static void
udf_sync_caches_rmw(struct udf_strat_args *args)
{
struct udf_mount *ump = args->ump;
udf_mmc_synchronise_caches(ump);
}
/* --------------------------------------------------------------------- */
static void
udf_shedule_read_callback(struct buf *buf)
{
@ -1495,6 +1505,7 @@ struct udf_strategy udf_strat_rmw =
udf_read_nodedscr_rmw,
udf_write_nodedscr_rmw,
udf_queuebuf_rmw,
udf_sync_caches_rmw,
udf_discstrat_init_rmw,
udf_discstrat_finish_rmw
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_strat_sequential.c,v 1.14 2015/10/06 08:57:34 hannken Exp $ */
/* $NetBSD: udf_strat_sequential.c,v 1.15 2016/05/24 09:55:57 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_strat_sequential.c,v 1.14 2015/10/06 08:57:34 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_strat_sequential.c,v 1.15 2016/05/24 09:55:57 reinoud Exp $");
#endif /* not lint */
@ -86,6 +86,7 @@ struct strat_private {
kmutex_t discstrat_mutex; /* disc strategy */
int run_thread; /* thread control */
int sync_req; /* thread control */
int cur_queue;
struct disk_strategy old_strategy_setting;
@ -287,6 +288,30 @@ udf_queuebuf_seq(struct udf_strat_args *args)
/* --------------------------------------------------------------------- */
static void
udf_sync_caches_seq(struct udf_strat_args *args)
{
struct udf_mount *ump = args->ump;
struct strat_private *priv = PRIV(ump);
/* we might be called during unmount inadvertedly, be on safe side */
if (!priv)
return;
/* signal our thread that there might be something to do */
priv->sync_req = 1;
cv_signal(&priv->discstrat_cv);
mutex_enter(&priv->discstrat_mutex);
while (priv->sync_req) {
cv_timedwait(&priv->discstrat_cv,
&priv->discstrat_mutex, hz/8);
}
mutex_exit(&priv->discstrat_mutex);
}
/* --------------------------------------------------------------------- */
/* TODO convert to lb_size */
static void
udf_VAT_mapping_update(struct udf_mount *ump, struct buf *buf, uint32_t lb_map)
@ -539,7 +564,7 @@ udf_discstrat_thread(void *arg)
empty = 1;
mutex_enter(&priv->discstrat_mutex);
while (priv->run_thread || !empty) {
while (priv->run_thread || !empty || priv->sync_req) {
/* process the current selected queue */
udf_doshedule(ump);
empty = (bufq_peek(priv->queues[UDF_SHED_READING]) == NULL);
@ -547,9 +572,16 @@ udf_discstrat_thread(void *arg)
empty &= (bufq_peek(priv->queues[UDF_SHED_SEQWRITING]) == NULL);
/* wait for more if needed */
if (empty)
if (empty) {
if (priv->sync_req) {
/* on sync, we need to simulate a read->write transition */
udf_mmc_synchronise_caches(ump);
priv->cur_queue = UDF_SHED_READING;
priv->sync_req = 0;
}
cv_timedwait(&priv->discstrat_cv,
&priv->discstrat_mutex, hz/8);
}
}
mutex_exit(&priv->discstrat_mutex);
@ -621,6 +653,7 @@ udf_discstrat_init_seq(struct udf_strat_args *args)
/* create our disk strategy thread */
priv->run_thread = 1;
priv->sync_req = 0;
if (kthread_create(PRI_NONE, 0 /* KTHREAD_MPSAFE*/, NULL /* cpu_info*/,
udf_discstrat_thread, ump, &priv->queue_lwp,
"%s", "udf_rw")) {
@ -673,6 +706,7 @@ struct udf_strategy udf_strat_sequential =
udf_read_logvol_dscr_seq,
udf_write_logvol_dscr_seq,
udf_queuebuf_seq,
udf_sync_caches_seq,
udf_discstrat_init_seq,
udf_discstrat_finish_seq
};

View File

@ -1,9 +1,9 @@
/* $NetBSD: udf_subr.c,v 1.132 2015/08/24 08:31:56 hannken Exp $ */
/* $NetBSD: udf_subr.c,v 1.152 2021/01/11 22:02:28 skrll Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -12,7 +12,7 @@
* 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.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
@ -23,13 +23,13 @@
* 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.
*
*
*/
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.132 2015/08/24 08:31:56 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.152 2021/01/11 22:02:28 skrll Exp $");
#endif /* not lint */
@ -319,27 +319,25 @@ udf_setup_writeparams(struct udf_mount *ump)
}
int
udf_synchronise_caches(struct udf_mount *ump)
void
udf_mmc_synchronise_caches(struct udf_mount *ump)
{
struct mmc_op mmc_op;
DPRINTF(CALL, ("udf_synchronise_caches()\n"));
DPRINTF(CALL, ("udf_mcc_synchronise_caches()\n"));
if (ump->vfs_mountp->mnt_flag & MNT_RDONLY)
return 0;
return;
/* discs are done now */
if (ump->discinfo.mmc_class == MMC_CLASS_DISC)
return 0;
return;
memset(&mmc_op, 0, sizeof(struct mmc_op));
mmc_op.operation = MMC_OP_SYNCHRONISECACHE;
/* ignore return code */
(void) VOP_IOCTL(ump->devvp, MMCOP, &mmc_op, FKIOCTL, NOCRED);
return 0;
}
/* --------------------------------------------------------------------- */
@ -811,7 +809,7 @@ udf_lock_node(struct udf_node *udf_node, int flag, char const *fname, const int
if (ret == EWOULDBLOCK) {
DPRINTF(LOCKING, ( "udf_lock_node: udf_node %p would block "
"wanted at %s:%d, previously locked at %s:%d\n",
udf_node, fname, lineno,
udf_node, fname, lineno,
udf_node->lock_fname, udf_node->lock_lineno));
}
}
@ -930,7 +928,7 @@ udf_read_anchors(struct udf_mount *ump)
positions[1] = track_end-256;
positions[2] = track_end;
positions[3] = track_start+512; /* [UDF 2.60/6.11.2] */
/* XXX shouldn't +512 be prefered above +256 for compat with Roxio CD */
/* XXX shouldn't +512 be preferred over +256 for compat with Roxio CD */
ok = 0;
anchorsp = ump->anchors;
@ -946,7 +944,7 @@ udf_read_anchors(struct udf_mount *ump)
/* VATs are only recorded on sequential media, but initialise */
ump->first_possible_vat_location = track_start + 2;
ump->last_possible_vat_location = track_end + last_track.packet_size;
ump->last_possible_vat_location = track_end;
return ok;
}
@ -984,7 +982,7 @@ udf_get_record_vpart(struct udf_mount *ump, int udf_c_type)
}
/*
/*
* BUGALERT: some rogue implementations use random physical partition
* numbers to break other implementations so lookup the number.
*/
@ -1235,7 +1233,7 @@ udf_retrieve_lvint(struct udf_mount *ump)
/* are we linking to a new piece? */
if (dscr && lvint->next_extent.len) {
len = udf_rw32(lvint->next_extent.len);
len = udf_rw32(lvint->next_extent.len);
lbnum = udf_rw32(lvint->next_extent.loc);
if (trace_len >= UDF_LVDINT_SEGMENTS-1) {
@ -1281,7 +1279,7 @@ udf_loose_lvint_history(struct udf_mount *ump)
uint32_t out_ext, out_wpos, out_len;
uint32_t lb_num;
uint32_t len, start;
int ext, minext, extlen, cnt, cpy_len, dscr_type;
int ext, sumext, extlen, cnt, cpy_len, dscr_type;
int losing;
int error;
@ -1289,18 +1287,29 @@ udf_loose_lvint_history(struct udf_mount *ump)
/* search smallest extent */
trace = &ump->lvint_trace[0];
minext = trace->end - trace->start;
sumext = trace->end - trace->start;
for (ext = 1; ext < UDF_LVDINT_SEGMENTS; ext++) {
trace = &ump->lvint_trace[ext];
extlen = trace->end - trace->start;
if (extlen == 0)
break;
minext = MIN(minext, extlen);
sumext += extlen;
}
losing = MIN(minext, UDF_LVINT_LOSSAGE);
/* no sense wiping all */
if (losing == minext)
losing--;
/* just one element? its not legal but be bug compatible */
if (sumext == 1) {
/* overwrite the only entry */
DPRINTF(VOLUMES, ("\tLinux bugcompat overwriting sole entry\n"));
trace = &ump->lvint_trace[0];
trace->wpos = 0;
return 0;
}
losing = MIN(sumext, UDF_LVINT_LOSSAGE);
/* no sense wiping too much */
if (sumext == UDF_LVINT_LOSSAGE)
losing = UDF_LVINT_LOSSAGE/2;
DPRINTF(VOLUMES, ("\tlosing %d entries\n", losing));
@ -1437,7 +1446,6 @@ udf_writeout_lvint(struct udf_mount *ump, int lvflag)
DPRINTF(VOLUMES, ("writing out logvol integrity descriptor\n"));
again:
/* get free space in last chunk */
trace = ump->lvint_trace;
while (trace->wpos > (trace->end - trace->start)) {
@ -1465,11 +1473,20 @@ again:
if (space < 1) {
if (lvflag & UDF_APPENDONLY_LVINT)
return EROFS;
/* loose history by re-writing extents */
error = udf_loose_lvint_history(ump);
if (error)
return error;
goto again;
trace = ump->lvint_trace;
while (trace->wpos > (trace->end - trace->start))
trace++;
space = (trace->end - trace->start) - trace->wpos;
DPRINTF(VOLUMES, ("new try: write start = %d, end = %d, "
"pos = %d, wpos = %d, "
"space = %d\n", trace->start, trace->end,
trace->pos, trace->wpos, space));
}
/* update our integrity descriptor to identify us and timestamp it */
@ -1573,7 +1590,7 @@ udf_read_physical_partition_spacetables(struct udf_mount *ump)
if (partd == NULL)
continue;
parthdr = &partd->_impl_use.part_hdr;
len = udf_rw32(parthdr->unalloc_space_table.len);
if (len) {
printf("UDF mount: space tables not supported\n");
@ -1632,7 +1649,7 @@ udf_read_physical_partition_spacetables(struct udf_mount *ump)
if (partd == NULL)
continue;
parthdr = &partd->_impl_use.part_hdr;
len = udf_rw32(parthdr->freed_space_table.len);
if (len) {
printf("UDF mount: space tables not supported\n");
@ -1673,6 +1690,14 @@ udf_write_physical_partition_spacetables(struct udf_mount *ump, int waitfor)
DPRINTF(VOLUMES, ("Write unalloc. space bitmap %d\n",
lb_num + ptov));
dscr = (union dscrptr *) ump->part_unalloc_dscr[phys_part];
/* force a sane minimum for descriptors CRC length */
/* see UDF 2.3.1.2 and 2.3.8.1 */
KASSERT(udf_rw16(dscr->sbd.tag.id) == TAGID_SPACE_BITMAP);
if (udf_rw16(dscr->sbd.tag.desc_crc_len) == 0)
dscr->sbd.tag.desc_crc_len = udf_rw16(8);
/* write out space bitmap */
error = udf_write_phys_dscr_sync(ump, NULL, UDF_C_DSCR,
(union dscrptr *) dscr,
ptov + lb_num, lb_num);
@ -1699,6 +1724,14 @@ udf_write_physical_partition_spacetables(struct udf_mount *ump, int waitfor)
DPRINTF(VOLUMES, ("Write freed space bitmap %d\n",
lb_num + ptov));
dscr = (union dscrptr *) ump->part_freed_dscr[phys_part];
/* force a sane minimum for descriptors CRC length */
/* see UDF 2.3.1.2 and 2.3.8.1 */
KASSERT(udf_rw16(dscr->sbd.tag.id) == TAGID_SPACE_BITMAP);
if (udf_rw16(dscr->sbd.tag.desc_crc_len) == 0)
dscr->sbd.tag.desc_crc_len = udf_rw16(8);
/* write out space bitmap */
error = udf_write_phys_dscr_sync(ump, NULL, UDF_C_DSCR,
(union dscrptr *) dscr,
ptov + lb_num, lb_num);
@ -1738,7 +1771,7 @@ udf_read_metadata_partition_spacetable(struct udf_mount *ump)
"%"PRIu64" bytes\n", inflen));
/* allocate space for bitmap */
dscr = malloc(inflen, M_UDFVOLD, M_CANFAIL | M_WAITOK);
dscr = malloc(inflen, M_UDFVOLD, M_WAITOK);
if (!dscr)
return ENOMEM;
@ -1981,7 +2014,7 @@ udf_process_vds(struct udf_mount *ump) {
DPRINTF(VOLUMES, ("\t%d -> %d(%d) type %d\n", log_part,
raw_phys_part, phys_part, pmap_type));
if (phys_part == UDF_PARTITIONS)
return EINVAL;
if (pmap_type == UDF_VTOP_TYPE_UNKNOWN)
@ -2097,7 +2130,7 @@ udf_process_vds(struct udf_mount *ump) {
snprintb(bits, sizeof(bits), UDFONERROR_BITS, ump->lvreadwrite);
DPRINTF(VOLUMES, ("\tactions on logvol errors %s\n", bits));
DPRINTF(VOLUMES, ("\tselected sheduler `%s`\n",
DPRINTF(VOLUMES, ("\tselected sheduler `%s`\n",
(ump->strategy == &udf_strat_direct) ? "Direct" :
(ump->strategy == &udf_strat_sequential) ? "Sequential" :
(ump->strategy == &udf_strat_rmw) ? "RMW" : "UNKNOWN!"));
@ -2281,12 +2314,12 @@ udf_create_parentfid(struct udf_mount *ump, struct fileid_desc *fid,
* (a) inside the file's (e)fe in the length of the extended attribute area
* before the allocation descriptors/filedata
*
* (b) in a file referenced by (e)fe->ext_attr_icb and
* (b) in a file referenced by (e)fe->ext_attr_icb and
*
* (c) in the e(fe)'s associated stream directory that can hold various
* sub-files. In the stream directory a few fixed named subfiles are reserved
* for NT/Unix ACL's and OS/2 attributes.
*
*
* NOTE: Extended attributes are read randomly but allways written
* *atomicaly*. For ACL's this interface is propably different but not known
* to me yet.
@ -2554,7 +2587,7 @@ udf_extattr_insert_internal(struct udf_mount *ump, union dscrptr *dscr,
/* --------------------------------------------------------------------- */
static int
static int
udf_update_lvid_from_vat_extattr(struct udf_node *vat_node)
{
struct udf_mount *ump;
@ -2590,7 +2623,7 @@ udf_update_lvid_from_vat_extattr(struct udf_node *vat_node)
return error;
/* paranoia */
if (a_l != sizeof(*implext) -1 + udf_rw32(implext->iu_l) + sizeof(lvext)) {
if (a_l != sizeof(*implext) -2 + udf_rw32(implext->iu_l) + sizeof(lvext)) {
DPRINTF(VOLUMES, ("VAT LVExtension size doesn't compute\n"));
return EINVAL;
}
@ -2621,7 +2654,7 @@ udf_update_lvid_from_vat_extattr(struct udf_node *vat_node)
}
static int
static int
udf_update_vat_extattr_from_lvid(struct udf_node *vat_node)
{
struct udf_mount *ump;
@ -2706,7 +2739,7 @@ udf_vat_write(struct udf_node *vat_node, uint8_t *blob, int size, uint32_t offse
/* realloc */
new_vat_table = realloc(ump->vat_table,
ump->vat_table_alloc_len + UDF_VAT_CHUNKSIZE,
M_UDFVOLD, M_WAITOK | M_CANFAIL);
M_UDFVOLD, M_WAITOK);
if (!new_vat_table) {
printf("udf_vat_write: can't extent VAT, out of mem\n");
return ENOMEM;
@ -2833,7 +2866,6 @@ udf_writeout_vat(struct udf_mount *ump)
if (error)
printf("udf_writeout_vat: error writing VAT node!\n");
out:
return error;
}
@ -2904,8 +2936,7 @@ udf_check_for_vat(struct udf_node *vat_node)
((vat_length + UDF_VAT_CHUNKSIZE-1) / UDF_VAT_CHUNKSIZE)
* UDF_VAT_CHUNKSIZE;
vat_table = malloc(vat_table_alloc_len, M_UDFVOLD,
M_CANFAIL | M_WAITOK);
vat_table = malloc(vat_table_alloc_len, M_UDFVOLD, M_WAITOK);
if (vat_table == NULL) {
printf("allocation of %d bytes failed for VAT\n",
vat_table_alloc_len);
@ -2974,7 +3005,7 @@ udf_check_for_vat(struct udf_node *vat_node)
lvinfo->min_udf_readver = vat->min_udf_readver;
lvinfo->min_udf_writever = vat->min_udf_writever;
lvinfo->max_udf_writever = vat->max_udf_writever;
udf_update_logvolname(ump, vat->logvol_id);
}
@ -2995,6 +3026,10 @@ udf_check_for_vat(struct udf_node *vat_node)
ump->logvol_integrity->integrity_type = udf_rw32(UDF_INTEGRITY_CLOSED);
ump->logvol_integrity->time = *mtime;
/* if we're updating, free old allocated space */
if (ump->vat_table)
free(ump->vat_table, M_UDFVOLD);
ump->vat_table_len = vat_length;
ump->vat_table_alloc_len = vat_table_alloc_len;
ump->vat_table = vat_table;
@ -3017,49 +3052,71 @@ out:
static int
udf_search_vat(struct udf_mount *ump, union udf_pmap *mapping)
{
struct udf_node *vat_node;
struct udf_node *vat_node, *accepted_vat_node;
struct long_ad icb_loc;
uint32_t early_vat_loc, vat_loc;
uint32_t early_vat_loc, late_vat_loc, vat_loc;
int error;
/* mapping info not needed */
mapping = mapping;
vat_loc = ump->last_possible_vat_location;
early_vat_loc = vat_loc - 256; /* 8 blocks of 32 sectors */
DPRINTF(VOLUMES, ("Searching VAT\n"));
DPRINTF(VOLUMES, ("1) last possible %d, early_vat_loc %d \n",
vat_loc, early_vat_loc));
early_vat_loc = MAX(early_vat_loc, ump->first_possible_vat_location);
/*
* Start reading forward in blocks from the first possible vat
* location. If not found in this block, start again a bit before
* until we get a hit.
*/
late_vat_loc = ump->last_possible_vat_location;
early_vat_loc = MAX(late_vat_loc - 64, ump->first_possible_vat_location);
DPRINTF(VOLUMES, ("2) last possible %d, early_vat_loc %d \n",
vat_loc, early_vat_loc));
/* start looking from the end of the range */
DPRINTF(VOLUMES, ("\tfull range %d to %d\n", early_vat_loc, late_vat_loc));
accepted_vat_node = NULL;
do {
DPRINTF(VOLUMES, ("Checking for VAT at sector %d\n", vat_loc));
icb_loc.loc.part_num = udf_rw16(UDF_VTOP_RAWPART);
icb_loc.loc.lb_num = udf_rw32(vat_loc);
vat_loc = early_vat_loc;
DPRINTF(VOLUMES, ("\tchecking range %d to %d\n",
early_vat_loc, late_vat_loc));
do {
DPRINTF(VOLUMES, ("\t\tChecking for VAT at sector %d\n",
vat_loc));
icb_loc.loc.part_num = udf_rw16(UDF_VTOP_RAWPART);
icb_loc.loc.lb_num = udf_rw32(vat_loc);
error = udf_get_node(ump, &icb_loc, &vat_node);
if (!error) {
error = udf_check_for_vat(vat_node);
DPRINTFIF(VOLUMES, !error,
("VAT accepted at %d\n", vat_loc));
if (!error)
break;
}
if (vat_node) {
vput(vat_node->vnode);
vat_node = NULL;
}
vat_loc--; /* walk backwards */
} while (vat_loc >= early_vat_loc);
error = udf_get_node(ump, &icb_loc, &vat_node,
LK_EXCLUSIVE);
if (!error) {
error = udf_check_for_vat(vat_node);
vat_node->i_flags = 0; /* reset access */
}
if (!error) {
DPRINTFIF(VOLUMES, !error,
("VAT candidate accepted at %d\n",
vat_loc));
if (accepted_vat_node)
vput(accepted_vat_node->vnode);
accepted_vat_node = vat_node;
accepted_vat_node->i_flags |= IN_NO_DELETE;
vat_node = NULL;
}
if (vat_node)
vput(vat_node->vnode);
vat_loc++; /* walk forward */
} while (vat_loc < late_vat_loc);
if (accepted_vat_node)
break;
/* keep our VAT node around */
if (vat_node) {
UDF_SET_SYSTEMFILE(vat_node->vnode);
ump->vat_node = vat_node;
early_vat_loc = MAX(early_vat_loc - 64, ump->first_possible_vat_location);
late_vat_loc = MIN(early_vat_loc + 64, ump->last_possible_vat_location);
} while (late_vat_loc > ump->first_possible_vat_location);
/* keep our last accepted VAT node around */
if (accepted_vat_node) {
/* revert no delete flag again to avoid potential side effects */
accepted_vat_node->i_flags &= ~IN_NO_DELETE;
UDF_SET_SYSTEMFILE(accepted_vat_node->vnode);
ump->vat_node = accepted_vat_node;
return 0;
}
return error;
@ -3141,7 +3198,8 @@ udf_read_metadata_nodes(struct udf_mount *ump, union udf_pmap *mapping)
DPRINTF(VOLUMES, ("Metadata file\n"));
icb_loc.loc.lb_num = pmm->meta_file_lbn;
error = udf_get_node(ump, &icb_loc, &ump->metadata_node);
error = udf_get_node(ump, &icb_loc, &ump->metadata_node,
LK_EXCLUSIVE);
if (ump->metadata_node) {
vp = ump->metadata_node->vnode;
UDF_SET_SYSTEMFILE(vp);
@ -3150,7 +3208,8 @@ udf_read_metadata_nodes(struct udf_mount *ump, union udf_pmap *mapping)
icb_loc.loc.lb_num = pmm->meta_mirror_file_lbn;
if (icb_loc.loc.lb_num != -1) {
DPRINTF(VOLUMES, ("Metadata copy file\n"));
error = udf_get_node(ump, &icb_loc, &ump->metadatamirror_node);
error = udf_get_node(ump, &icb_loc, &ump->metadatamirror_node,
LK_EXCLUSIVE);
if (ump->metadatamirror_node) {
vp = ump->metadatamirror_node->vnode;
UDF_SET_SYSTEMFILE(vp);
@ -3160,7 +3219,8 @@ udf_read_metadata_nodes(struct udf_mount *ump, union udf_pmap *mapping)
icb_loc.loc.lb_num = pmm->meta_bitmap_file_lbn;
if (icb_loc.loc.lb_num != -1) {
DPRINTF(VOLUMES, ("Metadata bitmap file\n"));
error = udf_get_node(ump, &icb_loc, &ump->metadatabitmap_node);
error = udf_get_node(ump, &icb_loc, &ump->metadatabitmap_node,
LK_EXCLUSIVE);
if (ump->metadatabitmap_node) {
vp = ump->metadatabitmap_node->vnode;
UDF_SET_SYSTEMFILE(vp);
@ -3341,7 +3401,7 @@ udf_read_rootdirs(struct udf_mount *ump)
/* try to read in the rootdir */
dir_loc = &ump->fileset_desc->rootdir_icb;
error = udf_get_node(ump, dir_loc, &rootdir_node);
error = udf_get_node(ump, dir_loc, &rootdir_node, LK_EXCLUSIVE);
if (error)
return ENOENT;
@ -3354,7 +3414,8 @@ udf_read_rootdirs(struct udf_mount *ump)
dir_loc = &ump->fileset_desc->streamdir_icb;
if (udf_rw32(dir_loc->len)) {
printf("udf_read_rootdirs: streamdir defined ");
error = udf_get_node(ump, dir_loc, &streamdir_node);
error = udf_get_node(ump, dir_loc, &streamdir_node,
LK_EXCLUSIVE);
if (error) {
printf("but error in streamdir reading\n");
} else {
@ -3674,6 +3735,21 @@ udf_open_logvol(struct udf_mount *ump)
/* determine data and metadata tracks again */
error = udf_search_writing_tracks(ump);
if (ump->lvclose & UDF_WRITE_VAT) {
/*
* we writeout the VAT to get a self-sustained session
* for fsck
*/
DPRINTF(VOLUMES, ("lvclose & UDF_WRITE_VAT\n"));
/* write out the VAT data and all its descriptors */
DPRINTF(VOLUMES, ("writeout vat_node\n"));
udf_writeout_vat(ump);
/* force everything to be synchronized on the device */
(void) udf_synchronise_caches(ump);
}
}
/* mark it open */
@ -3722,15 +3798,6 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
/* write out the VAT data and all its descriptors */
DPRINTF(VOLUMES, ("writeout vat_node\n"));
udf_writeout_vat(ump);
(void) vflushbuf(ump->vat_node->vnode, FSYNC_WAIT);
(void) VOP_FSYNC(ump->vat_node->vnode,
FSCRED, FSYNC_WAIT, 0, 0);
if (ump->lvclose & UDF_CLOSE_SESSION) {
DPRINTF(VOLUMES, ("udf_close_logvol: closing session "
"as requested\n"));
}
/* at least two DVD packets and 3 CD-R packets */
nvats = 32;
@ -3765,6 +3832,9 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
if (!error)
nok++;
}
/* force everything to be synchronized on the device */
(void) udf_synchronise_caches(ump);
if (nok < 14) {
/* arbitrary; but at least one or two CD frames */
printf("writeout of at least 14 VATs failed\n");
@ -3776,6 +3846,8 @@ udf_close_logvol(struct udf_mount *ump, int mntflags)
/* finish closing of session */
if (ump->lvclose & UDF_CLOSE_SESSION) {
DPRINTF(VOLUMES, ("udf_close_logvol: closing session "
"as requested\n"));
error = udf_validate_session_start(ump);
if (error)
return error;
@ -3995,6 +4067,7 @@ static const struct genfs_ops udf_genfsops = {
.gop_alloc = udf_gop_alloc,
.gop_write = genfs_gop_write_rwmap,
.gop_markupdate = udf_gop_markupdate,
.gop_putrange = genfs_gop_putrange,
};
@ -4046,7 +4119,7 @@ static uint32_t
unix_mode_to_udf_perm(mode_t mode)
{
uint32_t perm;
perm = ((mode & S_IRWXO) );
perm |= ((mode & S_IRWXG) << 2);
perm |= ((mode & S_IRWXU) << 4);
@ -4350,7 +4423,7 @@ udf_getownership(struct udf_node *udf_node, uid_t *uidp, gid_t *gidp)
uid = (uid_t)udf_rw32(efe->uid);
gid = (gid_t)udf_rw32(efe->gid);
}
/* do the uid/gid translation game */
if (uid == (uid_t) -1)
uid = ump->mount_args.anon_uid;
@ -4478,7 +4551,7 @@ udf_dirhash_fill(struct udf_node *dir_node)
*
*/
int
int
udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
struct long_ad *icb_loc, int *found)
{
@ -4486,7 +4559,8 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
struct dirhash *dirh;
struct dirhash_entry *dirh_ep;
struct fileid_desc *fid;
struct dirent *dirent;
struct dirent *dirent, *s_dirent;
struct charspec osta_charspec;
uint64_t diroffset;
uint32_t lb_size;
int hit, error;
@ -4504,18 +4578,28 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
dirh = dir_node->dir_hash;
/* allocate temporary space for fid */
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size);
fid = malloc(lb_size, M_UDFTEMP, M_WAITOK);
dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size);
fid = malloc(lb_size, M_UDFTEMP, M_WAITOK);
dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
s_dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
DPRINTF(DIRHASH, ("dirhash_lookup looking for `%*.*s`\n",
namelen, namelen, name));
/* convert given unix name to canonical unix name */
udf_osta_charset(&osta_charspec);
unix_to_udf_name((char *) fid->data, &fid->l_fi,
name, namelen, &osta_charspec);
udf_to_unix_name(s_dirent->d_name, NAME_MAX,
(char *) fid->data, fid->l_fi,
&osta_charspec);
s_dirent->d_namlen = strlen(s_dirent->d_name);
/* search our dirhash hits */
memset(icb_loc, 0, sizeof(*icb_loc));
dirh_ep = NULL;
for (;;) {
hit = dirhash_lookup(dirh, name, namelen, &dirh_ep);
hit = dirhash_lookup(dirh, s_dirent->d_name, s_dirent->d_namlen, &dirh_ep);
/* if no hit, abort the search */
if (!hit)
break;
@ -4532,16 +4616,7 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
dirent->d_namlen, dirent->d_namlen, dirent->d_name));
/* see if its our entry */
#ifdef DIAGNOSTIC
if (dirent->d_namlen != namelen) {
printf("WARNING: dirhash_lookup() returned wrong "
"d_namelen: %d and ought to be %d\n",
dirent->d_namlen, namelen);
printf("\tlooked for `%s' and got `%s'\n",
name, dirent->d_name);
}
#endif
if (strncmp(dirent->d_name, name, namelen) == 0) {
if (strncmp(dirent->d_name, s_dirent->d_name, s_dirent->d_namlen) == 0) {
*found = 1;
*icb_loc = fid->icb;
break;
@ -4549,6 +4624,7 @@ udf_lookup_name_in_dir(struct vnode *vp, const char *name, int namelen,
}
free(fid, M_UDFTEMP);
free(dirent, M_UDFTEMP);
free(s_dirent, M_UDFTEMP);
dirhash_put(dir_node->dir_hash);
@ -4718,12 +4794,11 @@ udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node,
struct dirhash_entry *dirh_ep;
struct file_entry *fe = dir_node->fe;
struct fileid_desc *fid;
struct dirent *dirent;
struct dirent *dirent, *s_dirent;
struct charspec osta_charspec;
uint64_t diroffset;
uint32_t lb_size, fidsize;
int found, error;
char const *name = cnp->cn_nameptr;
int namelen = cnp->cn_namelen;
int hit, refcnt;
/* get our dirhash and make sure its read in */
@ -4740,16 +4815,26 @@ udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node,
assert(dir_node->efe);
}
/* allocate temporary space for fid */
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size);
fid = malloc(lb_size, M_UDFTEMP, M_WAITOK);
dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
/* allocate temporary space for fid and dirents */
lb_size = udf_rw32(dir_node->ump->logical_vol->lb_size);
fid = malloc(lb_size, M_UDFTEMP, M_WAITOK);
dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
s_dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK);
/* convert given unix name to canonical unix name */
udf_osta_charset(&osta_charspec);
unix_to_udf_name((char *) fid->data, &fid->l_fi,
cnp->cn_nameptr, cnp->cn_namelen, &osta_charspec);
udf_to_unix_name(s_dirent->d_name, NAME_MAX,
(char *) fid->data, fid->l_fi,
&osta_charspec);
s_dirent->d_namlen = strlen(s_dirent->d_name);
/* search our dirhash hits */
found = 0;
dirh_ep = NULL;
for (;;) {
hit = dirhash_lookup(dirh, name, namelen, &dirh_ep);
hit = dirhash_lookup(dirh, s_dirent->d_name, s_dirent->d_namlen, &dirh_ep);
/* if no hit, abort the search */
if (!hit)
break;
@ -4763,8 +4848,8 @@ udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node,
break;
/* see if its our entry */
KASSERT(dirent->d_namlen == namelen);
if (strncmp(dirent->d_name, name, namelen) == 0) {
KASSERT(dirent->d_namlen == s_dirent->d_namlen);
if (strncmp(dirent->d_name, s_dirent->d_name, s_dirent->d_namlen) == 0) {
found = 1;
break;
}
@ -4788,7 +4873,7 @@ udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node,
/* write out */
error = vn_rdwr(UIO_WRITE, dir_node->vnode,
fid, fidsize, diroffset,
fid, fidsize, diroffset,
UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED,
FSCRED, NULL, NULL);
if (error)
@ -4845,6 +4930,7 @@ udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node,
error_out:
free(fid, M_UDFTEMP);
free(dirent, M_UDFTEMP);
free(s_dirent, M_UDFTEMP);
dirhash_put(dir_node->dir_hash);
@ -4950,7 +5036,7 @@ udf_dir_update_rootentry(struct udf_mount *ump, struct udf_node *dir_node,
/* write out */
error = vn_rdwr(UIO_WRITE, dir_node->vnode,
fid, fidsize, diroffset,
fid, fidsize, diroffset,
UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED,
FSCRED, NULL, NULL);
@ -5154,7 +5240,7 @@ udf_dir_attach(struct udf_mount *ump, struct udf_node *dir_node,
/* writeout FID/update parent directory */
error = vn_rdwr(UIO_WRITE, dvp,
fid, chosen_size, chosen_fid_pos,
fid, chosen_size, chosen_fid_pos,
UIO_SYSSPACE, IO_ALTSEMANTICS | IO_NODELOCKED,
FSCRED, NULL, NULL);
@ -5336,7 +5422,7 @@ udf_loadvnode(struct mount *mp, struct vnode *vp,
/* choose this one */
last_fe_icb_loc = icb_loc;
/* record and process/update (ext)fentry */
if (dscr_type == TAGID_FENTRY) {
if (udf_node->fe)
@ -5544,16 +5630,18 @@ udf_loadvnode(struct mount *mp, struct vnode *vp,
int
udf_get_node(struct udf_mount *ump, struct long_ad *node_icb_loc,
struct udf_node **udf_noderes)
struct udf_node **udf_noderes, int lktype)
{
int error;
struct vnode *vp;
*udf_noderes = NULL;
error = vcache_get(ump->vfs_mountp, &node_icb_loc->loc,
sizeof(node_icb_loc->loc), &vp);
if (error)
return error;
error = vn_lock(vp, LK_EXCLUSIVE);
error = vn_lock(vp, lktype);
if (error) {
vrele(vp);
return error;
@ -5696,7 +5784,7 @@ udf_dispose_node(struct udf_node *udf_node)
int
udf_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp,
struct vattr *vap, kauth_cred_t cred,
struct vattr *vap, kauth_cred_t cred, void *extra,
size_t *key_len, const void **new_key)
{
union dscrptr *dscr;
@ -5840,7 +5928,7 @@ udf_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp,
gid = parent_gid;
udf_setownership(udf_node, uid, gid);
*key_len = sizeof(udf_node->loc.loc);;
*key_len = sizeof(udf_node->loc.loc);
*new_key = &udf_node->loc.loc;
return 0;
@ -5855,7 +5943,7 @@ udf_create_node(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
struct udf_mount *ump = dir_node->ump;
int error;
error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, vpp);
error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, NULL, vpp);
if (error)
return error;
@ -5880,6 +5968,7 @@ udf_create_node(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
/* adjust file count */
udf_adjust_filecount(udf_node, 1);
cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags);
return 0;
}
@ -5914,6 +6003,9 @@ udf_delete_node(struct udf_node *udf_node)
struct long_ad *loc;
int extnr, lvint, dummy;
if (udf_node->i_flags & IN_NO_DELETE)
return;
/* paranoia check on integrity; should be open!; we could panic */
lvint = udf_rw32(udf_node->ump->logvol_integrity->integrity_type);
if (lvint == UDF_INTEGRITY_CLOSED)
@ -6342,7 +6434,11 @@ udf_sync_pass(struct udf_mount *ump, kauth_cred_t cred, int pass, int *ndirty)
static bool
udf_sync_selector(void *cl, struct vnode *vp)
{
struct udf_node *udf_node = VTOI(vp);
struct udf_node *udf_node;
KASSERT(mutex_owned(vp->v_interlock));
udf_node = VTOI(vp);
if (vp->v_vflag & VV_SYSTEM)
return false;
@ -6352,7 +6448,7 @@ udf_sync_selector(void *cl, struct vnode *vp)
return false;
if ((udf_node->i_flags & (IN_ACCESSED | IN_UPDATE | IN_MODIFIED)) == 0)
return false;
if (LIST_EMPTY(&vp->v_dirtyblkhd) && UVM_OBJ_IS_CLEAN(&vp->v_uobj))
if (LIST_EMPTY(&vp->v_dirtyblkhd) && (vp->v_iflag & VI_ONWORKLST) == 0)
return false;
return true;
@ -6398,7 +6494,7 @@ recount:
udf_sync_pass(ump, cred, 3, &ndirty);
DPRINTF(SYNC, ("counted num dirty pending blocks %d\n",
ndirty));
if (ndirty) {
/* 1/4 second wait */
kpause("udfsync2", false, hz/4, NULL);
@ -6424,7 +6520,7 @@ recount:
/*
* Read and write file extent in/from the buffer.
*
* The splitup of the extent into seperate request-buffers is to minimise
* The splitup of the extent into separate request-buffers is to minimise
* copying around as much as possible.
*
* block based file reading and writing
@ -6438,21 +6534,26 @@ udf_read_internal(struct udf_node *node, uint8_t *blob)
struct extfile_entry *efe = node->efe;
uint64_t inflen;
uint32_t sector_size;
uint8_t *pos;
uint8_t *srcpos;
int icbflags, addr_type;
/* get extent and do some paranoia checks */
ump = node->ump;
sector_size = ump->discinfo.sector_size;
/*
* XXX there should be real bounds-checking logic here,
* in case ->l_ea or ->inf_len contains nonsense.
*/
if (fe) {
inflen = udf_rw64(fe->inf_len);
pos = &fe->data[0] + udf_rw32(fe->l_ea);
srcpos = &fe->data[0] + udf_rw32(fe->l_ea);
icbflags = udf_rw16(fe->icbtag.flags);
} else {
assert(node->efe);
inflen = udf_rw64(efe->inf_len);
pos = &efe->data[0] + udf_rw32(efe->l_ea);
srcpos = &efe->data[0] + udf_rw32(efe->l_ea);
icbflags = udf_rw16(efe->icbtag.flags);
}
addr_type = icbflags & UDF_ICB_TAG_FLAGS_ALLOC_MASK;
@ -6462,8 +6563,8 @@ udf_read_internal(struct udf_node *node, uint8_t *blob)
assert(inflen < sector_size);
/* copy out info */
memset(blob, 0, sector_size);
memcpy(blob, pos, inflen);
memcpy(blob, srcpos, inflen);
memset(&blob[inflen], 0, sector_size - inflen);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_subr.h,v 1.19 2013/07/07 19:49:44 reinoud Exp $ */
/* $NetBSD: udf_subr.h,v 1.21 2020/01/17 20:08:08 ad Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -40,7 +40,8 @@ int udf_search_tracks(struct udf_mount *ump, struct udf_args *args,
int *first_tracknr, int *last_tracknr);
int udf_search_writing_tracks(struct udf_mount *ump);
int udf_setup_writeparams(struct udf_mount *ump);
int udf_synchronise_caches(struct udf_mount *ump);
void udf_mmc_synchronise_caches(struct udf_mount *ump);
void udf_synchronise_caches(struct udf_mount *ump);
/* tags operations */
int udf_fidsize(struct fileid_desc *fid);
@ -131,7 +132,7 @@ uint64_t udf_advance_uniqueid(struct udf_mount *ump);
void udf_lock_node(struct udf_node *udf_node, int flag, char const *fname, const int lineno);
void udf_unlock_node(struct udf_node *udf_node, int flag);
int udf_get_node(struct udf_mount *ump, struct long_ad *icbloc, struct udf_node **noderes);
int udf_get_node(struct udf_mount *ump, struct long_ad *icbloc, struct udf_node **noderes, int);
int udf_writeout_node(struct udf_node *udf_node, int waitfor);
int udf_dispose_node(struct udf_node *node);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_vfsops.c,v 1.71 2015/08/24 08:31:56 hannken Exp $ */
/* $NetBSD: udf_vfsops.c,v 1.80 2020/04/14 12:47:44 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.71 2015/08/24 08:31:56 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.80 2020/04/14 12:47:44 reinoud Exp $");
#endif /* not lint */
@ -79,8 +79,6 @@ MALLOC_JUSTDEFINE(M_UDFVOLD, "UDF volspace", "UDF volume space descriptors");
MALLOC_JUSTDEFINE(M_UDFTEMP, "UDF temp", "UDF scrap space");
struct pool udf_node_pool;
static struct sysctllog *udf_sysctl_log;
/* internal functions */
static int udf_mountfs(struct vnode *, struct mount *, struct lwp *, struct udf_args *);
@ -118,7 +116,7 @@ struct vfsops udf_vfsops = {
.vfs_mountroot = udf_mountroot,
.vfs_snapshot = udf_snapshot,
.vfs_extattrctl = vfs_stdextattrctl,
.vfs_suspendctl = (void *)eopnotsupp,
.vfs_suspendctl = genfs_suspendctl,
.vfs_renamelock_enter = genfs_renamelock_enter,
.vfs_renamelock_exit = genfs_renamelock_exit,
.vfs_fsync = (void *)eopnotsupp,
@ -169,10 +167,34 @@ udf_done(void)
*/
#define UDF_VERBOSE_SYSCTLOPT 1
/*
* XXX the "24" below could be dynamic, thereby eliminating one
* more instance of the "number to vfs" mapping problem, but
* "24" is the order as taken from sys/mount.h
*/
SYSCTL_SETUP(udf_sysctl_setup, "udf sysctl")
{
const struct sysctlnode *node;
sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "udf",
SYSCTL_DESCR("OSTA Universal File System"),
NULL, 0, NULL, 0,
CTL_VFS, 24, CTL_EOL);
#ifdef DEBUG
sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "verbose",
SYSCTL_DESCR("Bitmask for filesystem debugging"),
NULL, 0, &udf_verbose, 0,
CTL_VFS, 24, UDF_VERBOSE_SYSCTLOPT, CTL_EOL);
#endif
}
static int
udf_modcmd(modcmd_t cmd, void *arg)
{
const struct sysctlnode *node;
int error;
switch (cmd) {
@ -180,31 +202,11 @@ udf_modcmd(modcmd_t cmd, void *arg)
error = vfs_attach(&udf_vfsops);
if (error != 0)
break;
/*
* XXX the "24" below could be dynamic, thereby eliminating one
* more instance of the "number to vfs" mapping problem, but
* "24" is the order as taken from sys/mount.h
*/
sysctl_createv(&udf_sysctl_log, 0, NULL, &node,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "udf",
SYSCTL_DESCR("OSTA Universal File System"),
NULL, 0, NULL, 0,
CTL_VFS, 24, CTL_EOL);
#ifdef DEBUG
sysctl_createv(&udf_sysctl_log, 0, NULL, &node,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "verbose",
SYSCTL_DESCR("Bitmask for filesystem debugging"),
NULL, 0, &udf_verbose, 0,
CTL_VFS, 24, UDF_VERBOSE_SYSCTLOPT, CTL_EOL);
#endif
break;
case MODULE_CMD_FINI:
error = vfs_detach(&udf_vfsops);
if (error != 0)
break;
sysctl_teardown(&udf_sysctl_log);
break;
default:
error = ENOTTY;
@ -277,7 +279,6 @@ static void
udf_release_system_nodes(struct mount *mp)
{
struct udf_mount *ump = VFSTOUDF(mp);
int error;
/* if we haven't even got an ump, dont bother */
if (!ump)
@ -294,10 +295,6 @@ udf_release_system_nodes(struct mount *mp)
vrele(ump->metadatamirror_node->vnode);
if (ump->metadatabitmap_node)
vrele(ump->metadatabitmap_node->vnode);
/* This flush should NOT write anything nor allow any node to remain */
if ((error = vflush(ump->vfs_mountp, NULLVP, 0)) != 0)
panic("Failure to flush UDF system vnodes\n");
}
@ -361,7 +358,7 @@ udf_mount(struct mount *mp, const char *path,
}
if (bdevsw_lookup(devvp->v_rdev) == NULL) {
vrele(devvp);
return ENXIO;
return ENXIO;
}
/*
@ -442,12 +439,14 @@ static bool
udf_sanity_selector(void *cl, struct vnode *vp)
{
KASSERT(mutex_owned(vp->v_interlock));
vprint("", vp);
if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) {
printf(" is locked\n");
}
if (vp->v_usecount > 1)
printf(" more than one usecount %d\n", vp->v_usecount);
if (vrefcnt(vp) > 1)
printf(" more than one usecount %d\n", vrefcnt(vp));
return false;
}
@ -518,6 +517,10 @@ udf_unmount(struct mount *mp, int mntflags)
/* NOTE release system nodes should NOT write anything */
udf_release_system_nodes(mp);
/* This flush should NOT write anything nor allow any node to remain */
if ((error = vflush(ump->vfs_mountp, NULLVP, 0)) != 0)
panic("Failure to flush UDF system vnodes\n");
/* finalise disc strategy */
udf_discstrat_finish(ump);
@ -743,7 +746,7 @@ udf_start(struct mount *mp, int flags)
/* --------------------------------------------------------------------- */
int
udf_root(struct mount *mp, struct vnode **vpp)
udf_root(struct mount *mp, int lktype, struct vnode **vpp)
{
struct vnode *vp;
struct long_ad *dir_loc;
@ -754,12 +757,13 @@ udf_root(struct mount *mp, struct vnode **vpp)
DPRINTF(CALL, ("udf_root called\n"));
dir_loc = &ump->fileset_desc->rootdir_icb;
error = udf_get_node(ump, dir_loc, &root_dir);
error = udf_get_node(ump, dir_loc, &root_dir, lktype);
if (error)
return error;
if (!root_dir)
error = ENOENT;
if (error)
return error;
vp = root_dir->vnode;
KASSERT(vp->v_vflag & VV_ROOT);
@ -893,7 +897,7 @@ udf_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
* (optional) TODO lookup why some sources state NFSv3
*/
int
udf_vget(struct mount *mp, ino_t ino,
udf_vget(struct mount *mp, ino_t ino, int lktype,
struct vnode **vpp)
{
DPRINTF(NOTIMPL, ("udf_vget called\n"));
@ -906,7 +910,7 @@ udf_vget(struct mount *mp, ino_t ino,
* Lookup vnode for file handle specified
*/
int
udf_fhtovp(struct mount *mp, struct fid *fhp,
udf_fhtovp(struct mount *mp, struct fid *fhp, int lktype,
struct vnode **vpp)
{
DPRINTF(NOTIMPL, ("udf_fhtovp called\n"));

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf_vnops.c,v 1.101 2015/04/20 23:03:08 riastradh Exp $ */
/* $NetBSD: udf_vnops.c,v 1.114 2020/06/27 17:29:18 christos Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.101 2015/04/20 23:03:08 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.114 2020/06/27 17:29:18 christos Exp $");
#endif /* not lint */
@ -71,16 +71,13 @@ __KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.101 2015/04/20 23:03:08 riastradh Ex
static int udf_do_readlink(struct udf_node *udf_node, uint64_t filesize,
uint8_t *targetbuf, int *length);
/* externs */
extern int prtactive;
/* implementations of vnode functions; table follows at end */
/* --------------------------------------------------------------------- */
int
udf_inactive(void *v)
{
struct vop_inactive_args /* {
struct vop_inactive_v2_args /* {
struct vnode *a_vp;
bool *a_recycle;
} */ *ap = v;
@ -92,7 +89,6 @@ udf_inactive(void *v)
if (udf_node == NULL) {
DPRINTF(NODE, ("udf_inactive: inactive NULL UDF node\n"));
VOP_UNLOCK(vp);
return 0;
}
@ -115,14 +111,12 @@ udf_inactive(void *v)
*ap->a_recycle = false;
if ((refcnt == 0) && ((vp->v_vflag & VV_SYSTEM) == 0)) {
*ap->a_recycle = true;
VOP_UNLOCK(vp);
return 0;
}
/* write out its node */
if (udf_node->i_flags & (IN_CHANGE | IN_UPDATE | IN_MODIFIED))
udf_update(vp, NULL, NULL, NULL, 0);
VOP_UNLOCK(vp);
return 0;
}
@ -132,16 +126,16 @@ udf_inactive(void *v)
int
udf_reclaim(void *v)
{
struct vop_reclaim_args /* {
struct vop_reclaim_v2_args /* {
struct vnode *a_vp;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct udf_node *udf_node = VTOI(vp);
int refcnt;
VOP_UNLOCK(vp);
DPRINTF(NODE, ("udf_reclaim called for node %p\n", udf_node));
if (prtactive && vp->v_usecount > 1)
vprint("udf_reclaim(): pushing active", vp);
if (udf_node == NULL) {
DPRINTF(NODE, ("udf_reclaim(): null udfnode\n"));
@ -174,9 +168,6 @@ udf_reclaim(void *v)
tsleep(&udf_node->outstanding_nodedscr, PRIBIO, "recl wait", hz/8);
}
vcache_remove(vp->v_mount, &udf_node->loc.loc,
sizeof(udf_node->loc.loc));
/* dispose all node knowledge */
udf_dispose_node(udf_node);
@ -257,7 +248,7 @@ udf_read(void *v)
/* ubc, here we come, prepare to trap */
error = ubc_uiomove(uobj, uio, len, advice,
UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
UBC_READ | UBC_PARTIALOK | UBC_VNODE_FLAGS(vp));
if (error)
break;
}
@ -375,7 +366,7 @@ udf_write(void *v)
/* ubc, here we come, prepare to trap */
error = ubc_uiomove(uobj, uio, len, advice,
UBC_WRITE | UBC_UNMAP_FLAG(vp));
UBC_WRITE | UBC_VNODE_FLAGS(vp));
if (error)
break;
@ -388,7 +379,7 @@ udf_write(void *v)
*/
if ((vp->v_type != VDIR) &&
(old_offset >> 16 != uio->uio_offset >> 16)) {
mutex_enter(vp->v_interlock);
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
error = VOP_PUTPAGES(vp, (old_offset >> 16) << 16,
(uio->uio_offset >> 16) << 16,
PGO_CLEANIT | PGO_LAZY);
@ -618,7 +609,7 @@ udf_readdir(void *v)
if (uio->uio_resid < _DIRENT_SIZE(dirent))
break;
/* remember the last entry we transfered */
/* remember the last entry we transferred */
transoffset = diroffset;
/* skip deleted entries */
@ -759,7 +750,8 @@ udf_lookup(void *v)
if (error == 0) {
DPRINTF(LOOKUP, ("\tfound '..'\n"));
/* try to create/reuse the node */
error = udf_get_node(ump, &icb_loc, &res_node);
error = udf_get_node(ump, &icb_loc, &res_node,
LK_EXCLUSIVE);
if (!error) {
DPRINTF(LOOKUP,
@ -811,7 +803,7 @@ udf_lookup(void *v)
*/
/* try to create/reuse the node */
error = udf_get_node(ump, &icb_loc, &res_node);
error = udf_get_node(ump, &icb_loc, &res_node, LK_EXCLUSIVE);
if (error)
goto out;
@ -834,7 +826,7 @@ udf_lookup(void *v)
udf_getownership(dir_node, &d_uid, &d_gid);
error = kauth_authorize_vnode(cnp->cn_cred,
KAUTH_VNODE_DELETE, res_node->vnode,
dir_node->vnode, genfs_can_sticky(cnp->cn_cred,
dir_node->vnode, genfs_can_sticky(dvp, cnp->cn_cred,
d_uid, d_uid));
if (error) {
error = EPERM;
@ -1049,7 +1041,7 @@ udf_chown(struct vnode *vp, uid_t new_uid, gid_t new_gid,
/* check permissions */
error = kauth_authorize_vnode(cred, KAUTH_VNODE_CHANGE_OWNERSHIP,
vp, NULL, genfs_can_chown(cred, uid, gid, new_uid, new_gid));
vp, NULL, genfs_can_chown(vp, cred, uid, gid, new_uid, new_gid));
if (error)
return (error);
@ -1086,7 +1078,7 @@ udf_chmod(struct vnode *vp, mode_t mode, kauth_cred_t cred)
/* check permissions */
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY, vp,
NULL, genfs_can_chmod(vp->v_type, cred, uid, gid, mode));
NULL, genfs_can_chmod(vp, cred, uid, gid, mode));
if (error)
return (error);
@ -1195,7 +1187,7 @@ udf_chtimes(struct vnode *vp,
/* check permissions */
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, vp,
NULL, genfs_can_chtimes(vp, setattrflags, uid, cred));
NULL, genfs_can_chtimes(vp, cred, uid, setattrflags));
if (error)
return (error);
@ -1334,9 +1326,9 @@ udf_pathconf(void *v)
#endif
*ap->a_retval = bits;
return 0;
default:
return genfs_pathconf(ap);
}
return EINVAL;
}
@ -1387,15 +1379,15 @@ udf_close(void *v)
udf_node = udf_node; /* shut up gcc */
if (!async && (vp->v_type != VDIR)) {
mutex_enter(vp->v_interlock);
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER);
error = VOP_PUTPAGES(vp, 0, 0, PGO_CLEANIT);
if (error)
return error;
}
mutex_enter(vp->v_interlock);
if (vp->v_usecount > 1)
udf_itimes(udf_node, NULL, NULL, NULL);
if (vrefcnt(vp) > 1)
udf_itimes(udf_node, NULL, NULL, NULL);
mutex_exit(vp->v_interlock);
return 0;
@ -1445,13 +1437,13 @@ udf_check_possible(struct vnode *vp, struct vattr *vap, mode_t mode)
}
static int
udf_check_permitted(struct vnode *vp, struct vattr *vap, mode_t mode,
udf_check_permitted(struct vnode *vp, struct vattr *vap, accmode_t accmode,
kauth_cred_t cred)
{
/* ask the generic genfs_can_access to advice on security */
return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(mode,
vp->v_type, vap->va_mode), vp, NULL, genfs_can_access(vp->v_type,
vap->va_mode, vap->va_uid, vap->va_gid, mode, cred));
return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(accmode,
vp->v_type, vap->va_mode), vp, NULL, genfs_can_access(vp, cred,
vap->va_uid, vap->va_gid, vap->va_mode, NULL, accmode));
}
int
@ -1459,12 +1451,12 @@ udf_access(void *v)
{
struct vop_access_args /* {
struct vnode *a_vp;
int a_mode;
accmode_t a_accmode;
kauth_cred_t a_cred;
struct proc *a_p;
} */ *ap = v;
struct vnode *vp = ap->a_vp;
mode_t mode = ap->a_mode;
accmode_t accmode = ap->a_accmode;
kauth_cred_t cred = ap->a_cred;
/* struct udf_node *udf_node = VTOI(vp); */
struct vattr vap;
@ -1476,11 +1468,11 @@ udf_access(void *v)
if (error)
return error;
error = udf_check_possible(vp, &vap, mode);
error = udf_check_possible(vp, &vap, accmode);
if (error)
return error;
error = udf_check_permitted(vp, &vap, mode, cred);
error = udf_check_permitted(vp, &vap, accmode, cred);
return error;
}
@ -1947,7 +1939,7 @@ udf_readlink(void *v)
int
udf_remove(void *v)
{
struct vop_remove_args /* {
struct vop_remove_v2_args /* {
struct vnode *a_dvp;
struct vnode *a_vp;
struct componentname *a_cnp;
@ -1978,7 +1970,6 @@ udf_remove(void *v)
vrele(vp);
else
vput(vp);
vput(dvp);
return error;
}
@ -1988,7 +1979,7 @@ udf_remove(void *v)
int
udf_rmdir(void *v)
{
struct vop_rmdir_args /* {
struct vop_rmdir_v2_args /* {
struct vnode *a_dvp;
struct vnode *a_vp;
struct componentname *a_cnp;
@ -2001,12 +1992,11 @@ udf_rmdir(void *v)
struct udf_mount *ump = dir_node->ump;
int error, isempty;
DPRINTF(NOTIMPL, ("udf_rmdir '%s' called\n", cnp->cn_nameptr));
DPRINTF(CALL, ("udf_rmdir '%s' called\n", cnp->cn_nameptr));
/* don't allow '.' to be deleted */
if (dir_node == udf_node) {
vrele(dvp);
vput(vp);
vrele(vp);
return EINVAL;
}
@ -2023,7 +2013,6 @@ udf_rmdir(void *v)
dirhash_put(udf_node->dir_hash);
if (!isempty) {
vput(dvp);
vput(vp);
return ENOTEMPTY;
}
@ -2046,8 +2035,7 @@ udf_rmdir(void *v)
}
DPRINTFIF(NODE, error, ("\tgot error removing dir\n"));
/* unput the nodes and exit */
vput(dvp);
/* put the node and exit */
vput(vp);
return error;
@ -2191,6 +2179,7 @@ const struct vnodeopv_entry_desc udf_vnodeop_entries[] = {
{ &vop_open_desc, udf_open }, /* open */
{ &vop_close_desc, udf_close }, /* close */
{ &vop_access_desc, udf_access }, /* access */
{ &vop_accessx_desc, genfs_accessx }, /* accessx */
{ &vop_getattr_desc, udf_getattr }, /* getattr */
{ &vop_setattr_desc, udf_setattr }, /* setattr */ /* TODO chflags */
{ &vop_read_desc, udf_read }, /* read */

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.36 2013/08/05 14:41:57 reinoud Exp $
# $NetBSD: Makefile,v 1.37 2019/10/13 07:28:19 mrg Exp $
#
WARNS?= 5
@ -31,6 +31,12 @@ CPPFLAGS+= -I${.CURDIR} -I${MKNODSRC} -I${MTREESRC} -DMAKEFS
.if !defined(HOSTPROG)
DPADD+= ${LIBUTIL}
LDADD+= -lutil
COPTS.cd9660.c+= ${GCC_NO_STRINGOP_TRUNCATION} ${GCC_NO_FORMAT_TRUNCATION}
COPTS.cd9660_conversion.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.udf.c+= ${GCC_NO_STRINGOP_TRUNCATION}
COPTS.v7fs_estimate.c+= ${GCC_NO_STRINGOP_TRUNCATION}
COPTS.v7fs_populate.c+= ${GCC_NO_STRINGOP_TRUNCATION} ${GCC_NO_FORMAT_TRUNCATION}
.endif
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660.c,v 1.49 2015/06/17 01:05:41 christos Exp $ */
/* $NetBSD: cd9660.c,v 1.57 2020/11/10 20:48:29 reinoud Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -103,7 +103,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660.c,v 1.49 2015/06/17 01:05:41 christos Exp $");
__RCSID("$NetBSD: cd9660.c,v 1.57 2020/11/10 20:48:29 reinoud Exp $");
#endif /* !__lint */
#include <string.h>
@ -124,7 +124,7 @@ __RCSID("$NetBSD: cd9660.c,v 1.49 2015/06/17 01:05:41 christos Exp $");
static void cd9660_finalize_PVD(iso9660_disk *);
static cd9660node *cd9660_allocate_cd9660node(void);
static void cd9660_set_defaults(iso9660_disk *);
static int cd9660_arguments_set_string(const char *, const char *, int,
static int cd9660_arguments_set_string(const char *, const char *, size_t,
char, char *);
static void cd9660_populate_iso_dir_record(
struct _iso_directory_record_cd9660 *, u_char, u_char, u_char,
@ -178,7 +178,7 @@ static int cd9660_add_generic_bootimage(iso9660_disk *, const char *);
/*
* Allocate and initalize a cd9660node
* Allocate and initialize a cd9660node
* @returns struct cd9660node * Pointer to new node, or NULL on error
*/
static cd9660node *
@ -298,7 +298,7 @@ cd9660_prep_opts(fsinfo_t *fsopts)
"Allow 37 char filenames (unimplemented)"),
OPT_BOOL('i', "allow-illegal-chars", allow_illegal_chars,
"Allow illegal characters in filenames"),
OPT_BOOL('D', "allow-multidot", allow_multidot,
OPT_BOOL('m', "allow-multidot", allow_multidot,
"Allow multiple periods in filenames"),
OPT_BOOL('o', "omit-trailing-period", omit_trailing_period,
"Omit trailing periods in filenames"),
@ -321,6 +321,7 @@ cd9660_prep_opts(fsinfo_t *fsopts)
OPT_STR('\0', "no-boot", "No boot support"),
OPT_STR('\0', "hard-disk-boot", "Boot from hard disk"),
OPT_STR('\0', "boot-load-segment", "Boot load segment"),
OPT_STR('\0', "platformid", "Section Header Platform ID"),
{ .name = NULL }
};
@ -339,10 +340,11 @@ cd9660_cleanup_opts(fsinfo_t *fsopts)
}
static int
cd9660_arguments_set_string(const char *val, const char *fieldtitle, int length,
char testmode, char * dest)
cd9660_arguments_set_string(const char *val, const char *fieldtitle,
size_t length, char testmode, char * dest)
{
int len, test;
size_t len;
int test;
if (val == NULL)
warnx("error: The %s requires a string argument", fieldtitle);
@ -457,7 +459,8 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts)
/* RRIP */
cd9660_eltorito_add_boot_option(diskStructure, name, 0);
rv = 1;
} else if (strcmp(name, "boot-load-segment") == 0) {
} else if (strcmp(name, "boot-load-segment") == 0 ||
strcmp(name, "platformid") == 0) {
if (buf[0] == '\0') {
warnx("Option `%s' doesn't contain a value",
name);
@ -483,7 +486,7 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts)
*/
void
cd9660_makefs(const char *image, const char *dir, fsnode *root,
fsinfo_t *fsopts)
fsinfo_t *fsopts)
{
int64_t startoffset;
int numDirectories;
@ -661,7 +664,7 @@ typedef int (*cd9660node_func)(cd9660node *);
static void
cd9660_finalize_PVD(iso9660_disk *diskStructure)
{
time_t tim;
time_t tstamp = stampst.st_ino ? stampst.st_mtime : time(NULL);
/* root should be a fixed size of 34 bytes since it has no name */
memcpy(diskStructure->primaryDescriptor.root_directory_record,
@ -710,23 +713,23 @@ cd9660_finalize_PVD(iso9660_disk *diskStructure)
diskStructure->primaryDescriptor.bibliographic_file_id, 37);
/* Setup dates */
time(&tim);
cd9660_time_8426(
(unsigned char *)diskStructure->primaryDescriptor.creation_date,
tim);
tstamp);
cd9660_time_8426(
(unsigned char *)diskStructure->primaryDescriptor.modification_date,
tim);
tstamp);
/*
cd9660_set_date(diskStructure->primaryDescriptor.expiration_date, now);
*/
#if 0
cd9660_set_date(diskStructure->primaryDescriptor.expiration_date,
tstamp);
#endif
memset(diskStructure->primaryDescriptor.expiration_date, '0' ,16);
diskStructure->primaryDescriptor.expiration_date[16] = 0;
cd9660_time_8426(
(unsigned char *)diskStructure->primaryDescriptor.effective_date,
tim);
tstamp);
}
static void
@ -821,7 +824,7 @@ cd9660_fill_extended_attribute_record(cd9660node *node)
static int
cd9660_translate_node_common(iso9660_disk *diskStructure, cd9660node *newnode)
{
time_t tim;
time_t tstamp = stampst.st_ino ? stampst.st_mtime : time(NULL);
u_char flag;
char temp[ISO_FILENAME_MAXLENGTH_WITH_PADDING];
@ -841,9 +844,8 @@ cd9660_translate_node_common(iso9660_disk *diskStructure, cd9660node *newnode)
/* Set the various dates */
/* If we want to use the current date and time */
time(&tim);
cd9660_time_915(newnode->isoDirRecord->date, tim);
cd9660_time_915(newnode->isoDirRecord->date, tstamp);
cd9660_bothendian_dword(newnode->fileDataLength,
newnode->isoDirRecord->size);
@ -883,7 +885,8 @@ cd9660_translate_node(iso9660_disk *diskStructure, fsnode *node,
return 0;
/* Finally, overwrite some of the values that are set by default */
cd9660_time_915(newnode->isoDirRecord->date, node->inode->st.st_mtime);
cd9660_time_915(newnode->isoDirRecord->date,
stampst.st_ino ? stampst.st_mtime : node->inode->st.st_mtime);
return 1;
}
@ -1078,7 +1081,7 @@ cd9660_rename_filename(iso9660_disk *diskStructure, cd9660node *iter, int num,
tmp = emalloc(ISO_FILENAME_MAXLENGTH_WITH_PADDING);
while (i < num) {
while (i < num && iter) {
powers = 1;
count = 0;
digits = 1;
@ -1281,6 +1284,8 @@ cd9660_rrip_move_directory(iso9660_disk *diskStructure, cd9660node *dir)
diskStructure->rootNode, dir);
if (diskStructure->rr_moved_dir == NULL)
return 0;
cd9660_time_915(diskStructure->rr_moved_dir->isoDirRecord->date,
stampst.st_ino ? stampst.st_mtime : start_time.tv_sec);
}
/* Create a file with the same ORIGINAL name */
@ -1290,7 +1295,7 @@ cd9660_rrip_move_directory(iso9660_disk *diskStructure, cd9660node *dir)
return NULL;
diskStructure->rock_ridge_move_count++;
snprintf(newname, sizeof(newname), "%08i",
snprintf(newname, sizeof(newname), "%08u",
diskStructure->rock_ridge_move_count);
/* Point to old parent */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660.h,v 1.20 2013/01/29 15:52:25 christos Exp $ */
/* $NetBSD: cd9660.h,v 1.21 2015/12/24 15:52:37 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -308,7 +308,7 @@ typedef struct _iso9660_disk {
/************ FUNCTIONS **************/
int cd9660_valid_a_chars(const char *);
int cd9660_valid_d_chars(const char *);
void cd9660_uppercase_characters(char *, int);
void cd9660_uppercase_characters(char *, size_t);
/* ISO Data Types */
void cd9660_721(uint16_t, unsigned char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660_conversion.c,v 1.4 2007/03/14 14:11:17 christos Exp $ */
/* $NetBSD: cd9660_conversion.c,v 1.5 2017/02/08 21:33:12 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660_conversion.c,v 1.4 2007/03/14 14:11:17 christos Exp $");
__RCSID("$NetBSD: cd9660_conversion.c,v 1.5 2017/02/08 21:33:12 christos Exp $");
#endif /* !__lint */
@ -150,6 +150,9 @@ cd9660_pad_string_spaces(char *str, int len)
static char
cd9660_compute_gm_offset(time_t tim)
{
if (stampst.st_ino)
return 0;
struct tm t, gm;
(void)localtime_r(&tim, &t);
@ -173,7 +176,10 @@ cd9660_time_8426(unsigned char *buf, time_t tim)
struct tm t;
char temp[18];
(void)localtime_r(&tim, &t);
if (stampst.st_ino)
(void)gmtime_r(&tim, &t);
else
(void)localtime_r(&tim, &t);
(void)snprintf(temp, sizeof(temp), "%04i%02i%02i%02i%02i%02i%02i",
1900+(int)t.tm_year,
(int)t.tm_mon+1,
@ -192,7 +198,10 @@ cd9660_time_915(unsigned char *buf, time_t tim)
{
struct tm t;
(void)localtime_r(&tim, &t);
if (stampst.st_ino)
(void)gmtime_r(&tim, &t);
else
(void)localtime_r(&tim, &t);
buf[0] = t.tm_year;
buf[1] = t.tm_mon+1;
buf[2] = t.tm_mday;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660_eltorito.c,v 1.20 2013/01/28 21:03:28 christos Exp $ */
/* $NetBSD: cd9660_eltorito.c,v 1.24 2020/11/15 00:18:48 jmcneill Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660_eltorito.c,v 1.20 2013/01/28 21:03:28 christos Exp $");
__RCSID("$NetBSD: cd9660_eltorito.c,v 1.24 2020/11/15 00:18:48 jmcneill Exp $");
#endif /* !__lint */
#ifdef DEBUG
@ -56,11 +56,12 @@ static struct boot_catalog_entry *cd9660_boot_setup_validation_entry(char);
static struct boot_catalog_entry *cd9660_boot_setup_default_entry(
struct cd9660_boot_image *);
static struct boot_catalog_entry *cd9660_boot_setup_section_head(char);
static struct boot_catalog_entry *cd9660_boot_setup_validation_entry(char);
#if 0
static u_char cd9660_boot_get_system_type(struct cd9660_boot_image *);
#endif
static struct cd9660_boot_image *default_boot_image;
int
cd9660_add_boot_disk(iso9660_disk *diskStructure, const char *boot_info)
{
@ -108,9 +109,11 @@ cd9660_add_boot_disk(iso9660_disk *diskStructure, const char *boot_info)
else if (strcmp(sysname, "macppc") == 0 ||
strcmp(sysname, "mac68k") == 0)
new_image->system = ET_SYS_MAC;
else if (strcmp(sysname, "efi") == 0)
new_image->system = ET_SYS_EFI;
else {
warnx("boot disk system must be "
"i386, powerpc, macppc, or mac68k");
"i386, powerpc, macppc, mac68k, or efi");
free(temp);
free(new_image);
return 0;
@ -175,9 +178,15 @@ cd9660_add_boot_disk(iso9660_disk *diskStructure, const char *boot_info)
new_image->serialno = diskStructure->image_serialno++;
new_image->platform_id = new_image->system;
/* TODO : Need to do anything about the boot image in the tree? */
diskStructure->is_bootable = 1;
/* First boot image is initial/default entry. */
if (default_boot_image == NULL)
default_boot_image = new_image;
return 1;
}
@ -211,6 +220,13 @@ cd9660_eltorito_add_boot_option(iso9660_disk *diskStructure,
warn("%s: strtoul", __func__);
return 0;
}
} else if (strcmp(option_string, "platformid") == 0) {
if (strcmp(value, "efi") == 0)
image->platform_id = ET_SYS_EFI;
else {
warn("%s: unknown platform: %s", __func__, value);
return 0;
}
} else {
return 0;
}
@ -233,6 +249,7 @@ cd9660_boot_setup_validation_entry(char sys)
size_t i;
entry = cd9660_init_boot_catalog_entry();
entry->entry_type = ET_ENTRY_VE;
ve = &entry->entry_data.VE;
ve->header_id[0] = 1;
@ -267,6 +284,7 @@ cd9660_boot_setup_default_entry(struct cd9660_boot_image *disk)
if (default_entry == NULL)
return NULL;
default_entry->entry_type = ET_ENTRY_IE;
ie = &default_entry->entry_data.IE;
ie->boot_indicator[0] = disk->bootable;
@ -294,6 +312,7 @@ cd9660_boot_setup_section_head(char platform)
if (entry == NULL)
return NULL;
entry->entry_type = ET_ENTRY_SH;
sh = &entry->entry_data.SH;
/* More by default. The last one will manually be set to 0x91 */
sh->header_indicator[0] = ET_SECTION_HEADER_MORE;
@ -310,6 +329,7 @@ cd9660_boot_setup_section_entry(struct cd9660_boot_image *disk)
if ((entry = cd9660_init_boot_catalog_entry()) == NULL)
return NULL;
entry->entry_type = ET_ENTRY_SE;
se = &entry->entry_data.SE;
se->boot_indicator[0] = ET_BOOTABLE;
@ -342,12 +362,13 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
int used_sectors;
int num_entries = 0;
int catalog_sectors;
struct boot_catalog_entry *x86_head, *mac_head, *ppc_head,
struct boot_catalog_entry *x86_head, *mac_head, *ppc_head, *efi_head,
*valid_entry, *default_entry, *temp, *head, **headp, *next;
struct cd9660_boot_image *tmp_disk;
u_char system;
headp = NULL;
x86_head = mac_head = ppc_head = NULL;
x86_head = mac_head = ppc_head = efi_head = NULL;
/* If there are no boot disks, don't bother building boot information */
if (TAILQ_EMPTY(&diskStructure->boot_images))
@ -359,9 +380,16 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
cd9660_bothendian_dword(first_sector,
diskStructure->boot_descriptor->boot_catalog_pointer);
/*
* Use system type of default image for validation entry. Fallback to
* X86 system type if not found.
*/
system = default_boot_image != NULL ? default_boot_image->system :
ET_SYS_X86;
/* Step 1: Generate boot catalog */
/* Step 1a: Validation entry */
valid_entry = cd9660_boot_setup_validation_entry(ET_SYS_X86);
valid_entry = cd9660_boot_setup_validation_entry(system);
if (valid_entry == NULL)
return -1;
@ -391,14 +419,25 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
sector = first_sector + catalog_sectors;
TAILQ_FOREACH(tmp_disk, &diskStructure->boot_images, image_list) {
tmp_disk->sector = sector;
sector += tmp_disk->num_sectors;
sector += tmp_disk->num_sectors /
(diskStructure->sectorSize / 512);
}
LIST_INSERT_HEAD(&diskStructure->boot_entries, valid_entry, ll_struct);
/* Step 1b: Initial/default entry */
/* TODO : PARAM */
tmp_disk = TAILQ_FIRST(&diskStructure->boot_images);
if (default_boot_image != NULL) {
struct cd9660_boot_image *tcbi;
TAILQ_FOREACH(tcbi, &diskStructure->boot_images, image_list) {
if (tcbi == default_boot_image) {
tmp_disk = tcbi;
break;
}
}
}
if (tmp_disk == NULL)
tmp_disk = TAILQ_FIRST(&diskStructure->boot_images);
default_entry = cd9660_boot_setup_default_entry(tmp_disk);
if (default_entry == NULL) {
warnx("Error: memory allocation failed in cd9660_setup_boot");
@ -409,14 +448,18 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
/* Todo: multiple default entries? */
tmp_disk = TAILQ_NEXT(tmp_disk, image_list);
tmp_disk = TAILQ_FIRST(&diskStructure->boot_images);
head = NULL;
temp = default_entry;
/* If multiple boot images are given : */
while (tmp_disk != NULL) {
for (; tmp_disk != NULL; tmp_disk = TAILQ_NEXT(tmp_disk, image_list)) {
if (tmp_disk == default_boot_image)
continue;
/* Step 2: Section header */
switch (tmp_disk->system) {
switch (tmp_disk->platform_id) {
case ET_SYS_X86:
headp = &x86_head;
break;
@ -426,6 +469,9 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
case ET_SYS_MAC:
headp = &mac_head;
break;
case ET_SYS_EFI:
headp = &efi_head;
break;
default:
warnx("%s: internal error: unknown system type",
__func__);
@ -434,7 +480,7 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
if (*headp == NULL) {
head =
cd9660_boot_setup_section_head(tmp_disk->system);
cd9660_boot_setup_section_head(tmp_disk->platform_id);
if (head == NULL) {
warnx("Error: memory allocation failed in "
"cd9660_setup_boot");
@ -459,9 +505,17 @@ cd9660_setup_boot(iso9660_disk *diskStructure, int first_sector)
head = next;
LIST_INSERT_AFTER(head, temp, ll_struct);
tmp_disk = TAILQ_NEXT(tmp_disk, image_list);
}
/* Find the last Section Header entry and mark it as the last. */
head = NULL;
LIST_FOREACH(next, &diskStructure->boot_entries, ll_struct) {
if (next->entry_type == ET_ENTRY_SH)
head = next;
}
if (head != NULL)
head->entry_data.SH.header_indicator[0] = ET_SECTION_HEADER_LAST;
/* TODO: Remaining boot disks when implemented */
return first_sector + used_sectors;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660_eltorito.h,v 1.5 2009/07/04 14:31:38 ahoka Exp $ */
/* $NetBSD: cd9660_eltorito.h,v 1.6 2017/01/24 11:22:43 nonaka Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -40,6 +40,7 @@
#define ET_SYS_X86 0
#define ET_SYS_PPC 1
#define ET_SYS_MAC 2
#define ET_SYS_EFI 0xef /* Platform ID at section header entry */
#define ET_BOOT_ENTRY_SIZE 0x20
@ -145,6 +146,7 @@ struct cd9660_boot_image {
u_char targetMode;
u_char system;
u_char bootable;
u_char platform_id; /* for section header entry */
/*
* If the boot image exists in the filesystem
* already, this is a pointer to that node. For the sake

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660_strings.c,v 1.5 2011/03/23 13:11:51 christos Exp $ */
/* $NetBSD: cd9660_strings.c,v 1.6 2015/12/24 15:52:37 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -46,14 +46,14 @@
#include "cd9660.h"
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660_strings.c,v 1.5 2011/03/23 13:11:51 christos Exp $");
__RCSID("$NetBSD: cd9660_strings.c,v 1.6 2015/12/24 15:52:37 christos Exp $");
#endif /* !__lint */
void
cd9660_uppercase_characters(char *str, int len)
cd9660_uppercase_characters(char *str, size_t len)
{
int p;
size_t p;
for (p = 0; p < len; p++) {
if (islower((unsigned char)str[p]) )

View File

@ -43,10 +43,7 @@
#include <string.h>
#include <zlib.h>
#include <util.h>
#if defined(__minix)
#include <unistd.h>
#endif
#include "makefs.h"
#include "chfs_makefs.h"
@ -128,7 +125,6 @@ write_eb_header(fsinfo_t *fsopts)
if ((uint32_t)opts->pagesize < MINSIZE)
errx(EXIT_FAILURE, "pagesize cannot be less than %zu", MINSIZE);
buf = emalloc(opts->pagesize);
memset(buf, 0xFF, opts->pagesize);
ebhdr.ec_hdr.magic = htole32(CHFS_MAGIC_BITMASK);
ebhdr.ec_hdr.erase_cnt = htole32(1);
@ -136,6 +132,8 @@ write_eb_header(fsinfo_t *fsopts)
(uint8_t *)&ebhdr.ec_hdr + 8, 4));
memcpy(buf, &ebhdr.ec_hdr, CHFS_EB_EC_HDR_SIZE);
memset(buf + CHFS_EB_EC_HDR_SIZE, 0xFF,
opts->pagesize - CHFS_EB_EC_HDR_SIZE);
buf_write(fsopts, buf, opts->pagesize);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs.c,v 1.64 2015/01/12 19:50:25 christos Exp $ */
/* $NetBSD: ffs.c,v 1.70 2017/12/16 23:08:40 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -71,7 +71,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: ffs.c,v 1.64 2015/01/12 19:50:25 christos Exp $");
__RCSID("$NetBSD: ffs.c,v 1.70 2017/12/16 23:08:40 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -466,6 +466,7 @@ ffs_create_image(const char *image, fsinfo_t *fsopts)
char *buf;
int i, bufsize;
off_t bufrem;
time_t tstamp;
int oflags = O_RDWR | O_CREAT;
assert (image != NULL);
@ -530,7 +531,15 @@ ffs_create_image(const char *image, fsinfo_t *fsopts)
/* make the file system */
if (debug & DEBUG_FS_CREATE_IMAGE)
printf("calling mkfs(\"%s\", ...)\n", image);
fs = ffs_mkfs(image, fsopts);
if (stampst.st_ino)
tstamp = stampst.st_ctime;
else
tstamp = start_time.tv_sec;
srandom(tstamp);
fs = ffs_mkfs(image, fsopts, tstamp);
fsopts->superblock = (void *)fs;
if (debug & DEBUG_FS_CREATE_IMAGE) {
time_t t;
@ -637,19 +646,12 @@ ffs_build_dinode1(struct ufs1_dinode *dinp, dirbuf_t *dbufp, fsnode *cur,
{
size_t slen;
void *membuf;
struct stat *st = stampst.st_ino ? &stampst : &cur->inode->st;
memset(dinp, 0, sizeof(*dinp));
dinp->di_mode = cur->inode->st.st_mode;
dinp->di_nlink = cur->inode->nlink;
dinp->di_size = cur->inode->st.st_size;
dinp->di_atime = cur->inode->st.st_atime;
dinp->di_mtime = cur->inode->st.st_mtime;
dinp->di_ctime = cur->inode->st.st_ctime;
#if HAVE_STRUCT_STAT_ST_MTIMENSEC
dinp->di_atimensec = cur->inode->st.st_atimensec;
dinp->di_mtimensec = cur->inode->st.st_mtimensec;
dinp->di_ctimensec = cur->inode->st.st_ctimensec;
#endif
#if HAVE_STRUCT_STAT_ST_FLAGS
dinp->di_flags = cur->inode->st.st_flags;
#endif
@ -658,6 +660,15 @@ ffs_build_dinode1(struct ufs1_dinode *dinp, dirbuf_t *dbufp, fsnode *cur,
#endif
dinp->di_uid = cur->inode->st.st_uid;
dinp->di_gid = cur->inode->st.st_gid;
dinp->di_atime = st->st_atime;
dinp->di_mtime = st->st_mtime;
dinp->di_ctime = st->st_ctime;
#if HAVE_STRUCT_STAT_ST_MTIMENSEC
dinp->di_atimensec = st->st_atimensec;
dinp->di_mtimensec = st->st_mtimensec;
dinp->di_ctimensec = st->st_ctimensec;
#endif
/* not set: di_db, di_ib, di_blocks, di_spare */
membuf = NULL;
@ -685,31 +696,33 @@ ffs_build_dinode2(struct ufs2_dinode *dinp, dirbuf_t *dbufp, fsnode *cur,
{
size_t slen;
void *membuf;
struct stat *st = stampst.st_ino ? &stampst : &cur->inode->st;
memset(dinp, 0, sizeof(*dinp));
dinp->di_mode = cur->inode->st.st_mode;
dinp->di_nlink = cur->inode->nlink;
dinp->di_size = cur->inode->st.st_size;
dinp->di_atime = cur->inode->st.st_atime;
dinp->di_mtime = cur->inode->st.st_mtime;
dinp->di_ctime = cur->inode->st.st_ctime;
#if HAVE_STRUCT_STAT_ST_MTIMENSEC
dinp->di_atimensec = cur->inode->st.st_atimensec;
dinp->di_mtimensec = cur->inode->st.st_mtimensec;
dinp->di_ctimensec = cur->inode->st.st_ctimensec;
#endif
#if HAVE_STRUCT_STAT_ST_FLAGS
dinp->di_flags = cur->inode->st.st_flags;
#endif
#if HAVE_STRUCT_STAT_ST_GEN
dinp->di_gen = cur->inode->st.st_gen;
#endif
#if HAVE_STRUCT_STAT_BIRTHTIME
dinp->di_birthtime = cur->inode->st.st_birthtime;
dinp->di_birthnsec = cur->inode->st.st_birthtimensec;
#endif
dinp->di_uid = cur->inode->st.st_uid;
dinp->di_gid = cur->inode->st.st_gid;
dinp->di_atime = st->st_atime;
dinp->di_mtime = st->st_mtime;
dinp->di_ctime = st->st_ctime;
#if HAVE_STRUCT_STAT_ST_MTIMENSEC
dinp->di_atimensec = st->st_atimensec;
dinp->di_mtimensec = st->st_mtimensec;
dinp->di_ctimensec = st->st_ctimensec;
#endif
#if HAVE_STRUCT_STAT_BIRTHTIME
dinp->di_birthtime = st->st_birthtime;
dinp->di_birthnsec = st->st_birthtimensec;
#endif
/* not set: di_db, di_ib, di_blocks, di_spare */
membuf = NULL;
@ -1102,12 +1115,11 @@ ffs_write_inode(union dinode *dp, uint32_t ino, const fsinfo_t *fsopts)
* Initialize inode blocks on the fly for UFS2.
*/
initediblk = ufs_rw32(cgp->cg_initediblk, fsopts->needswap);
if (ffs_opts->version == 2 &&
while (ffs_opts->version == 2 &&
(uint32_t)(cgino + FFS_INOPB(fs)) > initediblk &&
initediblk < ufs_rw32(cgp->cg_niblk, fsopts->needswap)) {
memset(buf, 0, fs->fs_bsize);
dip = (struct ufs2_dinode *)buf;
srandom(time(NULL));
for (i = 0; i < FFS_INOPB(fs); i++) {
dip->di_gen = random() / 2 + 1;
dip++;

View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.c,v 1.22 2015/03/29 05:52:59 agc Exp $ */
/* $NetBSD: buf.c,v 1.24 2016/06/24 19:24:11 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: buf.c,v 1.22 2015/03/29 05:52:59 agc Exp $");
__RCSID("$NetBSD: buf.c,v 1.24 2016/06/24 19:24:11 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -78,17 +78,17 @@ bread(struct vnode *vp, daddr_t blkno, int size, int u2 __unused,
(long long)(*bpp)->b_blkno, (long long) offset,
(*bpp)->b_bcount);
if (lseek((*bpp)->b_fs->fd, offset, SEEK_SET) == -1)
err(1, "%s: lseek %lld (%lld)", __func__,
err(EXIT_FAILURE, "%s: lseek %lld (%lld)", __func__,
(long long)(*bpp)->b_blkno, (long long)offset);
rv = read((*bpp)->b_fs->fd, (*bpp)->b_data, (*bpp)->b_bcount);
rv = read((*bpp)->b_fs->fd, (*bpp)->b_data, (size_t)(*bpp)->b_bcount);
if (debug & DEBUG_BUF_BREAD)
printf("bread: read %ld (%lld) returned %zd\n",
(*bpp)->b_bcount, (long long)offset, rv);
if (rv == -1) /* read error */
err(1, "%s: read %ld (%lld) returned %zd", __func__,
err(EXIT_FAILURE, "%s: read %ld (%lld) returned %zd", __func__,
(*bpp)->b_bcount, (long long)offset, rv);
else if (rv != (*bpp)->b_bcount) /* short read */
err(1, "%s: read %ld (%lld) returned %zd", __func__,
errx(EXIT_FAILURE, "%s: read %ld (%lld) returned %zd", __func__,
(*bpp)->b_bcount, (long long)offset, rv);
else
return (0);
@ -129,14 +129,14 @@ bwrite(struct buf *bp)
{
off_t offset;
ssize_t rv;
int bytes;
size_t bytes;
fsinfo_t *fs = bp->b_fs;
assert (bp != NULL);
offset = bp->b_blkno * fs->sectorsize + fs->offset;
bytes = bp->b_bcount;
bytes = (size_t)bp->b_bcount;
if (debug & DEBUG_BUF_BWRITE)
printf("bwrite: blkno %lld offset %lld bcount %d\n",
printf("bwrite: blkno %lld offset %lld bcount %zu\n",
(long long)bp->b_blkno, (long long) offset, bytes);
if (lseek(bp->b_fs->fd, offset, SEEK_SET) == -1)
return (errno);
@ -145,7 +145,7 @@ bwrite(struct buf *bp)
printf("bwrite: write %ld (offset %lld) returned %lld\n",
bp->b_bcount, (long long)offset, (long long)rv);
brelse(bp, 0);
if (rv == bytes)
if (rv == (ssize_t)bytes)
return (0);
else if (rv == -1) /* write error */
return (errno);
@ -210,8 +210,8 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int u1 __unused,
}
bp->b_bcount = size;
if (bp->b_data == NULL || bp->b_bcount > bp->b_bufsize) {
n = erealloc(bp->b_data, size);
memset(n, 0, size);
n = erealloc(bp->b_data, (size_t)size);
memset(n, 0, (size_t)size);
bp->b_data = n;
bp->b_bufsize = size;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.h,v 1.10 2015/03/29 05:52:59 agc Exp $ */
/* $NetBSD: buf.h,v 1.13 2018/09/03 16:29:37 riastradh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -40,6 +40,7 @@
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
@ -87,7 +88,34 @@ struct buf * getblk(struct vnode *, daddr_t, int, int, int);
#define BC_AGE 0
#define min(a, b) MIN((a), (b))
#define microtime(tv) gettimeofday((tv), NULL)
static inline unsigned int
uimin(unsigned int a, unsigned int b)
{
return (a < b ? a : b);
}
static inline unsigned int
uimax(unsigned int a, unsigned int b)
{
return (a > b ? a : b);
}
static inline void
microtime(struct timeval *tv)
{
extern struct stat stampst;
if (stampst.st_ino) {
tv->tv_sec = stampst.st_mtime;
tv->tv_usec = 0;
} else {
gettimeofday((tv), NULL);
}
}
#define KASSERT(a)
#define IO_SYNC 1

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_alloc.c,v 1.28 2015/03/29 05:52:59 agc Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.29 2016/06/24 19:24:11 christos Exp $ */
/* From: NetBSD: ffs_alloc.c,v 1.50 2001/09/06 02:16:01 lukem Exp */
/*
@ -47,7 +47,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: ffs_alloc.c,v 1.28 2015/03/29 05:52:59 agc Exp $");
__RCSID("$NetBSD: ffs_alloc.c,v 1.29 2016/06/24 19:24:11 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -107,7 +107,7 @@ ffs_alloc(struct inode *ip, daddr_t lbn __unused, daddr_t bpref, int size,
*bnp = 0;
if (size > fs->fs_bsize || ffs_fragoff(fs, size) != 0) {
errx(1, "ffs_alloc: bad size: bsize %d size %d",
errx(EXIT_FAILURE, "%s: bad size: bsize %d size %d", __func__,
fs->fs_bsize, size);
}
if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
@ -441,8 +441,8 @@ ffs_blkfree(struct inode *ip, daddr_t bno, long size)
if (size > fs->fs_bsize || ffs_fragoff(fs, size) != 0 ||
ffs_fragnum(fs, bno) + ffs_numfrags(fs, size) > fs->fs_frag) {
errx(1, "blkfree: bad size: bno %lld bsize %d size %ld",
(long long)bno, fs->fs_bsize, size);
errx(EXIT_FAILURE, "%s: bad size: bno %lld bsize %d "
"size %ld", __func__, (long long)bno, fs->fs_bsize, size);
}
cg = dtog(fs, bno);
if (bno >= fs->fs_size) {
@ -465,8 +465,8 @@ ffs_blkfree(struct inode *ip, daddr_t bno, long size)
if (size == fs->fs_bsize) {
fragno = ffs_fragstoblks(fs, cgbno);
if (!ffs_isfreeblock(fs, cg_blksfree(cgp, needswap), fragno)) {
errx(1, "blkfree: freeing free block %lld",
(long long)bno);
errx(EXIT_FAILURE, "%s: freeing free block %lld",
__func__, (long long)bno);
}
ffs_setblock(fs, cg_blksfree(cgp, needswap), fragno);
ffs_clusteracct(fs, cgp, fragno, 1);
@ -486,7 +486,8 @@ ffs_blkfree(struct inode *ip, daddr_t bno, long size)
frags = ffs_numfrags(fs, size);
for (i = 0; i < frags; i++) {
if (isset(cg_blksfree(cgp, needswap), cgbno + i)) {
errx(1, "blkfree: freeing free frag: block %lld",
errx(EXIT_FAILURE, "%s: freeing free frag: "
"block %lld", __func__,
(long long)(cgbno + i));
}
setbit(cg_blksfree(cgp, needswap), cgbno + i);
@ -566,11 +567,10 @@ ffs_mapsearch(struct fs *fs, struct cg *cgp, daddr_t bpref, int allocsiz)
(const u_char *)fragtbl[fs->fs_frag],
(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));
if (loc == 0) {
errx(1,
"ffs_alloccg: map corrupted: start %d len %d offset %d %ld",
ostart, olen,
ufs_rw32(cgp->cg_freeoff, needswap),
(long)cg_blksfree(cgp, needswap) - (long)cgp);
errx(EXIT_FAILURE, "%s: map corrupted: start %d "
"len %d offset %d %ld", __func__, ostart, olen,
ufs_rw32(cgp->cg_freeoff, needswap),
(long)cg_blksfree(cgp, needswap) - (long)cgp);
/* NOTREACHED */
}
}
@ -592,6 +592,7 @@ ffs_mapsearch(struct fs *fs, struct cg *cgp, daddr_t bpref, int allocsiz)
subfield <<= 1;
}
}
errx(1, "ffs_alloccg: block not in map: bno %lld", (long long)bno);
errx(EXIT_FAILURE, "%s: block not in map: bno %lld", __func__,
(long long)bno);
return (-1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_extern.h,v 1.6 2003/08/07 11:25:33 agc Exp $ */
/* $NetBSD: ffs_extern.h,v 1.7 2017/02/09 04:42:53 kre Exp $ */
/* From: NetBSD: ffs_extern.h,v 1.19 2001/08/17 02:18:48 lukem Exp */
/*-
@ -59,7 +59,7 @@ void ffs_clusteracct(struct fs *, struct cg *, int32_t, int);
int ffs_balloc(struct inode *, off_t, int, struct buf **);
/* ffs_bswap.c */
void ffs_sb_swap(struct fs*, struct fs *);
void ffs_sb_swap(const struct fs*, struct fs *);
void ffs_dinode1_swap(struct ufs1_dinode *, struct ufs1_dinode *);
void ffs_dinode2_swap(struct ufs2_dinode *, struct ufs2_dinode *);
void ffs_csum_swap(struct csum *, struct csum *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs.c,v 1.32 2013/10/19 17:16:37 christos Exp $ */
/* $NetBSD: mkfs.c,v 1.39 2020/03/26 04:25:28 kre Exp $ */
/*
* Copyright (c) 2002 Networks Associates Technology, Inc.
@ -48,7 +48,7 @@
static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
#else
#ifdef __RCSID
__RCSID("$NetBSD: mkfs.c,v 1.32 2013/10/19 17:16:37 christos Exp $");
__RCSID("$NetBSD: mkfs.c,v 1.39 2020/03/26 04:25:28 kre Exp $");
#endif
#endif
#endif /* not lint */
@ -102,7 +102,11 @@ union {
char *iobuf;
int iobufsize;
char writebuf[FFS_MAXBSIZE];
union {
struct fs fs;
char pad[FFS_MAXBSIZE];
} wb;
#define writebuf wb.pad
static int Oflag; /* format as an 4.3BSD file system */
static int64_t fssize; /* file system size */
@ -121,8 +125,19 @@ static int sbsize; /* superblock size */
static int avgfilesize; /* expected average file size */
static int avgfpdir; /* expected number of files per directory */
static void
ffs_sb_copy(struct fs *o, const struct fs *i, size_t l, const fsinfo_t *fsopts)
{
memcpy(o, i, l);
/* Zero out pointers */
o->fs_csp = NULL;
o->fs_maxcluster = NULL;
if (fsopts->needswap)
ffs_sb_swap(i, o);
}
struct fs *
ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
{
int fragsperinode, optimalfpg, origdensity, minfpg, lastminfpg;
int32_t cylno, i, csfrags;
@ -445,7 +460,7 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
sblock.fs_state = 0;
sblock.fs_clean = FS_ISCLEAN;
sblock.fs_ronly = 0;
sblock.fs_id[0] = start_time.tv_sec;
sblock.fs_id[0] = tstamp;
sblock.fs_id[1] = random();
sblock.fs_fsmnt[0] = '\0';
csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize);
@ -461,9 +476,9 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
sblock.fs_cstotal.cs_nifree = sblock.fs_ncg * sblock.fs_ipg - UFS_ROOTINO;
sblock.fs_cstotal.cs_ndir = 0;
sblock.fs_dsize -= csfrags;
sblock.fs_time = start_time.tv_sec;
sblock.fs_time = tstamp;
if (Oflag <= 1) {
sblock.fs_old_time = start_time.tv_sec;
sblock.fs_old_time = tstamp;
sblock.fs_old_dsize = sblock.fs_dsize;
sblock.fs_old_csaddr = sblock.fs_csaddr;
sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
@ -508,14 +523,12 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
* Make a copy of the superblock into the buffer that we will be
* writing out in each cylinder group.
*/
memcpy(writebuf, &sblock, sbsize);
if (fsopts->needswap)
ffs_sb_swap(&sblock, (struct fs*)writebuf);
ffs_sb_copy(&wb.fs, &sblock, sbsize, fsopts);
memcpy(iobuf, writebuf, SBLOCKSIZE);
printf("super-block backups (for fsck -b #) at:");
for (cylno = 0; cylno < sblock.fs_ncg; cylno++) {
initcg(cylno, start_time.tv_sec, fsopts);
initcg(cylno, tstamp, fsopts);
if (cylno % nprintcols == 0)
printf("\n");
printf(" %*lld,", printcolwidth,
@ -528,7 +541,7 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
* Now construct the initial file system,
* then write out the super-block.
*/
sblock.fs_time = start_time.tv_sec;
sblock.fs_time = tstamp;
if (Oflag <= 1) {
sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
sblock.fs_old_cstotal.cs_nbfree = sblock.fs_cstotal.cs_nbfree;
@ -555,9 +568,7 @@ ffs_write_superblock(struct fs *fs, const fsinfo_t *fsopts)
saveflag = fs->fs_flags & FS_INTERNAL;
fs->fs_flags &= ~FS_INTERNAL;
memcpy(writebuf, &sblock, sbsize);
if (fsopts->needswap)
ffs_sb_swap(fs, (struct fs*)writebuf);
ffs_sb_copy(&wb.fs, &sblock, sbsize, fsopts);
ffs_wtfs(fs->fs_sblockloc / sectorsize, sbsize, writebuf, fsopts);
/* Write out the duplicate super blocks */
@ -787,15 +798,15 @@ ffs_rdfs(daddr_t bno, int size, void *bf, const fsinfo_t *fsopts)
offset = bno * fsopts->sectorsize + fsopts->offset;
if (lseek(fsopts->fd, offset, SEEK_SET) < 0)
err(1, "%s: seek error for sector %lld", __func__,
err(EXIT_FAILURE, "%s: seek error for sector %lld", __func__,
(long long)bno);
n = read(fsopts->fd, bf, size);
if (n == -1) {
err(1, "%s: read error bno %lld size %d", __func__,
err(EXIT_FAILURE, "%s: read error bno %lld size %d", __func__,
(long long)bno, size);
}
else if (n != size)
errx(1, "%s: short read error for sector %lld", __func__,
errx(EXIT_FAILURE, "%s: short read error for sector %lld", __func__,
(long long)bno);
}
@ -810,15 +821,15 @@ ffs_wtfs(daddr_t bno, int size, void *bf, const fsinfo_t *fsopts)
offset = bno * fsopts->sectorsize + fsopts->offset;
if (lseek(fsopts->fd, offset, SEEK_SET) == -1)
err(1, "%s: seek error for sector %lld", __func__,
(long long)bno);
err(EXIT_FAILURE, "%s: seek error @%jd for sector %jd",
__func__, (intmax_t)offset, (intmax_t)bno);
n = write(fsopts->fd, bf, size);
if (n == -1)
err(1, "%s: write error for sector %lld", __func__,
(long long)bno);
err(EXIT_FAILURE, "%s: write error for sector %jd", __func__,
(intmax_t)bno);
else if (n != size)
errx(1, "%s: short write error for sector %lld", __func__,
(long long)bno);
errx(EXIT_FAILURE, "%s: short write error for sector %jd",
__func__, (intmax_t)bno);
}
@ -841,5 +852,5 @@ ilog2(int val)
for (n = 0; n < sizeof(n) * CHAR_BIT; n++)
if (1 << n == val)
return (n);
errx(1, "%s: %d is not a power of 2", __func__, val);
errx(EXIT_FAILURE, "%s: %d is not a power of 2", __func__, val);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs_extern.h,v 1.3 2009/10/21 01:07:47 snj Exp $ */
/* $NetBSD: newfs_extern.h,v 1.4 2015/12/21 00:58:08 christos Exp $ */
/* From: NetBSD: extern.h,v 1.3 2000/12/01 12:03:27 simonb Exp $ */
/*
@ -26,7 +26,7 @@
*/
/* prototypes */
struct fs *ffs_mkfs(const char *, const fsinfo_t *);
struct fs *ffs_mkfs(const char *, const fsinfo_t *, time_t);
void ffs_write_superblock(struct fs *, const fsinfo_t *);
void ffs_rdfs(daddr_t, int, void *, const fsinfo_t *);
void ffs_wtfs(daddr_t, int, void *, const fsinfo_t *);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: makefs.8,v 1.53 2013/08/06 20:16:54 wiz Exp $
.\" $NetBSD: makefs.8,v 1.66 2020/11/15 00:18:48 jmcneill Exp $
.\"
.\" Copyright (c) 2001-2003 Wasabi Systems, Inc.
.\" All rights reserved.
@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd August 6, 2013
.Dd November 14, 2020
.Dt MAKEFS 8
.Os
.Sh NAME
@ -54,6 +54,7 @@
.Op Fl o Ar fs-options
.Op Fl S Ar sector-size
.Op Fl s Ar image-size
.Op Fl T Ar timestamp
.Op Fl t Ar fs-type
.Ar image-file
.Ar directory
@ -178,7 +179,7 @@ and
.Xr getgrnam 3
(and related) library calls.
.It Fl O Ar offset
Instead of creating the filesystem at the beginning of the file, start
Instead of creating the file system at the beginning of the file, start
at offset.
Valid only for
.Sy ffs
@ -199,24 +200,58 @@ Defaults to 512.
.It Fl s Ar image-size
Set the size of the file system image to
.Ar image-size .
This is equivalent of setting both the minimum
.Fl ( M )
and the maximum
.Fl ( m )
sizes to
.Ar image-size .
For
.Sy ffs
and
.Sy msdos
the
.Ar offset
is not included on that size.
.It Fl T Ar timestamp
Specify a timestamp to be set for all file system files and directories
created so that repeatable builds are possible.
The
.Ar timestamp
can be a
.Pa pathname ,
where the timestamps are derived from that file, a parseable date
for
.Xr parsedate 3
(this option is not yet available in the tools build), or an integer
value interpreted as the number of seconds from the Epoch.
Note that timestamps specified in an
.Xr mtree 5
spec file, override the default timestamp.
When this option is enabled, file systems that regularly use
.Xr localtime 3
to convert times to the native format (such as udf and cd9660), use
.Xr gmtime 3
instead with the specified timestamps so that they are immune to
timezone changes and get consistent timestamps.
.It Fl t Ar fs-type
Create an
.Ar fs-type
file system image.
The following file system types are supported:
.Bl -tag -width cd9660 -offset indent
.It Sy ffs
BSD fast file system (default).
.It Sy cd9660
ISO 9660 file system.
.It Sy chfs
Chip flash file system.
.It Sy ffs
BSD fast file system (default).
.It Sy msdos
FAT12, FAT16, or FAT32 file system.
.It Sy v7fs
7th Edition(V7) file system.
.It Sy udf
ISO/Ecma UDF file system.
.It Sy v7fs
7th Edition(V7) file system.
.El
.It Fl x
Exclude file system nodes not explicitly listed in the specfile.
@ -228,7 +263,7 @@ This is useful for virtual machine images.
.Pp
Where sizes are specified, a decimal number of bytes is expected.
Two or more numbers may be separated by an
.Dq x
.Sq x
to indicate a product.
Each number may have one of the following optional suffixes:
.Bl -tag -width 3n -offset indent -compact
@ -264,10 +299,14 @@ Expected number of files per directory.
Block size.
.It Sy density
Bytes per inode.
.It Sy extent
Maximum extent size.
.It Sy fsize
Fragment size.
.It Sy label
Label name of the image.
.It Sy maxbpcg
Maximum total number of blocks in a cylinder group.
.It Sy maxbpg
Maximum blocks per file in a cylinder group.
.It Sy minfree
@ -277,10 +316,6 @@ Optimization preference; one of
.Ql space
or
.Ql time .
.It Sy extent
Maximum extent size.
.It Sy maxbpcg
Maximum total number of blocks in a cylinder group.
.It Sy version
UFS version.
1 for FFS (default), 2 for UFS2.
@ -304,7 +339,7 @@ the spec.
.\" Unknown
.It Sy allow-max-name
Allow 37 instead of 33 characters for filenames by omitting the
version id.
version ID.
.It Sy allow-multidot
Allow multiple dots in a filename.
.It Sy applicationid
@ -315,9 +350,6 @@ Use the
extension to encode
.Tn RISC OS
metadata.
.It Sy chrp-boot
Write an MBR partition table to the image to allow older CHRP hardware to
boot.
.It Sy boot-load-segment
Set load segment for the boot image.
.It Sy bootimage
@ -326,11 +358,15 @@ Filename of a boot image in the format
where
.Dq sysid
is one of
.Ql efi ,
.Ql i386 ,
.Ql mac68k ,
.Ql macppc ,
or
.Ql powerpc .
.It Sy chrp-boot
Write an MBR partition table to the image to allow older CHRP hardware to
boot.
.It Sy generic-bootimage
Load a generic boot image into the first 32K of the cd9660 image.
.It Sy hard-disk-boot
@ -350,6 +386,8 @@ ElTorito image.
Do not pad the image (apparently Linux needs the padding).
.\" .It Sy omit-trailing-period
.\" Unknown
.It Sy platformid
Set platform ID of section header entry of the boot image.
.It Sy preparer
Preparer ID of the image.
.It Sy publisher
@ -377,9 +415,63 @@ Type of the media.
NOR: 0 or NAND: 1.
.El
.Ss msdos-specific options
See
.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 fs specific options.
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.
.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
.Ss V7FS-specific options
The following keywords are supported:
.Pp
@ -398,7 +490,7 @@ Each of the options consists of a keyword, an equal sign
and a value.
The following keywords are supported:
.Pp
.Bl -tag -width optimization -compact
.Bl -tag -width optimization -offset indent -compact
.It Sy disctype
This can have the following values:
.Bl -tag -width cdromXdvdromXbdromXXX -compact
@ -453,8 +545,8 @@ utility appeared in
.An UCHIYAMA Yasushi
(v7fs support),
.An Tamas Toth
(chfs support).
(chfs support),
.An Christos Zoulas
(msdos support).
(msdos support),
.An Reinoud Zandijk
(udf support).

View File

@ -1,4 +1,4 @@
/* $NetBSD: makefs.c,v 1.50 2013/08/05 14:41:57 reinoud Exp $ */
/* $NetBSD: makefs.c,v 1.53 2015/11/27 15:10:32 joerg Exp $ */
/*
* Copyright (c) 2001-2003 Wasabi Systems, Inc.
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: makefs.c,v 1.50 2013/08/05 14:41:57 reinoud Exp $");
__RCSID("$NetBSD: makefs.c,v 1.53 2015/11/27 15:10:32 joerg Exp $");
#endif /* !__lint */
#include <assert.h>
@ -87,8 +87,10 @@ static fstype_t fstypes[] = {
u_int debug;
struct timespec start_time;
struct stat stampst;
static fstype_t *get_fstype(const char *);
static int get_tstamp(const char *, struct stat *);
static void usage(fstype_t *, fsinfo_t *) __dead;
int
@ -116,13 +118,18 @@ main(int argc, char *argv[])
fstype->prepare_options(&fsoptions);
specfile = NULL;
if (gettimeofday(&start, NULL) == -1)
err(1, "Unable to get system time");
#ifdef CLOCK_REALTIME
ch = clock_gettime(CLOCK_REALTIME, &start_time);
#else
ch = gettimeofday(&start, NULL);
start_time.tv_sec = start.tv_sec;
start_time.tv_nsec = start.tv_usec * 1000;
#endif
if (ch == -1)
err(1, "Unable to get system time");
while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:O:o:rs:S:t:xZ")) != -1) {
while ((ch = getopt(argc, argv, "B:b:d:f:F:M:m:N:O:o:rs:S:t:T:xZ")) != -1) {
switch (ch) {
case 'B':
@ -240,6 +247,12 @@ main(int argc, char *argv[])
fstype->prepare_options(&fsoptions);
break;
case 'T':
if (get_tstamp(optarg, &stampst) == -1)
errx(1, "Cannot get timestamp from `%s'",
optarg);
break;
case 'x':
fsoptions.onlyspec = 1;
break;
@ -409,6 +422,36 @@ copy_opts(const option_t *o)
return memcpy(ecalloc(i, sizeof(*o)), o, i * sizeof(*o));
}
static int
get_tstamp(const char *b, struct stat *st)
{
time_t when;
char *eb;
long long l;
if (stat(b, st) != -1)
return 0;
#ifndef HAVE_NBTOOL_CONFIG_H
errno = 0;
if ((when = parsedate(b, NULL, NULL)) == -1 && errno != 0)
#endif
{
errno = 0;
l = strtoll(b, &eb, 0);
if (b == eb || *eb || errno)
return -1;
when = (time_t)l;
}
st->st_ino = 1;
#if HAVE_STRUCT_STAT_BIRTHTIME
st->st_birthtime =
#endif
st->st_mtime = st->st_ctime = st->st_atime = when;
return 0;
}
static void
usage(fstype_t *fstype, fsinfo_t *fsoptions)
{
@ -419,7 +462,8 @@ usage(fstype_t *fstype, fsinfo_t *fsoptions)
"Usage: %s [-rxZ] [-B endian] [-b free-blocks] [-d debug-mask]\n"
"\t[-F mtree-specfile] [-f free-files] [-M minimum-size] [-m maximum-size]\n"
"\t[-N userdb-dir] [-O offset] [-o fs-options] [-S sector-size]\n"
"\t[-s image-size] [-t fs-type] image-file directory [extra-directory ...]\n",
"\t[-s image-size] [-T <timestamp/file>] [-t fs-type]"
" image-file directory [extra-directory ...]\n",
prog);
if (fstype) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: makefs.h,v 1.35 2013/08/05 14:41:57 reinoud Exp $ */
/* $NetBSD: makefs.h,v 1.36 2015/11/25 00:48:49 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -199,6 +199,7 @@ DECLARE_FUN(udf);
extern u_int debug;
extern struct timespec start_time;
extern struct stat stampst;
/*
* If -x is specified, we want to exclude nodes which do not appear

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdos.c,v 1.14 2013/02/03 03:21:21 christos Exp $ */
/* $NetBSD: msdos.c,v 1.20 2017/04/14 15:40:35 christos Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 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. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -37,7 +34,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: msdos.c,v 1.14 2013/02/03 03:21:21 christos Exp $");
__RCSID("$NetBSD: msdos.c,v 1.20 2017/04/14 15:40:35 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -58,7 +55,9 @@ __RCSID("$NetBSD: msdos.c,v 1.14 2013/02/03 03:21:21 christos Exp $");
#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"
@ -66,10 +65,15 @@ __RCSID("$NetBSD: msdos.c,v 1.14 2013/02/03 03:21:21 christos Exp $");
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 *msdos_opt = ecalloc(1, sizeof(*msdos_opt));
struct msdos_options_ex *msdos_opt = ecalloc(1, sizeof(*msdos_opt));
const option_t msdos_options[] = {
#define AOPT(_opt, _type, _name, _min, _desc) { \
.letter = _opt, \
@ -79,7 +83,7 @@ msdos_prep_opts(fsinfo_t *fsopts)
(sizeof(_type) == 1 ? OPT_INT8 : \
(sizeof(_type) == 2 ? OPT_INT16 : \
(sizeof(_type) == 4 ? OPT_INT32 : OPT_INT64)))), \
.value = &msdos_opt->_name, \
.value = &msdos_opt->options._name, \
.minimum = _min, \
.maximum = sizeof(_type) == 1 ? 0xff : \
(sizeof(_type) == 2 ? 0xffff : \
@ -88,6 +92,8 @@ msdos_prep_opts(fsinfo_t *fsopts)
},
ALLOPTS
#undef AOPT
{ 'U', "utf8", &msdos_opt->utf8, OPT_BOOL,
0, 1, "Use UTF8 names" },
{ .name = NULL }
};
@ -127,6 +133,12 @@ msdos_parse_opts(const char *option, fsinfo_t *fsopts)
msdos_opt->media_descriptor_set = 1;
else if (strcmp(msdos_options[rv].name, "hidden_sectors") == 0)
msdos_opt->hidden_sectors_set = 1;
if (stampst.st_ino) {
msdos_opt->timestamp_set = 1;
msdos_opt->timestamp = stampst.st_mtime;
}
return 1;
}
@ -134,45 +146,48 @@ msdos_parse_opts(const char *option, fsinfo_t *fsopts)
void
msdos_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
{
struct msdos_options *msdos_opt = fsopts->fs_specific;
struct msdos_options_ex *msdos_opt = fsopts->fs_specific;
struct vnode vp, rootvp;
struct timeval start;
struct msdosfsmount *pmp;
uint32_t flags;
assert(image != NULL);
assert(dir != NULL);
assert(root != NULL);
assert(fsopts != NULL);
/*
* XXX: pick up other options from the msdos specific ones?
* Is minsize right here?
*/
msdos_opt->create_size = MAX(msdos_opt->create_size, fsopts->minsize);
msdos_opt->offset = fsopts->offset;
if (msdos_opt->bytes_per_sector == 0) {
fsopts->size = fsopts->maxsize;
msdos_opt->options.create_size = MAX(msdos_opt->options.create_size,
fsopts->offset + fsopts->size);
msdos_opt->options.offset = fsopts->offset;
if (msdos_opt->options.bytes_per_sector == 0) {
if (fsopts->sectorsize == -1)
fsopts->sectorsize = 512;
msdos_opt->bytes_per_sector = fsopts->sectorsize;
msdos_opt->options.bytes_per_sector = fsopts->sectorsize;
} else if (fsopts->sectorsize == -1) {
fsopts->sectorsize = msdos_opt->bytes_per_sector;
} else if (fsopts->sectorsize != msdos_opt->bytes_per_sector) {
fsopts->sectorsize = msdos_opt->options.bytes_per_sector;
} else if (fsopts->sectorsize != msdos_opt->options.bytes_per_sector) {
err(1, "inconsistent sectorsize -S %u"
"!= -o bytes_per_sector %u",
fsopts->sectorsize, msdos_opt->bytes_per_sector);
fsopts->sectorsize, msdos_opt->options.bytes_per_sector);
}
/* create image */
printf("Creating `%s'\n", image);
TIMER_START(start);
if (mkfs_msdos(image, NULL, msdos_opt) == -1)
if (mkfs_msdos(image, NULL, &msdos_opt->options) == -1)
return;
TIMER_RESULTS(start, "mkfs_msdos");
fsopts->fd = open(image, O_RDWR);
vp.fs = fsopts;
if ((pmp = msdosfs_mount(&vp, 0)) == NULL)
flags = 0;
if (msdos_opt->utf8)
flags |= MSDOSFSMNT_UTF8;
if ((pmp = msdosfs_mount(&vp, flags)) == NULL)
err(1, "msdosfs_mount");
if (msdosfs_root(pmp, &rootvp) != 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdos.h,v 1.2 2013/01/26 00:31:49 christos Exp $ */
/* $NetBSD: msdos.h,v 1.3 2015/10/16 16:40:02 christos Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 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. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.6 2014/09/01 09:09:47 martin Exp $
# $NetBSD: Makefile.inc,v 1.7 2016/02/06 10:40:58 mlelstv Exp $
#
MSDOS= ${NETBSDSRCDIR}/sys/fs/msdosfs
@ -12,5 +12,5 @@ CPPFLAGS+= -I${NETBSDSRCDIR}/sys
.endif
SRCS+= mkfs_msdos.c msdosfs_fat.c msdosfs_conv.c msdosfs_vfsops.c
SRCS+= msdosfs_lookup.c msdosfs_denode.c msdosfs_vnops.c
SRCS+= msdosfs_lookup.c msdosfs_denode.c msdosfs_vnops.c msdosfs_unicode.c
SRCS+= clock_subr.c

View File

@ -50,7 +50,7 @@
#endif
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.9 2015/03/29 05:52:59 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.11 2018/01/27 02:07:33 sevan Exp $");
#include <sys/param.h>
@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.9 2015/03/29 05:52:59 agc Exp $
#include <stdlib.h>
#include <string.h>
#include <util.h>
#include <strings.h>
#include "makefs.h"
#include "msdos.h"
@ -152,6 +153,12 @@ msdosfs_mount(struct vnode *devvp, int flags)
}
}
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);

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vnops.c,v 1.16 2015/03/29 05:52:59 agc Exp $ */
/* $NetBSD: msdosfs_vnops.c,v 1.19 2017/04/13 17:10:12 christos Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -51,7 +51,7 @@
#endif
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.16 2015/03/29 05:52:59 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.19 2017/04/13 17:10:12 christos Exp $");
#include <sys/param.h>
#include <sys/mman.h>
@ -98,12 +98,20 @@ static void
msdosfs_times(struct msdosfsmount *pmp, struct denode *dep,
const struct stat *st)
{
struct timespec at;
struct timespec mt;
if (stampst.st_ino)
st = &stampst;
#ifndef HAVE_NBTOOL_CONFIG_H
struct timespec at = st->st_atimespec;
struct timespec mt = st->st_mtimespec;
at = st->st_atimespec;
mt = st->st_mtimespec;
#else
struct timespec at = { st->st_atime, 0 };
struct timespec mt = { st->st_mtime, 0 };
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);
@ -154,12 +162,12 @@ msdosfs_findslot(struct denode *dp, struct componentname *cnp)
break;
case 2:
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen) + 1;
cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
break;
case 3:
olddos = 0;
wincnt = winSlotCnt((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen) + 1;
cnp->cn_namelen, pmp->pm_flags & MSDOSFSMNT_UTF8) + 1;
break;
}
@ -243,7 +251,8 @@ msdosfs_findslot(struct denode *dp, struct componentname *cnp)
chksum = winChkName((const u_char *)cnp->cn_nameptr,
cnp->cn_namelen,
(struct winentry *)dep,
chksum);
chksum,
pmp->pm_flags & MSDOSFSMNT_UTF8);
continue;
}
@ -431,31 +440,29 @@ msdosfs_wfile(const char *path, struct denode *dep, fsnode *node)
return 0;
/* Don't bother to try to write files larger than the fs limit */
if (st->st_size > MSDOSFS_FILESIZE_MAX) {
errno = EFBIG;
return -1;
}
if (st->st_size > MSDOSFS_FILESIZE_MAX)
return EFBIG;
nsize = st->st_size;
DPRINTF(("%s(nsize=%zu, osize=%zu)\n", __func__, nsize, osize));
if (nsize > osize) {
if ((error = deextend(dep, nsize, NULL)) != 0) {
errno = error;
return -1;
}
if ((error = msdosfs_updatede(dep)) != 0) {
errno = error;
return -1;
}
if ((error = deextend(dep, nsize, NULL)) != 0)
return error;
if ((error = msdosfs_updatede(dep)) != 0)
return error;
}
if ((fd = open(path, O_RDONLY)) == -1)
err(1, "open %s", path);
if ((fd = open(path, O_RDONLY)) == -1) {
error = errno;
DPRINTF((1, "open %s: %s", path, strerror(error)));
return error;
}
if ((dat = mmap(0, nsize, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0))
== MAP_FAILED) {
DPRINTF(("%s: mmap %s %s", __func__, node->name,
strerror(errno)));
error = errno;
DPRINTF(("%s: mmap %s: %s", __func__, node->name,
strerror(error)));
close(fd);
goto out;
}
@ -469,6 +476,7 @@ msdosfs_wfile(const char *path, struct denode *dep, fsnode *node)
cn = dep->de_StartCluster;
if (cn == MSDOSFSROOT) {
DPRINTF(("%s: bad lbn %lu", __func__, cn));
error = EINVAL;
goto out;
}
bn = cntobn(pmp, cn);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udf.c,v 1.17 2015/06/16 23:04:14 christos Exp $ */
/* $NetBSD: udf.c,v 1.21 2020/04/18 12:25:01 martin Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
@ -30,7 +30,7 @@
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: udf.c,v 1.17 2015/06/16 23:04:14 christos Exp $");
__RCSID("$NetBSD: udf.c,v 1.21 2020/04/18 12:25:01 martin Exp $");
#include <stdio.h>
#include <stdlib.h>
@ -201,7 +201,7 @@ udf_emulate_discinfo(fsinfo_t *fsopts, struct mmc_discinfo *di,
case 0x10: /* DVDROM */
case 0x40: /* BDROM */
req_enable |= FORMAT_READONLY;
/* FALLTROUGH */
/* FALLTHROUGH */
case 0x01: /* disc */
/* set up a disc info profile for partitions/files */
di->mmc_class = MMC_CLASS_DISC;
@ -290,9 +290,6 @@ udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti)
void
udf_prep_opts(fsinfo_t *fsopts)
{
struct tm *tm;
time_t now;
const option_t udf_options[] = {
OPT_STR('T', "disctype", "disc type (cdrom,dvdrom,bdrom,"
"dvdram,bdre,disk,cdr,dvdr,bdr,cdrw,dvdrw)"),
@ -330,13 +327,16 @@ udf_prep_opts(fsinfo_t *fsopts)
context.max_udf = 0x201; /* 0x250 and 0x260 are not ready */
/* use user's time zone as default */
(void)time(&now);
tm = localtime(&now);
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
context.gmtoff = tm->tm_gmtoff;
#else
context.gmtoff = 0;
if (!stampst.st_ino) {
struct tm tm;
time_t now;
(void)time(&now);
(void)localtime_r(&now, &tm);
context.gmtoff = tm.tm_gmtoff;
} else
#endif
context.gmtoff = 0;
/* return info */
fsopts->fs_specific = NULL;
@ -514,6 +514,7 @@ static uint32_t
udf_datablocks(off_t sz)
{
/* predictor if it can be written inside the node */
/* XXX the predictor assumes NO extended attributes in the node */
if (sz < context.sector_size - UDF_EXTFENTRY_SIZE - 16)
return 0;
@ -561,7 +562,6 @@ udf_file_inject_blob(union dscrptr *dscr, uint8_t *blob, off_t size)
struct extfile_entry *efe;
uint64_t inf_len, obj_size;
uint32_t l_ea, l_ad;
uint32_t free_space, desc_size;
uint16_t crclen;
uint8_t *data, *pos;
@ -575,7 +575,6 @@ udf_file_inject_blob(union dscrptr *dscr, uint8_t *blob, off_t size)
icb = &fe->icbtag;
inf_len = udf_rw64(fe->inf_len);
obj_size = 0;
desc_size = sizeof(struct file_entry);
} else if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
efe = &dscr->efe;
data = efe->data;
@ -584,39 +583,22 @@ udf_file_inject_blob(union dscrptr *dscr, uint8_t *blob, off_t size)
icb = &efe->icbtag;
inf_len = udf_rw64(efe->inf_len);
obj_size = udf_rw64(efe->obj_size);
desc_size = sizeof(struct extfile_entry);
} else {
errx(1, "Bad tag passed to udf_file_inject_blob");
}
crclen = udf_rw16(dscr->tag.desc_crc_len);
/* calculate free space */
free_space = context.sector_size - (l_ea + l_ad) - desc_size;
/* check if it will fit internally */
if (udf_datablocks(size)) {
#if !defined(NDEBUG) && defined(__minix)
assert(free_space < size);
#else
if (!(free_space < size)) {
printf("%s:%d not enough free space\n", __FILE__, __LINE__);
abort();
}
#endif /* !defined(NDEBUG) && defined(__minix) */
/* the predictor tells it won't fit internally */
return 1;
}
/* going internal */
assert(l_ad == 0);
#if !defined(NDEBUG) && defined(__minix)
assert((udf_rw16(icb->flags) & UDF_ICB_TAG_FLAGS_ALLOC_MASK) ==
UDF_ICB_INTERN_ALLOC);
#else
if (!((udf_rw16(icb->flags) & UDF_ICB_TAG_FLAGS_ALLOC_MASK) == UDF_ICB_INTERN_ALLOC)) {
printf("%s:%d: allocation flags mismatch\n", __FILE__, __LINE__);
abort();
}
#endif /* !defined(NDEBUG) && defined(__minix) */
// assert(free_space >= size);
pos = data + l_ea + l_ad;
memcpy(pos, blob, size);
l_ad += size;
@ -704,14 +686,7 @@ udf_append_file_mapping(union dscrptr *dscr, struct long_ad *piece)
last_long = NULL;
if (l_ad != 0) {
if (use_shorts) {
#if !defined(NDEBUG) && defined(__minix)
assert(cur_alloc == UDF_ICB_SHORT_ALLOC);
#else
if (!(cur_alloc == UDF_ICB_SHORT_ALLOC)) {
printf("%s:%d: Expecting UDF_ICB_SHORT_ALLOC allocation\n", __FILE__, __LINE__);
abort();
}
#endif /* !defined(NDEBUG) && defined(__minix) */
pos += l_ad - short_len;
last_short = (struct short_ad *) pos;
last_lb_num = udf_rw32(last_short->lb_num);
@ -719,14 +694,7 @@ udf_append_file_mapping(union dscrptr *dscr, struct long_ad *piece)
last_len = UDF_EXT_LEN(udf_rw32(last_short->len));
last_flags = UDF_EXT_FLAGS(udf_rw32(last_short->len));
} else {
#if !defined(NDEBUG) && defined(__minix)
assert(cur_alloc == UDF_ICB_LONG_ALLOC);
#else
if (!(cur_alloc == UDF_ICB_LONG_ALLOC)) {
printf("%s:%d: Expecting UDF_ICB_LONG_ALLOC allocation\n", __FILE__, __LINE__);
abort();
}
#endif /* !defined(NDEBUG) && defined(__minix) */
pos += l_ad - long_len;
last_long = (struct long_ad *) pos;
last_lb_num = udf_rw32(last_long->loc.lb_num);
@ -906,6 +874,7 @@ udf_estimate_walk(fsinfo_t *fsopts,
case S_IFDIR:
if (strcmp(cur->name, ".") == 0)
continue;
/* FALLTHROUGH */
case S_IFLNK:
case S_IFREG:
/* create dummy FID to see how long name will become */

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.2 2013/08/05 18:45:00 reinoud Exp $
# $NetBSD: Makefile.inc,v 1.4 2020/09/06 07:20:31 mrg Exp $
#
UDF= ${NETBSDSRCDIR}/sys/fs/udf
@ -11,3 +11,7 @@ CPPFLAGS+= -I${UDF} -I${UDF_NEWFS} -I${FSCK}
SRCS += udf_create.c udf_write.c udf_osta.c
.if !defined(__MINIX)
CWARNFLAGS.clang+= -Wno-error=address-of-packed-member -Wno-error=constant-conversion
.endif # !defined(__MINIX)
CWARNFLAGS.gcc+= ${GCC_NO_ADDR_OF_PACKED_MEMBER}

View File

@ -132,10 +132,6 @@ estimate_size_walk(fsnode *root, char *dir, struct v7fs_geometry *geom)
int n;
off_t sz;
#if defined(__minix)
/* LSC: -Werror=maybe-uninitialized, when compiling with -O3. */
nblk = 0;
#endif /* defined(__minix) */
for (cur = root, nentries = 0; cur != NULL; cur = cur->next,
nentries++, geom->ninode++) {
switch (cur->type & S_IFMT) {
@ -261,10 +257,6 @@ v7fs_estimate(const char *dir, fsnode *root, fsinfo_t *fsopts)
v7fs_daddr_t nblk;
struct v7fs_geometry geom;
#if defined(__minix)
/* LSC: -Werror=maybe-uninitialized, when compiling with -O3. */
nblk = 0;
#endif /* defined(__minix) */
memset(&geom , 0, sizeof(geom));
strncpy(path, dir, sizeof(path));

View File

@ -1,4 +1,4 @@
/* $NetBSD: walk.c,v 1.28 2013/02/03 06:16:53 christos Exp $ */
/* $NetBSD: walk.c,v 1.29 2015/11/25 00:48:49 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: walk.c,v 1.28 2013/02/03 06:16:53 christos Exp $");
__RCSID("$NetBSD: walk.c,v 1.29 2015/11/25 00:48:49 christos Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -252,6 +252,20 @@ create_fsnode(const char *root, const char *path, const char *name,
cur->type = stbuf->st_mode & S_IFMT;
cur->inode->nlink = 1;
cur->inode->st = *stbuf;
if (stampst.st_ino) {
cur->inode->st.st_atime = stampst.st_atime;
cur->inode->st.st_mtime = stampst.st_mtime;
cur->inode->st.st_ctime = stampst.st_ctime;
#if HAVE_STRUCT_STAT_ST_MTIMENSEC
cur->inode->st.st_atimensec = stampst.st_atimensec;
cur->inode->st.st_mtimensec = stampst.st_mtimensec;
cur->inode->st.st_ctimensec = stampst.st_ctimensec;
#endif
#if HAVE_STRUCT_STAT_BIRTHTIME
cur->inode->st.st_birthtime = stampst.st_birthtime;
cur->inode->st.st_birthtimensec = stampst.st_birthtimensec;
#endif
}
return (cur);
}