17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0e42dee6Sartem * Common Development and Distribution License (the "License"). 6*0e42dee6Sartem * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*0e42dee6Sartem * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_FS_PC_FS_H 277c478bd9Sstevel@tonic-gate #define _SYS_FS_PC_FS_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/thread.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifdef __cplusplus 347c478bd9Sstevel@tonic-gate extern "C" { 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate typedef uint16_t pc_cluster16_t; 387c478bd9Sstevel@tonic-gate typedef uint32_t pc_cluster32_t; 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * PC (MSDOS) compatible virtual file system. 427c478bd9Sstevel@tonic-gate * 437c478bd9Sstevel@tonic-gate * A main goal of the implementation was to maintain statelessness 447c478bd9Sstevel@tonic-gate * except while files are open. Thus mounting and unmounting merely 457c478bd9Sstevel@tonic-gate * declared the file system name. The user may change disks at almost 467c478bd9Sstevel@tonic-gate * any time without concern (just like the PC). It is assumed that when 477c478bd9Sstevel@tonic-gate * files are open for writing the disk access light will be on, as a 487c478bd9Sstevel@tonic-gate * warning not to change disks. The implementation must, however, detect 497c478bd9Sstevel@tonic-gate * disk change and recover gracefully. It does this by comparing the 507c478bd9Sstevel@tonic-gate * in core entry for a directory to the on disk entry whenever a directory 517c478bd9Sstevel@tonic-gate * is searched. If a discrepancy is found active directories become root and 527c478bd9Sstevel@tonic-gate * active files are marked invalid. 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * There are only two type of nodes on the PC file system; files and 557c478bd9Sstevel@tonic-gate * directories. These are represented by two separate vnode op vectors, 567c478bd9Sstevel@tonic-gate * and they are kept in two separate tables. Files are known by the 577c478bd9Sstevel@tonic-gate * disk block number and block (cluster) offset of the files directory 587c478bd9Sstevel@tonic-gate * entry. Directories are known by the starting cluster number. 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate * The file system is locked for during each user operation. This is 617c478bd9Sstevel@tonic-gate * done to simplify disk verification error conditions. 627c478bd9Sstevel@tonic-gate * 637c478bd9Sstevel@tonic-gate * Notes on FAT32 support 647c478bd9Sstevel@tonic-gate * ---------------------- 657c478bd9Sstevel@tonic-gate * The basic difference between FAT32 and FAT16 is that cluster numbers are now 667c478bd9Sstevel@tonic-gate * 32-bit instead of 16-bit. The FAT is thus an array of 32-bit cluster numbers, 677c478bd9Sstevel@tonic-gate * and because of this the cluster size can be much smaller on a large disk 687c478bd9Sstevel@tonic-gate * (4k, say, on a 1 Gig drive instead of 16k). Unfortunately, the FAT is not 697c478bd9Sstevel@tonic-gate * the only place cluster numbers are stored - the starting cluster is stored 707c478bd9Sstevel@tonic-gate * in the directory entry for a file, and of course it's only 16-bit. Luckily, 717c478bd9Sstevel@tonic-gate * there's a 16-bit OS/2 Extended Attribute field that is now used to store the 727c478bd9Sstevel@tonic-gate * upper 16-bits of the starting cluster number. 737c478bd9Sstevel@tonic-gate * 747c478bd9Sstevel@tonic-gate * Most of the FAT32 changes to pcfs are under 'if it's FAT32' to minimize the 757c478bd9Sstevel@tonic-gate * effect on non-FAT32 filesystems (and still share the code), except for the 767c478bd9Sstevel@tonic-gate * starting cluster changes. It seemed easier to make common functions to 777c478bd9Sstevel@tonic-gate * handle that. 787c478bd9Sstevel@tonic-gate * 797c478bd9Sstevel@tonic-gate * Other changes: 807c478bd9Sstevel@tonic-gate * 817c478bd9Sstevel@tonic-gate * 1. FAT32 partitions are indicated by partition types 0xB and 0xC. 827c478bd9Sstevel@tonic-gate * 2. The boot sector is now 2 sectors, to make room for FAT32 extensions. 837c478bd9Sstevel@tonic-gate * 3. The root directory is no longer stored in a fixed location. Its' 847c478bd9Sstevel@tonic-gate * starting cluster is stored in the extended boot sector. 857c478bd9Sstevel@tonic-gate * 4. "Summary information" is now stored and we need to (at least) maintain 867c478bd9Sstevel@tonic-gate * the number of free clusters or scandisk will be upset. Though the 877c478bd9Sstevel@tonic-gate * sector this info is in is pointed to by the extensions in the boot 887c478bd9Sstevel@tonic-gate * sector, the magic offset of this information is just that so 897c478bd9Sstevel@tonic-gate * far - magic. 0x1e0. 907c478bd9Sstevel@tonic-gate * 5. FAT32 can use the alternate FAT. But we don't. 917c478bd9Sstevel@tonic-gate * 927c478bd9Sstevel@tonic-gate * FAT32 also exposed a latent bug: we bread() each copy of the FAT in one 937c478bd9Sstevel@tonic-gate * big chunk. This is not good on a large FAT32 drive, such as a 1 Gig 947c478bd9Sstevel@tonic-gate * Jaz drive that has 4k clusters, since the FAT becomes 1 Meg in size and 957c478bd9Sstevel@tonic-gate * bread blocks forever. So now we read the FAT in chunks. 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * pre-FAT32 boot sector. 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate struct bootsec { 1027c478bd9Sstevel@tonic-gate uchar_t instr[3]; 1037c478bd9Sstevel@tonic-gate uchar_t version[8]; 1047c478bd9Sstevel@tonic-gate uchar_t bps[2]; /* bytes per sector */ 1057c478bd9Sstevel@tonic-gate uchar_t spcl; /* sectors per allocation unit */ 1067c478bd9Sstevel@tonic-gate uchar_t res_sec[2]; /* reserved sectors, starting at 0 */ 1077c478bd9Sstevel@tonic-gate uchar_t nfat; /* number of FATs */ 1087c478bd9Sstevel@tonic-gate uchar_t rdirents[2]; /* number of root directory entries */ 1097c478bd9Sstevel@tonic-gate uchar_t numsect[2]; /* old total sectors in logical image */ 1107c478bd9Sstevel@tonic-gate uchar_t mediadesriptor; /* media descriptor byte */ 111*0e42dee6Sartem ushort_t fatsec; /* number of sectors per FAT */ 1127c478bd9Sstevel@tonic-gate ushort_t spt; /* sectors per track */ 1137c478bd9Sstevel@tonic-gate ushort_t nhead; /* number of heads */ 114*0e42dee6Sartem uint_t hiddensec; /* number of hidden sectors */ 1157c478bd9Sstevel@tonic-gate uint_t totalsec; /* total sectors in logical image */ 1167c478bd9Sstevel@tonic-gate }; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* 1197c478bd9Sstevel@tonic-gate * FAT32 volumes have a bigger boot sector. They include the normal 1207c478bd9Sstevel@tonic-gate * boot sector. 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate struct fat32_bootsec { 1237c478bd9Sstevel@tonic-gate struct bootsec f_bs; 1247c478bd9Sstevel@tonic-gate uint32_t f_fatlength; /* size of FAT */ 1257c478bd9Sstevel@tonic-gate uint16_t f_flags; 1267c478bd9Sstevel@tonic-gate uint8_t f_major; /* major filesystem version #? */ 1277c478bd9Sstevel@tonic-gate uint8_t f_minor; /* minor filesystem version #? */ 1287c478bd9Sstevel@tonic-gate uint32_t f_rootcluster; /* first cluster in root directory */ 1297c478bd9Sstevel@tonic-gate uint16_t f_infosector; /* where summary info is */ 1307c478bd9Sstevel@tonic-gate uint16_t f_backupboot; /* backup boot sector */ 1317c478bd9Sstevel@tonic-gate uint16_t f_reserved2[6]; 1327c478bd9Sstevel@tonic-gate }; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate #define FAT32_FS_SIGN 0x61417272 1357c478bd9Sstevel@tonic-gate #define FAT32_BOOT_FSINFO_OFF 0x1e0 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* 1387c478bd9Sstevel@tonic-gate * summary information for fat32 volumes. We need to maintain fs_free_clusters 1397c478bd9Sstevel@tonic-gate * or Microsoft Scandisk will be upset. 1407c478bd9Sstevel@tonic-gate */ 1417c478bd9Sstevel@tonic-gate struct fat32_boot_fsinfo { 1427c478bd9Sstevel@tonic-gate uint32_t fs_reserved1; 1437c478bd9Sstevel@tonic-gate uint32_t fs_signature; /* 0x61417272 */ 1447c478bd9Sstevel@tonic-gate uint32_t fs_free_clusters; /* # free clusters. -1 if unknown */ 1457c478bd9Sstevel@tonic-gate uint32_t fs_next_cluster; /* unused by pcfs */ 1467c478bd9Sstevel@tonic-gate uint32_t fs_reserved2[4]; 1477c478bd9Sstevel@tonic-gate }; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate #define FSINFO_UNKNOWN (-1) 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate struct pcfs { 1527c478bd9Sstevel@tonic-gate struct vfs *pcfs_vfs; /* vfs for this fs */ 1537c478bd9Sstevel@tonic-gate int pcfs_flags; /* flags */ 1547c478bd9Sstevel@tonic-gate int pcfs_ldrv; /* logical DOS drive number */ 1557c478bd9Sstevel@tonic-gate dev_t pcfs_xdev; /* actual device that is mounted */ 1567c478bd9Sstevel@tonic-gate struct vnode *pcfs_devvp; /* and a vnode for it */ 1577c478bd9Sstevel@tonic-gate int pcfs_secsize; /* sector size in bytes */ 1587c478bd9Sstevel@tonic-gate int pcfs_spcl; /* sectors per cluster */ 1597c478bd9Sstevel@tonic-gate int pcfs_spt; /* sectors per track */ 1607c478bd9Sstevel@tonic-gate int pcfs_sdshift; /* shift to convert sector into */ 1617c478bd9Sstevel@tonic-gate /* DEV_BSIZE "sectors"; assume */ 1627c478bd9Sstevel@tonic-gate /* pcfs_secsize is 2**n times of */ 1637c478bd9Sstevel@tonic-gate /* DEV_BSIZE */ 1647c478bd9Sstevel@tonic-gate int pcfs_fatsec; /* number of sec per FAT */ 1657c478bd9Sstevel@tonic-gate int pcfs_numfat; /* number of FAT copies */ 1667c478bd9Sstevel@tonic-gate int pcfs_rdirsec; /* number of sec in root dir */ 1677c478bd9Sstevel@tonic-gate daddr_t pcfs_dosstart; /* start blkno of DOS partition */ 1687c478bd9Sstevel@tonic-gate daddr_t pcfs_fatstart; /* start blkno of first FAT */ 1697c478bd9Sstevel@tonic-gate daddr_t pcfs_rdirstart; /* start blkno of root dir */ 1707c478bd9Sstevel@tonic-gate daddr_t pcfs_datastart; /* start blkno of data area */ 1717c478bd9Sstevel@tonic-gate int pcfs_clsize; /* cluster size in bytes */ 1727c478bd9Sstevel@tonic-gate int pcfs_ncluster; /* number of clusters in fs */ 1737c478bd9Sstevel@tonic-gate int pcfs_entps; /* number of dir entry per sector */ 1747c478bd9Sstevel@tonic-gate int pcfs_nrefs; /* number of active pcnodes */ 1757c478bd9Sstevel@tonic-gate int pcfs_frefs; /* number of active file pcnodes */ 1767c478bd9Sstevel@tonic-gate int pcfs_nxfrecls; /* next free cluster */ 1777c478bd9Sstevel@tonic-gate uchar_t *pcfs_fatp; /* ptr to FAT data */ 1787c478bd9Sstevel@tonic-gate uchar_t *pcfs_fat_changemap; /* map of changed fat data */ 1797c478bd9Sstevel@tonic-gate int pcfs_fatsize; /* size of FAT data */ 1807c478bd9Sstevel@tonic-gate int pcfs_fat_changemapsize; /* size of FAT changemap */ 1817c478bd9Sstevel@tonic-gate time_t pcfs_fattime; /* time FAT becomes invalid */ 1827c478bd9Sstevel@tonic-gate time_t pcfs_verifytime; /* time to reverify disk */ 1837c478bd9Sstevel@tonic-gate kmutex_t pcfs_lock; /* per filesystem lock */ 1847c478bd9Sstevel@tonic-gate kthread_id_t pcfs_owner; /* id of thread locking pcfs */ 1857c478bd9Sstevel@tonic-gate int pcfs_count; /* # of pcfs locks for pcfs_owner */ 1867c478bd9Sstevel@tonic-gate struct fat32_boot_fsinfo fsinfo_native; /* native fsinfo for fat32 */ 1877c478bd9Sstevel@tonic-gate uint32_t f32fsinfo_sector; /* where to read/write fsinfo */ 1887c478bd9Sstevel@tonic-gate struct pcfs *pcfs_nxt; /* linked list of all mounts */ 1897c478bd9Sstevel@tonic-gate int pcfs_fatjustread; /* Used to flag a freshly found FAT */ 1907c478bd9Sstevel@tonic-gate }; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate /* 1937c478bd9Sstevel@tonic-gate * flags 1947c478bd9Sstevel@tonic-gate */ 1957c478bd9Sstevel@tonic-gate #define PCFS_FATMOD 0x01 /* FAT has been modified */ 1967c478bd9Sstevel@tonic-gate #define PCFS_LOCKED 0x02 /* fs is locked */ 1977c478bd9Sstevel@tonic-gate #define PCFS_WANTED 0x04 /* locked fs is wanted */ 1987c478bd9Sstevel@tonic-gate #define PCFS_FAT16 0x400 /* 16 bit FAT */ 1997c478bd9Sstevel@tonic-gate #define PCFS_NOCHK 0x800 /* don't resync fat on error */ 2007c478bd9Sstevel@tonic-gate #define PCFS_BOOTPART 0x1000 /* boot partition type */ 2017c478bd9Sstevel@tonic-gate #define PCFS_HIDDEN 0x2000 /* show hidden files */ 2027c478bd9Sstevel@tonic-gate #define PCFS_PCMCIA_NO_CIS 0x4000 /* PCMCIA psuedo floppy */ 2037c478bd9Sstevel@tonic-gate #define PCFS_FOLDCASE 0x8000 /* fold all names from media to */ 2047c478bd9Sstevel@tonic-gate /* lowercase */ 2057c478bd9Sstevel@tonic-gate #define PCFS_FAT32 0x10000 /* 32 bit FAT */ 2067c478bd9Sstevel@tonic-gate #define PCFS_IRRECOV 0x20000 /* FS was messed with during write */ 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate /* for compatibility */ 2097c478bd9Sstevel@tonic-gate struct old_pcfs_args { 2107c478bd9Sstevel@tonic-gate int secondswest; /* seconds west of Greenwich */ 2117c478bd9Sstevel@tonic-gate int dsttime; /* type of dst correction */ 2127c478bd9Sstevel@tonic-gate }; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate struct pcfs_args { 2157c478bd9Sstevel@tonic-gate int secondswest; /* seconds west of Greenwich */ 2167c478bd9Sstevel@tonic-gate int dsttime; /* type of dst correction */ 2177c478bd9Sstevel@tonic-gate int flags; 2187c478bd9Sstevel@tonic-gate }; 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate /* 2217c478bd9Sstevel@tonic-gate * flags for the pcfs_args 'flags' field. 2227c478bd9Sstevel@tonic-gate * 22343893bfeSmm * Note that these two macros are obsolete - do not use them. 2247c478bd9Sstevel@tonic-gate */ 2257c478bd9Sstevel@tonic-gate #define PCFS_MNT_HIDDEN 0x01 /* show hidden files */ 2267c478bd9Sstevel@tonic-gate #define PCFS_MNT_FOLDCASE 0x02 /* fold all names from media to */ 2277c478bd9Sstevel@tonic-gate /* lowercase */ 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate /* 2307c478bd9Sstevel@tonic-gate * pcfs mount options. 2317c478bd9Sstevel@tonic-gate */ 2327c478bd9Sstevel@tonic-gate #define MNTOPT_PCFS_HIDDEN "hidden" 2337c478bd9Sstevel@tonic-gate #define MNTOPT_PCFS_NOHIDDEN "nohidden" 2347c478bd9Sstevel@tonic-gate #define MNTOPT_PCFS_FOLDCASE "foldcase" 2357c478bd9Sstevel@tonic-gate #define MNTOPT_PCFS_NOFOLDCASE "nofoldcase" 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * Disk timeout value in sec. 2397c478bd9Sstevel@tonic-gate * This is used to time out the in core FAT and to re-verify the disk. 2407c478bd9Sstevel@tonic-gate * This should be less than the time it takes to change floppys 2417c478bd9Sstevel@tonic-gate */ 2427c478bd9Sstevel@tonic-gate #define PCFS_DISKTIMEOUT 2 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate #define VFSTOPCFS(VFSP) ((struct pcfs *)((VFSP)->vfs_data)) 2457c478bd9Sstevel@tonic-gate #define PCFSTOVFS(FSP) ((FSP)->pcfs_vfs) 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate /* 2487c478bd9Sstevel@tonic-gate * special cluster numbers in FAT 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate #define PCF_FREECLUSTER 0x00 /* cluster is available */ 2517c478bd9Sstevel@tonic-gate #define PCF_ERRORCLUSTER 0x01 /* error occurred allocating cluster */ 2527c478bd9Sstevel@tonic-gate #define PCF_12BCLUSTER 0xFF0 /* 12-bit version of reserved cluster */ 2537c478bd9Sstevel@tonic-gate #define PCF_RESCLUSTER 0xFFF0 /* 16-bit version of reserved cluster */ 2547c478bd9Sstevel@tonic-gate #define PCF_RESCLUSTER32 0xFFFFFF0 /* 32-bit version */ 2557c478bd9Sstevel@tonic-gate #define PCF_BADCLUSTER 0xFFF7 /* bad cluster, do not use */ 2567c478bd9Sstevel@tonic-gate #define PCF_BADCLUSTER32 0xFFFFFF7 /* 32-bit version */ 2577c478bd9Sstevel@tonic-gate #define PCF_LASTCLUSTER 0xFFF8 /* >= means last cluster in file */ 2587c478bd9Sstevel@tonic-gate #define PCF_LASTCLUSTER32 0xFFFFFF8 /* 32-bit version */ 2597c478bd9Sstevel@tonic-gate #define PCF_LASTCLUSTERMARK 0xFFFF /* value used to mark last cluster */ 2607c478bd9Sstevel@tonic-gate #define PCF_LASTCLUSTERMARK32 0xFFFFFFF /* 32-bit version */ 2617c478bd9Sstevel@tonic-gate #define PCF_FIRSTCLUSTER 2 /* first valid cluster number */ 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * file system constants 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate #define PC_MAXFATSEC 256 /* maximum number of sectors in FAT */ 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* 2697c478bd9Sstevel@tonic-gate * file system parameter macros 2707c478bd9Sstevel@tonic-gate */ 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate #define IS_FAT32(PCFS) \ 2737c478bd9Sstevel@tonic-gate (((PCFS)->pcfs_flags & PCFS_FAT32) == PCFS_FAT32) 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate #define IS_FAT16(PCFS) \ 2767c478bd9Sstevel@tonic-gate (((PCFS)->pcfs_flags & PCFS_FAT16) == PCFS_FAT16) 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate #define IS_FAT12(PCFS) \ 2797c478bd9Sstevel@tonic-gate (((PCFS)->pcfs_flags & (PCFS_FAT16 | PCFS_FAT32)) == 0) 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate #define pc_clear_fatchanges(PCFS) \ 2827c478bd9Sstevel@tonic-gate bzero((PCFS)->pcfs_fat_changemap, (PCFS)->pcfs_fat_changemapsize) 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate #define pc_blksize(PCFS, PCP, OFF) /* file system block size */ \ 2857c478bd9Sstevel@tonic-gate (((PCTOV(PCP)->v_flag & VROOT) && !IS_FAT32(PCFS)) ? \ 2867c478bd9Sstevel@tonic-gate ((OFF) >= \ 2877c478bd9Sstevel@tonic-gate ((PCFS)->pcfs_rdirsec & \ 2887c478bd9Sstevel@tonic-gate ~((PCFS)->pcfs_spcl - 1)) * ((PCFS)->pcfs_secsize)? \ 2897c478bd9Sstevel@tonic-gate ((PCFS)->pcfs_rdirsec & \ 2907c478bd9Sstevel@tonic-gate ((PCFS)->pcfs_spcl - 1)) * ((PCFS)->pcfs_secsize): \ 2917c478bd9Sstevel@tonic-gate (PCFS)->pcfs_clsize): \ 2927c478bd9Sstevel@tonic-gate (PCFS)->pcfs_clsize) 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate #define pc_blkoff(PCFS, OFF) /* offset within block */ \ 2957c478bd9Sstevel@tonic-gate ((int)((OFF) & ((PCFS)->pcfs_clsize - 1))) 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate #define pc_lblkno(PCFS, OFF) /* logical block (cluster) no */ \ 2987c478bd9Sstevel@tonic-gate ((daddr_t)((OFF) / (PCFS)->pcfs_clsize)) 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate #define pc_dbtocl(PCFS, DB) /* disk blks to clusters */ \ 3017c478bd9Sstevel@tonic-gate ((int)((DB) / (PCFS)->pcfs_spcl)) 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate #define pc_cltodb(PCFS, CL) /* clusters to disk blks */ \ 3047c478bd9Sstevel@tonic-gate ((daddr_t)((CL) * (PCFS)->pcfs_spcl)) 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate #define pc_cldaddr(PCFS, CL) /* DEV_BSIZE "sector" addr for cluster */ \ 3077c478bd9Sstevel@tonic-gate (((daddr_t)((PCFS)->pcfs_datastart + \ 3087c478bd9Sstevel@tonic-gate ((CL) - PCF_FIRSTCLUSTER) * (PCFS)->pcfs_spcl)) << \ 3097c478bd9Sstevel@tonic-gate (PCFS)->pcfs_sdshift) 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate #define pc_daddrcl(PCFS, DADDR) /* cluster for disk address */ \ 3127c478bd9Sstevel@tonic-gate ((int)(((((DADDR) >> (PCFS)->pcfs_sdshift) - (PCFS)->pcfs_datastart) / \ 3137c478bd9Sstevel@tonic-gate (PCFS)->pcfs_spcl) + 2)) 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate #define pc_dbdaddr(PCFS, DB) /* sector to DEV_BSIZE "sector" addr */ \ 3167c478bd9Sstevel@tonic-gate ((DB) << (PCFS)->pcfs_sdshift) 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate #define pc_daddrdb(PCFS, DADDR) /* DEV_BSIZE "sector" addr to sector addr */ \ 3197c478bd9Sstevel@tonic-gate ((DADDR) >> (PCFS)->pcfs_sdshift) 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate #define pc_validcl(PCFS, CL) /* check that cluster no is legit */ \ 3227c478bd9Sstevel@tonic-gate ((int)(CL) >= PCF_FIRSTCLUSTER && \ 3237c478bd9Sstevel@tonic-gate (int)(CL) <= (PCFS)->pcfs_ncluster) 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * external routines. 3277c478bd9Sstevel@tonic-gate */ 3287c478bd9Sstevel@tonic-gate extern int pc_lockfs(struct pcfs *, int, int); /* lock fs and get fat */ 3297c478bd9Sstevel@tonic-gate extern void pc_unlockfs(struct pcfs *); /* ulock the fs */ 3307c478bd9Sstevel@tonic-gate extern int pc_getfat(struct pcfs *); /* get fat from disk */ 3317c478bd9Sstevel@tonic-gate extern void pc_invalfat(struct pcfs *); /* invalidate incore fat */ 3327c478bd9Sstevel@tonic-gate extern int pc_syncfat(struct pcfs *); /* sync fat to disk */ 3337c478bd9Sstevel@tonic-gate extern int pc_freeclusters(struct pcfs *); /* num free clusters in fs */ 3347c478bd9Sstevel@tonic-gate extern pc_cluster32_t pc_alloccluster(struct pcfs *, int); 3357c478bd9Sstevel@tonic-gate extern void pc_setcluster(struct pcfs *, pc_cluster32_t, pc_cluster32_t); 3367c478bd9Sstevel@tonic-gate extern void pc_mark_fat_updated(struct pcfs *fsp, pc_cluster32_t cn); 3377c478bd9Sstevel@tonic-gate extern int pc_fat_is_changed(struct pcfs *fsp, pc_cluster32_t bn); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* 3407c478bd9Sstevel@tonic-gate * debugging 3417c478bd9Sstevel@tonic-gate */ 3427c478bd9Sstevel@tonic-gate extern int pcfsdebuglevel; 3437c478bd9Sstevel@tonic-gate #define PC_DPRINTF0(level, A) \ 3447c478bd9Sstevel@tonic-gate if (pcfsdebuglevel >= level) \ 3457c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, (A)) 3467c478bd9Sstevel@tonic-gate #define PC_DPRINTF1(level, A, B) \ 3477c478bd9Sstevel@tonic-gate if (pcfsdebuglevel >= level) \ 3487c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, (A), (B)) 3497c478bd9Sstevel@tonic-gate #define PC_DPRINTF2(level, A, B, C) \ 3507c478bd9Sstevel@tonic-gate if (pcfsdebuglevel >= level) \ 3517c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, (A), (B), (C)) 3527c478bd9Sstevel@tonic-gate #define PC_DPRINTF3(level, A, B, C, D) \ 3537c478bd9Sstevel@tonic-gate if (pcfsdebuglevel >= level) \ 3547c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, (A), (B), (C), (D)) 3557c478bd9Sstevel@tonic-gate #define PC_DPRINTF4(level, A, B, C, D, E) \ 3567c478bd9Sstevel@tonic-gate if (pcfsdebuglevel >= level) \ 3577c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, (A), (B), (C), (D), (E)) 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate #ifdef __cplusplus 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate #endif 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate #endif /* _SYS_FS_PC_FS_H */ 364