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