fsck.h revision 23675
1/*
2 * Copyright (c) 1980, 1986, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)fsck.h	8.4 (Berkeley) 5/9/95
34 */
35
36#include <unistd.h>
37#include <stdlib.h>
38#include <stdio.h>
39
40#define	MAXDUP		10	/* limit on dup blks (per inode) */
41#define	MAXBAD		10	/* limit on bad blks (per inode) */
42#define	MAXBUFSPACE	40*1024	/* maximum space to allocate to buffers */
43#define	INOBUFSIZE	56*1024	/* size of buffer to read inodes in pass1 */
44
45#ifndef BUFSIZ
46#define BUFSIZ 1024
47#endif
48
49#define	USTATE	01		/* inode not allocated */
50#define	FSTATE	02		/* inode is file */
51#define	DSTATE	03		/* inode is directory */
52#define	DFOUND	04		/* directory found during descent */
53#define	DCLEAR	05		/* directory is to be cleared */
54#define	FCLEAR	06		/* file is to be cleared */
55
56/*
57 * buffer cache structure.
58 */
59struct bufarea {
60	struct bufarea *b_next;		/* free list queue */
61	struct bufarea *b_prev;		/* free list queue */
62	ufs_daddr_t b_bno;
63	int b_size;
64	int b_errs;
65	int b_flags;
66	union {
67		char *b_buf;			/* buffer space */
68		ufs_daddr_t *b_indir;		/* indirect block */
69		struct fs *b_fs;		/* super block */
70		struct cg *b_cg;		/* cylinder group */
71		struct dinode *b_dinode;	/* inode block */
72	} b_un;
73	char b_dirty;
74};
75
76#define	B_INUSE 1
77
78#define	MINBUFS		5	/* minimum number of buffers required */
79struct bufarea bufhead;		/* head of list of other blks in filesys */
80struct bufarea sblk;		/* file system superblock */
81struct bufarea cgblk;		/* cylinder group blocks */
82struct bufarea *pdirbp;		/* current directory contents */
83struct bufarea *pbp;		/* current inode block */
84
85#define	dirty(bp)	(bp)->b_dirty = 1
86#define	initbarea(bp) \
87	(bp)->b_dirty = 0; \
88	(bp)->b_bno = (ufs_daddr_t)-1; \
89	(bp)->b_flags = 0;
90
91#define	sbdirty()	sblk.b_dirty = 1
92#define	cgdirty()	cgblk.b_dirty = 1
93#define	sblock		(*sblk.b_un.b_fs)
94#define	cgrp		(*cgblk.b_un.b_cg)
95
96enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
97
98struct inodesc {
99	enum fixstate id_fix;	/* policy on fixing errors */
100	int (*id_func)();	/* function to be applied to blocks of inode */
101	ino_t id_number;	/* inode number described */
102	ino_t id_parent;	/* for DATA nodes, their parent */
103	ufs_daddr_t id_blkno;	/* current block number being examined */
104	int id_numfrags;	/* number of frags contained in block */
105	quad_t id_filesize;	/* for DATA nodes, the size of the directory */
106	int id_loc;		/* for DATA nodes, current location in dir */
107	int id_entryno;		/* for DATA nodes, current entry number */
108	struct direct *id_dirp;	/* for DATA nodes, ptr to current entry */
109	char *id_name;		/* for DATA nodes, name to find or enter */
110	char id_type;		/* type of descriptor, DATA or ADDR */
111};
112/* file types */
113#define	DATA	1
114#define	ADDR	2
115
116/*
117 * Linked list of duplicate blocks.
118 *
119 * The list is composed of two parts. The first part of the
120 * list (from duplist through the node pointed to by muldup)
121 * contains a single copy of each duplicate block that has been
122 * found. The second part of the list (from muldup to the end)
123 * contains duplicate blocks that have been found more than once.
124 * To check if a block has been found as a duplicate it is only
125 * necessary to search from duplist through muldup. To find the
126 * total number of times that a block has been found as a duplicate
127 * the entire list must be searched for occurences of the block
128 * in question. The following diagram shows a sample list where
129 * w (found twice), x (found once), y (found three times), and z
130 * (found once) are duplicate block numbers:
131 *
132 *    w -> y -> x -> z -> y -> w -> y
133 *    ^		     ^
134 *    |		     |
135 * duplist	  muldup
136 */
137struct dups {
138	struct dups *next;
139	ufs_daddr_t dup;
140};
141struct dups *duplist;		/* head of dup list */
142struct dups *muldup;		/* end of unique duplicate dup block numbers */
143
144/*
145 * Linked list of inodes with zero link counts.
146 */
147struct zlncnt {
148	struct zlncnt *next;
149	ino_t zlncnt;
150};
151struct zlncnt *zlnhead;		/* head of zero link count list */
152
153/*
154 * Inode cache data structures.
155 */
156struct inoinfo {
157	struct	inoinfo *i_nexthash;	/* next entry in hash chain */
158	ino_t	i_number;		/* inode number of this entry */
159	ino_t	i_parent;		/* inode number of parent */
160	ino_t	i_dotdot;		/* inode number of `..' */
161	size_t	i_isize;		/* size of inode */
162	u_int	i_numblks;		/* size of block array in bytes */
163	ufs_daddr_t i_blks[1];		/* actually longer */
164} **inphead, **inpsort;
165long numdirs, listmax, inplast;
166
167char	*cdevname;		/* name of device being checked */
168long	dev_bsize;		/* computed value of DEV_BSIZE */
169long	secsize;		/* actual disk sector size */
170char	fflag;			/* force fs check (ignore clean flag) */
171char	nflag;			/* assume a no response */
172char	yflag;			/* assume a yes response */
173int	bflag;			/* location of alternate super block */
174int	debug;			/* output debugging info */
175int	cvtlevel;		/* convert to newer file system format */
176int	doinglevel1;		/* converting to new cylinder group format */
177int	doinglevel2;		/* converting to new inode format */
178int	newinofmt;		/* filesystem has new inode format */
179char	preen;			/* just fix normal inconsistencies */
180char	hotroot;		/* checking root device */
181char	havesb;			/* superblock has been read */
182int	fsmodified;		/* 1 => write done to file system */
183int	fsreadfd;		/* file descriptor for reading file system */
184int	fswritefd;		/* file descriptor for writing file system */
185int	returntosingle;		/* return to single user mode */
186int	rerun;			/* rerun fsck. Only used in non-preen mode */
187
188ufs_daddr_t maxfsblock;		/* number of blocks in the file system */
189char	*blockmap;		/* ptr to primary blk allocation map */
190ino_t	maxino;			/* number of inodes in file system */
191ino_t	lastino;		/* last inode in use */
192char	*statemap;		/* ptr to inode state table */
193u_char	*typemap;		/* ptr to inode type table */
194short	*lncntp;		/* ptr to link count table */
195
196ino_t	lfdir;			/* lost & found directory inode number */
197char	*lfname;		/* lost & found directory name */
198int	lfmode;			/* lost & found directory creation mode */
199
200ufs_daddr_t n_blks;		/* number of blocks in use */
201ufs_daddr_t n_files;		/* number of files in use */
202
203#define	clearinode(dp)	(*(dp) = zino)
204struct	dinode zino;
205
206#define	setbmap(blkno)	setbit(blockmap, blkno)
207#define	testbmap(blkno)	isset(blockmap, blkno)
208#define	clrbmap(blkno)	clrbit(blockmap, blkno)
209
210#define	STOP	0x01
211#define	SKIP	0x02
212#define	KEEPON	0x04
213#define	ALTERED	0x08
214#define	FOUND	0x10
215
216#define	EEXIT	8		/* Standard error exit. */
217
218struct fstab;
219
220void		adjust __P((struct inodesc *, int lcnt));
221ufs_daddr_t	allocblk __P((long frags));
222ino_t		allocdir __P((ino_t parent, ino_t request, int mode));
223ino_t		allocino __P((ino_t request, int type));
224void		blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
225char	       *blockcheck __P((char *name));
226int		bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
227void		bufinit __P((void));
228void		bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
229void		cacheino __P((struct dinode *dp, ino_t inumber));
230void		catch __P((int));
231void		catchquit __P((int));
232int		changeino __P((ino_t dir, char *name, ino_t newnum));
233int		checkfstab __P((int preen, int maxrun,
234			int (*docheck)(struct fstab *),
235			int (*chkit)(char *, char *, long, int)));
236int		chkrange __P((ufs_daddr_t blk, int cnt));
237void		ckfini __P((int markclean));
238int		ckinode __P((struct dinode *dp, struct inodesc *));
239void		clri __P((struct inodesc *, char *type, int flag));
240void		direrror __P((ino_t ino, char *errmesg));
241int		dirscan __P((struct inodesc *));
242int		dofix __P((struct inodesc *, char *msg));
243void		ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
244void		ffs_fragacct __P((struct fs *, int, int32_t [], int));
245int		ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
246void		ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
247void		fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
248int		findino __P((struct inodesc *));
249int		findname __P((struct inodesc *));
250void		flush __P((int fd, struct bufarea *bp));
251void		freeblk __P((ufs_daddr_t blkno, long frags));
252void		freeino __P((ino_t ino));
253void		freeinodebuf __P((void));
254int		ftypeok __P((struct dinode *dp));
255void		getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
256struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
257struct inoinfo *getinoinfo __P((ino_t inumber));
258struct dinode  *getnextinode __P((ino_t inumber));
259void		getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
260struct dinode  *ginode __P((ino_t inumber));
261void		inocleanup __P((void));
262void		inodirty __P((void));
263int		linkup __P((ino_t orphan, ino_t parentdir));
264int		makeentry __P((ino_t parent, ino_t ino, char *name));
265void		panic __P((const char *fmt, ...));
266void		pass1 __P((void));
267void		pass1b __P((void));
268int		pass1check __P((struct inodesc *));
269void		pass2 __P((void));
270void		pass3 __P((void));
271void		pass4 __P((void));
272int		pass4check __P((struct inodesc *));
273void		pass5 __P((void));
274void		pfatal __P((const char *fmt, ...));
275void		pinode __P((ino_t ino));
276void		propagate __P((void));
277void		pwarn __P((const char *fmt, ...));
278int		reply __P((char *question));
279void		resetinodebuf __P((void));
280int		setup __P((char *dev));
281void		voidquit __P((int));
282