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 37extern "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 74typedef union clustDataTypes { 75 struct pcdir *dirp; 76 uchar_t *bytes; 77} ClusterContents; 78 79struct cached { 80 int32_t clusterNum; 81 ClusterContents clusterData; 82 short modified; 83 struct cached *next; 84}; 85 86typedef struct cached CachedCluster; 87 88struct 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 */ 101struct 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 122typedef 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 */ 175extern struct pcdir *addRootDirEnt(int fd, struct pcdir *copyme); 176extern struct pcdir *newDirEnt(struct pcdir *copyme); 177extern int32_t extractStartCluster(struct pcdir *dp); 178extern int32_t findImpactedCluster(struct pcdir *modified); 179extern int32_t readFATEntry(int32_t currentCluster); 180extern uint32_t extractSize(struct pcdir *dp); 181extern int32_t nextInChain(int32_t currentCluster); 182extern char *nextAvailableCHKName(int *chosen); 183extern void truncChainWithBadCluster(int fd, struct pcdir *dp, 184 int32_t startCluster); 185extern void mountSanityCheckFails(void); 186extern void markClusterModified(int32_t clusterNum); 187extern void scanAndFixMetadata(int fd); 188extern void updateDirEnt_Start(struct pcdir *dp, int32_t newStart); 189extern void addEntryToCHKList(int chkNumber); 190extern void createCHKNameList(int fd); 191extern void updateDirEnt_Name(struct pcdir *dp, char *newName); 192extern void updateDirEnt_Size(struct pcdir *dp, uint32_t newSize); 193extern void getRootDirectory(int fd); 194extern void writeClusterMods(int fd); 195extern void writeRootDirMods(int fd); 196extern 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); 199extern void findBadClusters(int fd); 200extern void markFreeInFAT(int32_t clusterNum); 201extern void markLastInFAT(int32_t clusterNum); 202extern void writeFATEntry(int32_t currentCluster, int32_t value); 203extern void markBadInFAT(int32_t clusterNum); 204extern void printSummary(FILE *outDest); 205extern void squirrelPath(struct nameinfo *pathInfo, int32_t clusterNum); 206extern void usingCHKName(void *nameCookie); 207extern void writeFATMods(int fd); 208extern 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); 212extern void splitChain(int fd, struct pcdir *dp, int32_t problemCluster, 213 struct pcdir **newdp, int32_t *orphanStart); 214extern void preenBail(char *outString); 215extern void readBPB(int fd); 216extern void getFAT(int fd); 217extern int checkFAT32CleanBit(int fd); 218extern int reservedInFAT(int32_t clusterNum); 219extern int isMarkedBad(int32_t clusterNum); 220extern int readCluster(int fd, int32_t clusterNum, uchar_t **data, 221 int32_t *datasize, int shouldCache); 222extern int freeInFAT(int32_t clusterNum); 223extern int lastInFAT(int32_t clusterNum); 224extern int markInUse(int fd, int32_t clusterNum, struct pcdir *referencer, 225 struct pcdir *longRef, int32_t longStartCluster, int isHidden, 226 ClusterInfo **template); 227extern int badInFAT(int32_t clusterNum); 228 229#ifdef __cplusplus 230} 231#endif 232 233#endif /* _FSCK_PCFS_H */ 234