xref: /onnv-gate/usr/src/cmd/fs.d/ufs/fsck/fsck.h (revision 4132:a454cf8a2c90)
10Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
20Sstevel@tonic-gate /*	  All Rights Reserved  	*/
30Sstevel@tonic-gate 
40Sstevel@tonic-gate /*
50Sstevel@tonic-gate  * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
60Sstevel@tonic-gate  * All rights reserved.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
90Sstevel@tonic-gate  * provided that: (1) source distributions retain this entire copyright
100Sstevel@tonic-gate  * notice and comment, and (2) distributions including binaries display
110Sstevel@tonic-gate  * the following acknowledgement:  ``This product includes software
120Sstevel@tonic-gate  * developed by the University of California, Berkeley and its contributors''
130Sstevel@tonic-gate  * in the documentation or other materials provided with the distribution
140Sstevel@tonic-gate  * and in all advertising materials mentioning features or use of this
150Sstevel@tonic-gate  * software. Neither the name of the University nor the names of its
160Sstevel@tonic-gate  * contributors may be used to endorse or promote products derived
170Sstevel@tonic-gate  * from this software without specific prior written permission.
180Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
190Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
200Sstevel@tonic-gate  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate 
230Sstevel@tonic-gate /*
24*4132Sabalfour  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
250Sstevel@tonic-gate  * Use is subject to license terms.
260Sstevel@tonic-gate  */
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #ifndef	_FSCK_FSCK_H
290Sstevel@tonic-gate #define	_FSCK_FSCK_H
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.3   */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #ifdef	__cplusplus
340Sstevel@tonic-gate extern "C" {
350Sstevel@tonic-gate #endif
360Sstevel@tonic-gate 
37392Sswilcox #include <stdio.h>
38392Sswilcox #include <stdarg.h>
39392Sswilcox #include <search.h>
40392Sswilcox #include <sys/param.h>
41392Sswilcox #include <sys/types.h>
42392Sswilcox #include <sys/mnttab.h>
43392Sswilcox #include <sys/vfstab.h>
44392Sswilcox #include <sys/fs/ufs_fs.h>
45392Sswilcox #include <sys/fs/ufs_inode.h>
46392Sswilcox 
470Sstevel@tonic-gate #define	MAXDUP		10	/* limit on dup blks (per inode) */
480Sstevel@tonic-gate #define	MAXBAD		10	/* limit on bad blks (per inode) */
49392Sswilcox #define	MAXBUFSPACE	40*1024 /* initial space to allocate to buffers */
500Sstevel@tonic-gate #define	INOBUFSIZE	56*1024	/* size of buffer to read inodes in pass1 */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #ifndef BUFSIZ
53392Sswilcox #define	BUFSIZ MAXPATHLEN
540Sstevel@tonic-gate #endif
550Sstevel@tonic-gate 
56392Sswilcox /*
57392Sswilcox  * Inode states in statemap[].
58392Sswilcox  */
59392Sswilcox #define	USTATE	0x01		/* inode not allocated */
60392Sswilcox #define	FSTATE	0x02		/* inode is file */
61392Sswilcox #define	DSTATE	0x04		/* inode is directory */
62392Sswilcox #define	SSTATE	0x08		/* inode is a shadow/acl */
63392Sswilcox #define	STMASK	0x0f		/* pick off the basic state/type */
64392Sswilcox 
65392Sswilcox /* flags OR'd into the above */
66392Sswilcox #define	INZLINK  0x0010		/* inode has zero links */
67392Sswilcox #define	INFOUND  0x0020		/* inode was found during descent */
68392Sswilcox #define	INCLEAR  0x0040		/* inode is to be cleared */
69392Sswilcox #define	INORPHAN 0x0080		/* inode is a known orphan (pass3 only) */
70392Sswilcox #define	INDELAYD 0x0200		/* link count update delayed */
71392Sswilcox #define	INMASK   0xfff0		/* pick off the modifiers */
72392Sswilcox 
73392Sswilcox #define	FZLINK	(FSTATE | INZLINK)
74392Sswilcox #define	DZLINK	(DSTATE | INZLINK)
75392Sswilcox #define	SZLINK	(SSTATE | INZLINK)
76392Sswilcox 
77392Sswilcox #define	DFOUND	(DSTATE | INFOUND)
78392Sswilcox 
79392Sswilcox #define	DCLEAR	(DSTATE | INCLEAR)
80392Sswilcox #define	FCLEAR	(FSTATE | INCLEAR)
81392Sswilcox #define	SCLEAR	(SSTATE | INCLEAR)
82392Sswilcox 
83392Sswilcox /*
84392Sswilcox  * These tests depend on the state/type defines above not overlapping bits.
85392Sswilcox  *
86392Sswilcox  *     	DUNFOUND === (state == DSTATE || state == DZLINK)
87392Sswilcox  *          INCLEAR is irrelevant to the determination of
88392Sswilcox  *          connectedness, so it's not included in this test.
89392Sswilcox  *
90392Sswilcox  *     	DVALID   === (state == DSTATE || state == DZLINK || state == DFOUND)
91392Sswilcox  */
92392Sswilcox #define	S_IS_DUNFOUND(state)	(((state) & (DSTATE | INZLINK)) \
93392Sswilcox 				== (state))
94392Sswilcox #define	S_IS_DVALID(state)	(((state) & (DSTATE | INZLINK | INFOUND | \
95392Sswilcox 				INORPHAN)) == (state))
96392Sswilcox #define	S_IS_ZLINK(state)	(((state) & INZLINK) != 0)
97392Sswilcox #define	INO_IS_DUNFOUND(ino)	S_IS_DUNFOUND(statemap[ino])
98392Sswilcox #define	INO_IS_DVALID(ino)	S_IS_DVALID(statemap[ino])
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate /*
1010Sstevel@tonic-gate  * buffer cache structure.
1020Sstevel@tonic-gate  */
1030Sstevel@tonic-gate struct bufarea {
1040Sstevel@tonic-gate 	struct bufarea	*b_next;		/* free list queue */
1050Sstevel@tonic-gate 	struct bufarea	*b_prev;		/* free list queue */
106392Sswilcox 	diskaddr_t	b_bno;			/* physical sector number */
1070Sstevel@tonic-gate 	int	b_size;
1080Sstevel@tonic-gate 	int	b_errs;
1090Sstevel@tonic-gate 	int	b_flags;
1100Sstevel@tonic-gate 	int	b_cnt;				/* reference cnt */
1110Sstevel@tonic-gate 	union {
1120Sstevel@tonic-gate 		char	*b_buf;			/* buffer space */
1130Sstevel@tonic-gate 		daddr32_t	*b_indir;	/* indirect block */
1140Sstevel@tonic-gate 		struct	fs *b_fs;		/* super block */
1150Sstevel@tonic-gate 		struct	cg *b_cg;		/* cylinder group */
1160Sstevel@tonic-gate 		struct	dinode *b_dinode;	/* inode block */
1170Sstevel@tonic-gate 	} b_un;
1180Sstevel@tonic-gate 	char	b_dirty;
1190Sstevel@tonic-gate };
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate #define	B_INUSE 1
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate #define	MINBUFS		5	/* minimum number of buffers required */
1240Sstevel@tonic-gate struct bufarea bufhead;		/* head of list of other blks in filesys */
1250Sstevel@tonic-gate struct bufarea sblk;		/* file system superblock */
126392Sswilcox struct bufarea asblk;		/* alternate superblock */
1270Sstevel@tonic-gate struct bufarea cgblk;		/* cylinder group blocks */
1280Sstevel@tonic-gate struct bufarea *pbp;		/* pointer to inode data in buffer pool */
1290Sstevel@tonic-gate struct bufarea *pdirbp;		/* pointer to directory data in buffer pool */
1300Sstevel@tonic-gate 
131392Sswilcox #define	sbdirty()	dirty(&sblk)
132392Sswilcox #define	cgdirty()	dirty(&cgblk)
1330Sstevel@tonic-gate #define	sblock		(*sblk.b_un.b_fs)
1340Sstevel@tonic-gate #define	cgrp		(*cgblk.b_un.b_cg)
1350Sstevel@tonic-gate 
136392Sswilcox /*
137392Sswilcox  * inodesc.id_fix values.  See inode.c for a description of their usage.
138392Sswilcox  */
139392Sswilcox enum fixstate {
140392Sswilcox 	DONTKNOW, NOFIX, FIX, IGNORE
141392Sswilcox };
142392Sswilcox 
143392Sswilcox /*
144392Sswilcox  * Tells truncino() whether or not to attempt to update the parent
145392Sswilcox  * directory's link count.  Also, TI_NODUP flags when we're discarding
146392Sswilcox  * fragments that are beyond the original end of the file, and so
147392Sswilcox  * should not be considered duplicate-claim candidates.
148392Sswilcox  */
149392Sswilcox #define	TI_NOPARENT	0x0001	/* leave parent's di_nlink alone */
150392Sswilcox #define	TI_PARENT	0x0002	/* update parent's di_nlink */
151392Sswilcox #define	TI_NODUP	0x0004	/* not a dup candidate */
1520Sstevel@tonic-gate 
153392Sswilcox /*
154392Sswilcox  * Modes for ckinode() and ckinode_common().
155392Sswilcox  *
156392Sswilcox  * CKI_TRAVERSE is the common case, and requests a traditional
157392Sswilcox  * traversal of blocks or directory entries.
158392Sswilcox  *
159392Sswilcox  * CKI_TRUNCATE indicates that we're truncating the file, and that any
160392Sswilcox  * block indices beyond the end of the target length should be cleared
161392Sswilcox  * after the callback has returned (i.e., this is a superset of
162392Sswilcox  * CKI_TRAVERSE).  idesc->id_truncto is the first logical block number
163392Sswilcox  * to clear.  If it is less than zero, then the traversal will be
164392Sswilcox  * equivalent to a simple CKI_TRAVERSE.
165392Sswilcox  */
166392Sswilcox enum cki_action { CKI_TRAVERSE, CKI_TRUNCATE };
167392Sswilcox 
168392Sswilcox /*
169392Sswilcox  * The general definition of an ino_t is an unsigned quantity.
170392Sswilcox  * However, the on-disk version is an int32_t, which is signed.
171392Sswilcox  * Since we really want to be able to detect wrapped-around
172392Sswilcox  * inode numbers and such, we'll use something that's compatible
173392Sswilcox  * with what's on disk since that's the only context that really
174392Sswilcox  * matters.  If an int32_t is found not to be sufficiently large,
175392Sswilcox  * this will make it much easier to change later.
176392Sswilcox  *
177392Sswilcox  * Note that there is one unsigned inode field in the on-disk
178392Sswilcox  * inode, ic_oeftflag.  Since all other inode fields are signed,
179392Sswilcox  * no legitimate inode number can be put into ic_oeftflag that
180392Sswilcox  * would overflow into the high bit.  Essentially, it should
181392Sswilcox  * actually be declared as int32_t just like all the others, and
182392Sswilcox  * we're going to pretend that it was.
183392Sswilcox  *
184392Sswilcox  * None of the routines that we use in ufs_subr.c do anything with
185392Sswilcox  * inode numbers.  If that changes, then great care will be needed
186392Sswilcox  * to deal with the differences in definition of ino_t and fsck_ino_t.
187392Sswilcox  * Lint is your friend.
188392Sswilcox  */
189392Sswilcox typedef int32_t		fsck_ino_t;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /*
192392Sswilcox  * See the full discussion of the interactions between struct inodesc
193392Sswilcox  * and ckinode() in inode.c
1940Sstevel@tonic-gate  */
195392Sswilcox struct inodesc {
196392Sswilcox 	enum fixstate id_fix;	/* policy on fixing errors */
197392Sswilcox 	int (*id_func)(struct inodesc *);
198392Sswilcox 				/* function to be applied to blocks of inode */
199392Sswilcox 	fsck_ino_t id_number;	/* inode number described */
200392Sswilcox 	fsck_ino_t id_parent;	/* for DATA nodes, their parent */
201392Sswilcox 				/* also used for extra (*id_func) parameter */
202392Sswilcox 				/* and return values */
203392Sswilcox 	daddr32_t id_lbn;	/* logical fragment number of current block */
204392Sswilcox 	daddr32_t id_blkno;	/* physical fragment number being examined */
205392Sswilcox 	int id_numfrags;	/* number of frags contained in block */
206392Sswilcox 	daddr32_t id_truncto;	/* # blocks to truncate to, -1 for no trunc. */
207392Sswilcox 	offset_t id_filesize;	/* for DATA nodes, the size of the directory */
208392Sswilcox 	uint_t id_loc;		/* for DATA nodes, current location in dir */
209392Sswilcox 	daddr32_t id_entryno;	/* for DATA nodes, current dir entry number */
210392Sswilcox 	daddr32_t id_firsthole;	/* for DATA inode, logical block that is */
211392Sswilcox 				/* zero but shouldn't be, -1 for no holes */
212392Sswilcox 	struct direct *id_dirp;	/* for DATA nodes, ptr to current entry */
213392Sswilcox 	caddr_t id_name;	/* for DATA nodes, name to find or enter */
214392Sswilcox 	char id_type;		/* type of descriptor, DATA or ADDR */
2150Sstevel@tonic-gate };
216392Sswilcox 
217392Sswilcox /* file types (0 is reserved for catching bugs) */
218392Sswilcox #define	DATA	1	/* a directory */
219392Sswilcox #define	ACL	2	/* an acl/shadow */
220392Sswilcox #define	ADDR	3	/* anything but a directory or an acl/shadow */
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate /*
223392Sswilcox  * OR'd flags for find_dup_ref()'s mode argument
2240Sstevel@tonic-gate  */
225392Sswilcox #define	DB_CREATE	0x01	/* if dup record found, make one */
226392Sswilcox #define	DB_INCR		0x02	/* increment block's reference count */
227392Sswilcox #define	DB_DECR		0x04	/* decrement block's reference count */
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /*
230392Sswilcox  * Cache data structures
2310Sstevel@tonic-gate  */
2320Sstevel@tonic-gate struct inoinfo {
233392Sswilcox 	struct inoinfo	*i_nextlist;	/* next inode/acl cache entry */
234392Sswilcox 	fsck_ino_t	i_number;	/* inode number of this entry */
235392Sswilcox 	fsck_ino_t	i_parent;	/* inode number of parent */
236392Sswilcox 	fsck_ino_t	i_dotdot;	/* inode number of .. */
237392Sswilcox 	fsck_ino_t	i_extattr;	/* inode of hidden attr dir */
238392Sswilcox 	offset_t	i_isize;	/* size of inode */
239392Sswilcox 	size_t		i_blkssize;	/* size of block array in bytes */
2400Sstevel@tonic-gate 	daddr32_t	i_blks[1];	/* actually longer */
241392Sswilcox };
242392Sswilcox 
243392Sswilcox /*
244392Sswilcox  * Inode cache
245392Sswilcox  */
246392Sswilcox struct inoinfo **inphead, **inpsort;
2470Sstevel@tonic-gate int64_t numdirs, listmax, inplast;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate /*
250392Sswilcox  * ACL cache
2510Sstevel@tonic-gate  */
252392Sswilcox struct inoinfo **aclphead, **aclpsort;
2530Sstevel@tonic-gate int64_t numacls, aclmax, aclplast;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate /*
256392Sswilcox  * Tree of directories we haven't reconnected or cleared.  Any
257392Sswilcox  * dir inode that linkup() fails on gets added, any that clri()
258392Sswilcox  * succeeds on gets removed.  If there are any left at the end of
259392Sswilcox  * pass four, then we have a user-forced corrupt filesystem, and
260392Sswilcox  * need to set iscorrupt.
261392Sswilcox  *
262392Sswilcox  * Elements are fsck_ino_t instances (not pointers).
263392Sswilcox  */
264392Sswilcox void *limbo_dirs;
265392Sswilcox 
266392Sswilcox /*
267392Sswilcox  * Number of directories we actually found in the filesystem,
268392Sswilcox  * as opposed to how many the superblock claims there are.
269392Sswilcox  */
270392Sswilcox fsck_ino_t countdirs;
271392Sswilcox 
272392Sswilcox /*
2730Sstevel@tonic-gate  * shadowclients and shadowclientinfo are structures for keeping track of
2740Sstevel@tonic-gate  * shadow inodes that exist, and which regular inodes use them (i.e. are
2750Sstevel@tonic-gate  * their clients).
2760Sstevel@tonic-gate  */
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate struct shadowclients {
279392Sswilcox 	fsck_ino_t *client;	/* an array of inode numbers */
2800Sstevel@tonic-gate 	int nclients; /* how many inodes in the array are in use (valid) */
2810Sstevel@tonic-gate 	struct shadowclients *next; /* link to more client inode numbers */
2820Sstevel@tonic-gate };
2830Sstevel@tonic-gate struct shadowclientinfo {
284392Sswilcox 	fsck_ino_t shadow;	/* the shadow inode that this info is for */
2850Sstevel@tonic-gate 	int totalClients;	/* how many inodes total refer to this */
2860Sstevel@tonic-gate 	struct shadowclients *clients; /* a linked list of wads of clients */
2870Sstevel@tonic-gate 	struct shadowclientinfo *next; /* link to the next shadow inode */
2880Sstevel@tonic-gate };
2890Sstevel@tonic-gate /* global pointer to this shadow/client information */
290392Sswilcox struct shadowclientinfo *shadowclientinfo;
291392Sswilcox struct shadowclientinfo *attrclientinfo;
292392Sswilcox 
293392Sswilcox /*
294392Sswilcox  * In ufs_inode.h ifdef _KERNEL, this is defined as `/@/'.  However,
295392Sswilcox  * to avoid all sorts of potential confusion (you can't actually use
296392Sswilcox  * `foo/@/bar' to get to an attribute), we use something that doesn't
297392Sswilcox  * look quite so much like a simple pathname.
298392Sswilcox  */
299392Sswilcox #define	XATTR_DIR_NAME	" <xattr> "
300392Sswilcox 
301392Sswilcox /*
302392Sswilcox  * granularity -- how many client inodes do we make space for at a time
303392Sswilcox  * initialized in setup.c;
304392Sswilcox  */
3050Sstevel@tonic-gate extern int maxshadowclients;
306392Sswilcox 
307392Sswilcox /*
308392Sswilcox  * Initialized global variables.
309392Sswilcox  */
310392Sswilcox extern caddr_t lfname;
3110Sstevel@tonic-gate 
312392Sswilcox /*
313392Sswilcox  * Unitialized globals.
314392Sswilcox  */
3150Sstevel@tonic-gate char	*devname;		/* name of device being checked */
316392Sswilcox size_t	dev_bsize;		/* computed value of DEV_BSIZE */
3170Sstevel@tonic-gate int	secsize;		/* actual disk sector size */
3180Sstevel@tonic-gate char	nflag;			/* assume a no response */
3190Sstevel@tonic-gate char	yflag;			/* assume a yes response */
320392Sswilcox daddr32_t	bflag;		/* location of alternate super block */
3210Sstevel@tonic-gate int	debug;			/* output debugging info */
3220Sstevel@tonic-gate int	rflag;			/* check raw file systems */
323392Sswilcox int	roflag;			/* do normal checks but don't update disk */
3240Sstevel@tonic-gate int	fflag;			/* check regardless of clean flag (force) */
325392Sswilcox int	mflag;			/* sanity check only */
326392Sswilcox int	verbose;		/* be chatty */
3270Sstevel@tonic-gate char	preen;			/* just fix normal inconsistencies */
3280Sstevel@tonic-gate char	mountedfs;		/* checking mounted device */
329392Sswilcox int	exitstat;		/* exit status (see EX* defines below) */
3300Sstevel@tonic-gate char	hotroot;		/* checking root device */
331392Sswilcox char	rerun;			/* rerun fsck. Only used in non-preen mode */
332392Sswilcox int	interrupted;		/* 1 => exit EXSIGNAL on exit */
3330Sstevel@tonic-gate char	havesb;			/* superblock has been read */
3340Sstevel@tonic-gate int	fsmodified;		/* 1 => write done to file system */
3350Sstevel@tonic-gate int	fsreadfd;		/* file descriptor for reading file system */
3360Sstevel@tonic-gate int	fswritefd;		/* file descriptor for writing file system */
3370Sstevel@tonic-gate int	iscorrupt;		/* known to be corrupt/inconsistent */
338392Sswilcox 				/* -1 means mark clean so user can mount+fix */
3390Sstevel@tonic-gate int	isdirty;		/* 1 => write pending to file system */
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate int	islog;			/* logging file system */
3420Sstevel@tonic-gate int	islogok;		/* log is okay */
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate int	errorlocked;		/* set => mounted fs has been error-locked */
3450Sstevel@tonic-gate 				/* implies fflag "force check flag" */
3460Sstevel@tonic-gate char	*elock_combuf;		/* error lock comment buffer */
3470Sstevel@tonic-gate char	*elock_mountp;		/* mount point; used to unlock error-lock */
3480Sstevel@tonic-gate int	pid;			/* fsck's process id (put in lockfs comment) */
3490Sstevel@tonic-gate int	mountfd;		/* fd of mount point */
3500Sstevel@tonic-gate struct lockfs	*lfp;		/* current lockfs status */
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate daddr32_t	maxfsblock;	/* number of blocks in the file system */
353392Sswilcox uint_t	largefile_count;	/* global largefile counter */
354392Sswilcox char	*mount_point;		/* if mounted, this is where */
3550Sstevel@tonic-gate char	*blockmap;		/* ptr to primary blk allocation map */
356392Sswilcox fsck_ino_t	maxino;		/* number of inodes in file system */
357392Sswilcox fsck_ino_t	lastino;	/* last inode in use */
358392Sswilcox ushort_t *statemap;		/* ptr to inode state table */
3590Sstevel@tonic-gate short	*lncntp;		/* ptr to link count table */
3600Sstevel@tonic-gate 
361392Sswilcox fsck_ino_t	lfdir;		/* lost & found directory inode number */
362392Sswilcox int		overflowed_lf;	/* tried to wrap lost & found's link count */
363392Sswilcox int		reattached_dir;	/* reconnected at least one directory */
364392Sswilcox int		broke_dir_link;	/* broke at least one directory hardlink */
3650Sstevel@tonic-gate 
366392Sswilcox daddr32_t	n_blks;		/* number of blocks in use */
367392Sswilcox fsck_ino_t	n_files;	/* number of files in use */
3680Sstevel@tonic-gate 
369392Sswilcox #define	clearinode(dp)	{ \
370392Sswilcox 	*(dp) = zino; \
371392Sswilcox }
3720Sstevel@tonic-gate struct	dinode zino;
3730Sstevel@tonic-gate 
374392Sswilcox #define	testbmap(blkno)	isset(blockmap, blkno)
3750Sstevel@tonic-gate #define	setbmap(blkno)	setbit(blockmap, blkno)
3760Sstevel@tonic-gate #define	clrbmap(blkno)	clrbit(blockmap, blkno)
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate #define	STOP	0x01
3790Sstevel@tonic-gate #define	SKIP	0x02
3800Sstevel@tonic-gate #define	KEEPON	0x04
3810Sstevel@tonic-gate #define	ALTERED	0x08
3820Sstevel@tonic-gate #define	FOUND	0x10
3830Sstevel@tonic-gate 
384392Sswilcox /*
385392Sswilcox  * Support relatively easy debugging of lncntp[] updates.  This can't
386392Sswilcox  * be a function, because of the (_op) step.  Normally, we just do that.
387392Sswilcox  */
388392Sswilcox #define	TRACK_LNCNTP(_ino, _op) (_op)
389392Sswilcox 
390392Sswilcox /*
391392Sswilcox  * See if the net link count for an inode has gone outside
392392Sswilcox  * what can be represented on disk.  Returning text as NULL
393392Sswilcox  * indicates no.
394392Sswilcox  *
395392Sswilcox  * Remember that link counts are effectively inverted, so
396392Sswilcox  * underflow and overflow are reversed as well.
397392Sswilcox  *
398392Sswilcox  * This check should be done before modifying the actual link
399392Sswilcox  * count.
400392Sswilcox  */
401392Sswilcox #define	LINK_RANGE(text, current, offset) { \
402392Sswilcox 	int net = ((int)(current)) + ((int)(offset)); \
403392Sswilcox 	text = NULL; \
404392Sswilcox 	if (net > (MAXLINK)) \
405392Sswilcox 		text = "UNDERFLOW"; \
406392Sswilcox 	else if (net < -(MAXLINK)) \
407392Sswilcox 		text = "OVERFLOW"; \
408392Sswilcox }
409392Sswilcox 
410392Sswilcox /*
411392Sswilcox  * If LINK_RANGE() indicated a problem, this is the boiler-plate
412392Sswilcox  * for dealing with it.  Usage is:
413392Sswilcox  *
414392Sswilcox  *     LINK_RANGE(text, current, offset);
415392Sswilcox  *     if (text != NULL) {
416392Sswilcox  *         LINK_CLEAR(text, ino, mode, idp);
417392Sswilcox  *         if (statemap[ino] == USTATE)
418392Sswilcox  *             ...inode was cleared...
419392Sswilcox  *     }
420392Sswilcox  *
421392Sswilcox  * Note that clri() will set iscorrupt if the user elects not to
422392Sswilcox  * clear the problem inode, so the filesystem won't get reported
423392Sswilcox  * as clean when it shouldn't be.
424392Sswilcox  */
425392Sswilcox #define	LINK_CLEAR(text, ino, mode, idp) { \
426392Sswilcox 	pwarn("%s LINK COUNT %s", file_id((ino), (mode)), (text)); \
427392Sswilcox 	pinode((ino)); \
428392Sswilcox 	pfatal(""); \
429392Sswilcox 	init_inodesc((idp)); \
430392Sswilcox 	(idp)->id_type = ADDR; \
431392Sswilcox 	(idp)->id_func = pass4check; \
432392Sswilcox 	(idp)->id_number = ino; \
433392Sswilcox 	(idp)->id_fix = DONTKNOW; \
434392Sswilcox 	clri((idp), (text), CLRI_QUIET, CLRI_NOP_CORRUPT); \
435392Sswilcox }
436392Sswilcox 
437392Sswilcox /*
438392Sswilcox  * Used for checking link count under/overflow specifically on
439392Sswilcox  * the lost+found directory.  If the user decides not to do the
440392Sswilcox  * clri(), then flag that we've hit this problem and refuse to do
441392Sswilcox  * the reconnect.
442392Sswilcox  */
443392Sswilcox #define	LFDIR_LINK_RANGE_RVAL(text, current, offset, idp, rval) { \
444392Sswilcox 	LINK_RANGE(text, current, offset); \
445392Sswilcox 	if (text != NULL) { \
446392Sswilcox 		LINK_CLEAR(text, lfdir, IFDIR, idp); \
447392Sswilcox 		if (statemap[lfdir] == USTATE) { \
448392Sswilcox 			lfdir = 0; \
449392Sswilcox 			return (rval); \
450392Sswilcox 		} else { \
451392Sswilcox 			overflowed_lf++; \
452392Sswilcox 		} \
453392Sswilcox 	} \
454392Sswilcox }
455392Sswilcox 
456392Sswilcox #define	LFDIR_LINK_RANGE_NORVAL(text, current, offset, idp) { \
457392Sswilcox 	LINK_RANGE(text, current, offset); \
458392Sswilcox 	if (text != NULL) { \
459392Sswilcox 		LINK_CLEAR(text, lfdir, IFDIR, idp); \
460392Sswilcox 		if (statemap[lfdir] == USTATE) { \
461392Sswilcox 			lfdir = 0; \
462392Sswilcox 			return; \
463392Sswilcox 		} else { \
464392Sswilcox 			overflowed_lf++; \
465392Sswilcox 		} \
466392Sswilcox 	} \
467392Sswilcox }
468392Sswilcox 
469392Sswilcox /*
470392Sswilcox  * Values for mounted() and mountedfs.
471392Sswilcox  */
472392Sswilcox #define	M_NOMNT		0	/* filesystem is not mounted */
473392Sswilcox #define	M_RO		1	/* filesystem is mounted read-only */
474392Sswilcox #define	M_RW		2	/* filesystem is mounted read-write */
475392Sswilcox 
476392Sswilcox #define	EXOKAY		0	/* file system is unmounted and ok */
477392Sswilcox #define	EXBADPARM	1	/* bad parameter(s) given */
478392Sswilcox #define	EXUMNTCHK	32	/* fsck -m: unmounted, needs checking */
479392Sswilcox #define	EXMOUNTED	33	/* file system already mounted, not magic, */
480392Sswilcox 				/* or it is magic and mounted read/write */
481392Sswilcox #define	EXNOSTAT	34	/* cannot stat device */
482392Sswilcox #define	EXREBOOTNOW	35	/* modified root or something equally scary */
483392Sswilcox #define	EXFNDERRS	36	/* uncorrectable errors, terminate normally */
484392Sswilcox #define	EXSIGNAL	37	/* a signal was caught during processing */
485392Sswilcox #define	EXERRFATAL	39	/* uncorrectable errors, exit immediately */
486392Sswilcox #define	EXROOTOKAY	40	/* for root, same as 0 */
487392Sswilcox 
488392Sswilcox /*
489392Sswilcox  * Values for clri()'s `verbose' and `corrupting' arguments (third
490392Sswilcox  * and fourth, respectively).
491392Sswilcox  */
492392Sswilcox #define	CLRI_QUIET		1
493392Sswilcox #define	CLRI_VERBOSE		2
494392Sswilcox 
495392Sswilcox #define	CLRI_NOP_OK		1
496392Sswilcox #define	CLRI_NOP_CORRUPT	2
4970Sstevel@tonic-gate 
498392Sswilcox /*
499392Sswilcox  * Filesystems that are `magical' - if they exist in vfstab,
500392Sswilcox  * then they have to be mounted for the system to have gotten
501392Sswilcox  * far enough to be able to run fsck.  Thus, don't get all
502392Sswilcox  * bent out of shape if we're asked to check it and it is mounted.
503392Sswilcox  * Actual initialization of the array is in main.c
504392Sswilcox  */
505392Sswilcox enum magic {
506392Sswilcox 	MAGIC_NONE = 0,
507392Sswilcox 	MAGIC_ROOT = 1,
508392Sswilcox 	MAGIC_USR = 2,
509504Sswilcox 	MAGIC_LIMIT = 3
510392Sswilcox };
511392Sswilcox extern char *magic_fs[];
512392Sswilcox 
513392Sswilcox /*
514392Sswilcox  * Paths needed by calcsb().
515392Sswilcox  */
516392Sswilcox #define	MKFS_PATH	"/usr/lib/fs/ufs/mkfs"
517392Sswilcox #define	NEWFS_PATH	"/usr/lib/fs/ufs/newfs"
518392Sswilcox 
519392Sswilcox int		acltypeok(struct dinode *);
520392Sswilcox void		add_orphan_dir(fsck_ino_t);
521392Sswilcox void		adjust(struct inodesc *, int);
522392Sswilcox daddr32_t	allocblk(int);
523392Sswilcox fsck_ino_t	allocdir(fsck_ino_t, fsck_ino_t, int, int);
524392Sswilcox fsck_ino_t	allocino(fsck_ino_t, int);
525392Sswilcox void		blkerror(fsck_ino_t, caddr_t, daddr32_t, daddr32_t);
526392Sswilcox void		brelse(struct bufarea *);
527392Sswilcox void		bufinit(void);
528392Sswilcox void		bwrite(int, caddr_t, diskaddr_t, int64_t);
529392Sswilcox void		cacheacl(struct dinode *, fsck_ino_t);
530392Sswilcox void		cacheino(struct dinode *, fsck_ino_t);
531392Sswilcox void		catch(int);
532392Sswilcox void		catchquit(int);
5333219Sabalfour caddr_t		cg_sanity(struct cg *, int);
534392Sswilcox void		cgflush(void);
535392Sswilcox int		cgisdirty(void);
536392Sswilcox int		changeino(fsck_ino_t, caddr_t, fsck_ino_t);
537392Sswilcox int		check_mnttab(caddr_t, caddr_t, size_t);
538392Sswilcox int		check_vfstab(caddr_t, caddr_t, size_t);
539392Sswilcox int		chkrange(daddr32_t, int);
540392Sswilcox void		ckfini(void);
541392Sswilcox int		ckinode(struct dinode *, struct inodesc *, enum cki_action);
542392Sswilcox void		clearattrref(fsck_ino_t);
543392Sswilcox int		cleardirentry(fsck_ino_t, fsck_ino_t);
544392Sswilcox void		clearshadow(fsck_ino_t, struct shadowclientinfo **);
545392Sswilcox void		clri(struct inodesc *, caddr_t, int, int);
546392Sswilcox void		deshadow(struct shadowclientinfo *, void (*)(fsck_ino_t));
547392Sswilcox void		direrror(fsck_ino_t, caddr_t, ...);
548392Sswilcox int		dirscan(struct inodesc *);
549392Sswilcox void		dirty(struct bufarea *);
550392Sswilcox int		do_errorlock(int);
551392Sswilcox int		dofix(struct inodesc *, caddr_t, ...);
552*4132Sabalfour void		examinelog(void (*)(daddr32_t));
553392Sswilcox void		errexit(caddr_t, ...);
554392Sswilcox void		fileerror(fsck_ino_t, fsck_ino_t, caddr_t, ...);
555392Sswilcox caddr_t		file_id(fsck_ino_t, mode_t);
556392Sswilcox int		find_dup_ref(daddr32_t, fsck_ino_t, daddr32_t, int);
557392Sswilcox int		findino(struct inodesc *);
558392Sswilcox int		findname(struct inodesc *);
559392Sswilcox void		fix_cg(struct cg *, int);
560392Sswilcox void		flush(int, struct bufarea *);
561392Sswilcox void		free_dup_state(void);
562392Sswilcox void		freeblk(fsck_ino_t, daddr32_t, int);
563392Sswilcox void		freeino(fsck_ino_t, int);
564392Sswilcox void		freeinodebuf(void);
565392Sswilcox int		fsck_asprintf(caddr_t *, caddr_t, ...);
566392Sswilcox int		fsck_bread(int, caddr_t, diskaddr_t, size_t);
567392Sswilcox int		ftypeok(struct dinode *);
568392Sswilcox struct bufarea	*getblk(struct bufarea *, daddr32_t, size_t);
569392Sswilcox struct bufarea	*getdatablk(daddr32_t, size_t size);
570392Sswilcox diskaddr_t	getdisksize(caddr_t, int);
571392Sswilcox struct inoinfo	*getinoinfo(fsck_ino_t);
572392Sswilcox struct dinode	*getnextinode(fsck_ino_t);
573392Sswilcox struct dinode	*getnextrefresh(void);
574392Sswilcox void		getpathname(caddr_t, fsck_ino_t, fsck_ino_t);
575392Sswilcox struct dinode	*ginode(fsck_ino_t);
576392Sswilcox caddr_t		hasvfsopt(struct vfstab *, caddr_t);
577392Sswilcox int		have_dups(void);
578392Sswilcox void		init_inodesc(struct inodesc *);
579392Sswilcox void		init_inoinfo(struct inoinfo *, struct dinode *, fsck_ino_t);
580392Sswilcox void		initbarea(struct bufarea *);
581392Sswilcox int		ino_t_cmp(const void *, const void *);
582392Sswilcox int		inocached(fsck_ino_t);
583392Sswilcox void		inocleanup(void);
584392Sswilcox void		inodirty(void);
585392Sswilcox int		is_errorlocked(caddr_t);
586392Sswilcox int		linkup(fsck_ino_t, fsck_ino_t, caddr_t);
587392Sswilcox int		lookup_named_ino(fsck_ino_t, caddr_t);
588392Sswilcox int		makeentry(fsck_ino_t, fsck_ino_t, caddr_t);
589392Sswilcox void		maybe_convert_attrdir_to_dir(fsck_ino_t);
590392Sswilcox int		mounted(caddr_t, caddr_t, size_t);
591392Sswilcox void		pass1(void);
592392Sswilcox void		pass1b(void);
593392Sswilcox int		pass1check(struct inodesc *);
594504Sswilcox void		pass2(void);
595392Sswilcox void		pass3a(void);
596392Sswilcox void		pass3b(void);
597392Sswilcox int		pass3bcheck(struct inodesc *);
598392Sswilcox void		pass4(void);
599392Sswilcox int		pass4check(struct inodesc *);
600392Sswilcox void		pass5(void);
601392Sswilcox void		pfatal(caddr_t, ...);
602392Sswilcox void		pinode(fsck_ino_t);
603392Sswilcox void		printclean(void);
604392Sswilcox void		propagate(void);
605392Sswilcox void		pwarn(caddr_t, ...);
606392Sswilcox caddr_t		rawname(caddr_t);
607392Sswilcox void		registershadowclient(fsck_ino_t, fsck_ino_t,
608392Sswilcox 		    struct shadowclientinfo **);
609392Sswilcox void		remove_orphan_dir(fsck_ino_t);
610392Sswilcox int		reply(caddr_t, ...);
611392Sswilcox int		report_dups(int);
612392Sswilcox void		resetinodebuf(void);
613392Sswilcox char		*setup(caddr_t);
614392Sswilcox void		truncino(fsck_ino_t, offset_t, int);
615392Sswilcox void		unbufinit(void);
616392Sswilcox caddr_t		unrawname(caddr_t);
617392Sswilcox void		unregistershadow(fsck_ino_t, struct shadowclientinfo **);
618392Sswilcox int		updateclean(void);
619392Sswilcox int		writable(caddr_t);
620392Sswilcox void		write_altsb(int);
621392Sswilcox 
622392Sswilcox /*
623392Sswilcox  * Functions from the kernel sources (ufs_subr.c, etc).
624392Sswilcox  */
625392Sswilcox extern void	fragacct(struct fs *, int, int32_t *, int);
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate #ifdef	__cplusplus
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate #endif
6300Sstevel@tonic-gate 
6310Sstevel@tonic-gate #endif	/* _FSCK_FSCK_H */
632