1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1999,2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #ifndef _FSCK_PCFS_H 28 #define _FSCK_PCFS_H 29 30 /* 31 * Structures used by the pcfs file system checker. 32 */ 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 #include <sys/types.h> 39 40 /* 41 * The root directory of FAT12/16 file systems doesn't sit in 42 * a cluster. 43 */ 44 #define FAKE_ROOTDIR_CLUST -1 45 46 /* 47 * The first available cluster number for a FAT fs is always the same, 2. 48 */ 49 #define FIRST_CLUSTER 2 50 51 #define RETURN_ON_OPEN_FAILURE 0 52 #define EXIT_ON_OPEN_FAILURE 1 53 54 #define NO_FAT_IN_SUMMARY 0 55 #define INCLUDE_FAT_IN_SUMMARY 1 56 57 #define RDCLUST_DONT_CACHE 0 58 #define RDCLUST_DO_CACHE 1 59 60 /* 61 * Return values for sanityCheckSize() 62 */ 63 #define SIZE_MATCHED 0 64 #define TRUNCATED 1 65 66 #define RDCLUST_MAX_RETRY 3 67 #define RDCLUST_GOOD 0 68 #define RDCLUST_FAIL -1 69 #define RDCLUST_MEMERR -2 70 #define RDCLUST_BADINPUT -3 71 72 typedef union clustDataTypes { 73 struct pcdir *dirp; 74 uchar_t *bytes; 75 } ClusterContents; 76 77 struct cached { 78 int32_t clusterNum; 79 ClusterContents clusterData; 80 short modified; 81 struct cached *next; 82 }; 83 84 typedef struct cached CachedCluster; 85 86 struct nameinfo { 87 char *fullName; 88 int references; 89 }; 90 91 /* 92 * This structure is shared between all structures belonging to 93 * a single file. The refcnt is a 24 bit integer, that should be 94 * sufficient for 4GB files, even when someone uses 256 byte clusters 95 * (4K is the typical cluster size, 512 bytes is probably the minimum) 96 * The inefficiency of using a bit field is compensated by the memory 97 * savings and prevented paging on large filesystems. 98 */ 99 struct clinfo { 100 struct pcdir *dirent; 101 union { 102 struct clinfo *_nextfree; 103 struct pcdir *_longent; 104 } _unionelem; 105 int32_t longEntStartClust; 106 int refcnt:24; 107 uint_t flags:8; 108 uchar_t *saved; 109 struct nameinfo *path; 110 }; 111 112 /* 113 * #define dirent conflicts with other dirent uses, so we used the 114 * second element instead of the first one one as union for the free 115 * list 116 */ 117 #define longent _unionelem._longent 118 #define nextfree _unionelem._nextfree 119 120 typedef struct clinfo ClusterInfo; 121 122 /* 123 * Return values for allocInUse 124 */ 125 #define CLINFO_PREVIOUSLY_ALLOCED 1 126 #define CLINFO_NEWLY_ALLOCED 0 127 128 #define CLINFO_BAD 0x1 129 #define CLINFO_ORPHAN 0x2 130 #define CLINFO_HIDDEN 0x4 131 132 /* 133 * Traversal operations for wandering the file system metadata 134 */ 135 #define PCFS_NO_SUBDIRS 0 136 #define PCFS_VISIT_SUBDIRS 1 137 138 #define PCFS_TRAVERSE_ALL 1 /* visit all nodes */ 139 #define PCFS_FIND_ATTR 2 /* search for matching attribute */ 140 #define PCFS_FIND_STATUS 3 /* search for same status */ 141 #define PCFS_FIND_CHKS 4 /* find FILENNNN.CHK files */ 142 143 /* 144 * Booleans for markInUse, whether or not file is marked hidden. 145 */ 146 #define VISIBLE 0 147 #define HIDDEN 1 148 149 /* 150 * Indices for various parts of the FILEnnnn.CHK name 151 */ 152 #define CHKNAME_F 0 153 #define CHKNAME_I 1 154 #define CHKNAME_L 2 155 #define CHKNAME_E 3 156 #define CHKNAME_THOUSANDS 4 157 #define CHKNAME_HUNDREDS 5 158 #define CHKNAME_TENS 6 159 #define CHKNAME_ONES 7 160 #define CHKNAME_C 0 161 #define CHKNAME_H 1 162 #define CHKNAME_K 2 163 164 /* 165 * Largest value that will fit into our lost+found naming scheme of 166 * FILEnnnn.CHK. 167 */ 168 #define MAXCHKVAL 9999 169 170 /* 171 * Function prototypes 172 */ 173 extern struct pcdir *addRootDirEnt(int fd, struct pcdir *copyme); 174 extern struct pcdir *newDirEnt(struct pcdir *copyme); 175 extern int32_t extractStartCluster(struct pcdir *dp); 176 extern int32_t findImpactedCluster(struct pcdir *modified); 177 extern int32_t readFATEntry(int32_t currentCluster); 178 extern uint32_t extractSize(struct pcdir *dp); 179 extern int32_t nextInChain(int32_t currentCluster); 180 extern char *nextAvailableCHKName(int *chosen); 181 extern void truncChainWithBadCluster(int fd, struct pcdir *dp, 182 int32_t startCluster); 183 extern void mountSanityCheckFails(void); 184 extern void markClusterModified(int32_t clusterNum); 185 extern void scanAndFixMetadata(int fd); 186 extern void updateDirEnt_Start(struct pcdir *dp, int32_t newStart); 187 extern void addEntryToCHKList(int chkNumber); 188 extern void createCHKNameList(int fd); 189 extern void updateDirEnt_Name(struct pcdir *dp, char *newName); 190 extern void updateDirEnt_Size(struct pcdir *dp, uint32_t newSize); 191 extern void getRootDirectory(int fd); 192 extern void writeClusterMods(int fd); 193 extern void writeRootDirMods(int fd); 194 extern void traverseFromRoot(int fd, int depth, int descend, int operation, 195 char matchRequired, struct pcdir **found, int32_t *lastDirCluster, 196 struct pcdir **dirEnd, char *recordPath, int *pathLen); 197 extern void findBadClusters(int fd); 198 extern void markFreeInFAT(int32_t clusterNum); 199 extern void markLastInFAT(int32_t clusterNum); 200 extern void writeFATEntry(int32_t currentCluster, int32_t value); 201 extern void markBadInFAT(int32_t clusterNum); 202 extern void printSummary(FILE *outDest); 203 extern void squirrelPath(struct nameinfo *pathInfo, int32_t clusterNum); 204 extern void usingCHKName(void *nameCookie); 205 extern void writeFATMods(int fd); 206 extern void traverseDir(int fd, int32_t startAt, int depth, int descend, 207 int operation, char matchRequired, struct pcdir **found, 208 int32_t *lastDirCluster, struct pcdir **dirEnd, char *recordPath, 209 int *pathLen); 210 extern void splitChain(int fd, struct pcdir *dp, int32_t problemCluster, 211 struct pcdir **newdp, int32_t *orphanStart); 212 extern void preenBail(char *outString); 213 extern void readBPB(int fd); 214 extern void getFAT(int fd); 215 extern int checkFAT32CleanBit(int fd); 216 extern int reservedInFAT(int32_t clusterNum); 217 extern int isMarkedBad(int32_t clusterNum); 218 extern int readCluster(int fd, int32_t clusterNum, uchar_t **data, 219 int32_t *datasize, int shouldCache); 220 extern int freeInFAT(int32_t clusterNum); 221 extern int lastInFAT(int32_t clusterNum); 222 extern int markInUse(int fd, int32_t clusterNum, struct pcdir *referencer, 223 struct pcdir *longRef, int32_t longStartCluster, int isHidden, 224 ClusterInfo **template); 225 extern int badInFAT(int32_t clusterNum); 226 227 #ifdef __cplusplus 228 } 229 #endif 230 231 #endif /* _FSCK_PCFS_H */ 232