usr.sbin/makefs: Synchronize on NetBSD-current (30/03/2021 16:09 UTC)
This commit is contained in:
parent
fd1285b2ec
commit
ba797217b8
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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), \
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
965
sys/fs/msdosfs/msdosfs_unicode.c
Normal file
965
sys/fs/msdosfs/msdosfs_unicode.c
Normal 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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]) )
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user