daddr_t => ufs_daddr_t
[unix-history] / usr / src / sys / ufs / lfs / lfs.h
CommitLineData
7168b5c1 1/*-
ad0f93d2
KB
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
7168b5c1
KB
4 *
5 * %sccs.include.redist.c%
6 *
89e2bb79 7 * @(#)lfs.h 8.8 (Berkeley) %G%
7168b5c1
KB
8 */
9
b6a5a267
KB
10#define LFS_LABELPAD 8192 /* LFS label size */
11#define LFS_SBPAD 8192 /* LFS superblock size */
7168b5c1 12
c4379551
KB
13/*
14 * XXX
15 * This is a kluge and NEEDS to go away.
16 *
17 * Right now, ufs code handles most of the calls for directory operations
18 * such as create, mkdir, link, etc. As a result VOP_UPDATE is being
19 * called with waitfor set (since ffs does these things synchronously).
20 * Since LFS does not want to do these synchronously, we treat the last
21 * argument to lfs_update as a set of flags. If LFS_SYNC is set, then
22 * the update should be synchronous, if not, do it asynchronously.
23 * Unfortunately, this means that LFS won't work with NFS yet because
24 * NFS goes through paths that will make normal calls to ufs which will
25 * call lfs with a last argument of 1.
26 */
27#define LFS_SYNC 0x02
28
0b4d6502 29/* On-disk and in-memory checkpoint segment usage structure. */
d5075120
KB
30typedef struct segusage SEGUSE;
31struct segusage {
993707aa
KM
32 u_int32_t su_nbytes; /* number of live bytes */
33 u_int32_t su_lastmod; /* SEGUSE last modified timestamp */
34 u_int16_t su_nsums; /* number of summaries in segment */
35 u_int16_t su_ninos; /* number of inode blocks in seg */
36
37#define SEGUSE_ACTIVE 0x01 /* segment is currently being written */
38#define SEGUSE_DIRTY 0x02 /* segment has data in it */
39#define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */
40 u_int32_t su_flags;
d5075120
KB
41};
42
2f387230 43#define SEGUPB(fs) (1 << (fs)->lfs_sushift)
cf5ef508 44#define SEGTABSIZE_SU(fs) \
2f387230 45 (((fs)->lfs_nseg + SEGUPB(fs) - 1) >> (fs)->lfs_sushift)
0c67132e 46
d5075120
KB
47/* On-disk file information. One per file with data blocks in the segment. */
48typedef struct finfo FINFO;
49struct finfo {
993707aa
KM
50 u_int32_t fi_nblocks; /* number of blocks */
51 u_int32_t fi_version; /* version number */
52 u_int32_t fi_ino; /* inode number */
89e2bb79 53 ufs_daddr_t fi_blocks[1]; /* array of logical block numbers */
d5075120
KB
54};
55
0b4d6502 56/* On-disk and in-memory super block. */
d5075120 57struct lfs {
113e98ad 58#define LFS_MAGIC 0x070162
993707aa 59 u_int32_t lfs_magic; /* magic number */
b6a5a267 60#define LFS_VERSION 1
993707aa 61 u_int32_t lfs_version; /* version number */
7168b5c1 62
993707aa
KM
63 u_int32_t lfs_size; /* number of blocks in fs */
64 u_int32_t lfs_ssize; /* number of blocks per segment */
65 u_int32_t lfs_dsize; /* number of disk blocks in fs */
66 u_int32_t lfs_bsize; /* file system block size */
67 u_int32_t lfs_fsize; /* size of frag blocks in fs */
68 u_int32_t lfs_frag; /* number of frags in a block in fs */
7168b5c1
KB
69
70/* Checkpoint region. */
993707aa
KM
71 ino_t lfs_free; /* start of the free list */
72 u_int32_t lfs_bfree; /* number of free disk blocks */
73 u_int32_t lfs_nfiles; /* number of allocated inodes */
74 int32_t lfs_avail; /* blocks available for writing */
75 u_int32_t lfs_uinodes; /* inodes in cache not yet on disk */
89e2bb79 76 ufs_daddr_t lfs_idaddr; /* inode file disk address */
993707aa 77 ino_t lfs_ifile; /* inode file inode number */
89e2bb79
KM
78 ufs_daddr_t lfs_lastseg; /* address of last segment written */
79 ufs_daddr_t lfs_nextseg; /* address of next segment to write */
80 ufs_daddr_t lfs_curseg; /* current segment being written */
81 ufs_daddr_t lfs_offset; /* offset in curseg for next partial */
82 ufs_daddr_t lfs_lastpseg; /* address of last partial written */
993707aa 83 u_int32_t lfs_tstamp; /* time stamp */
7168b5c1
KB
84
85/* These are configuration parameters. */
993707aa 86 u_int32_t lfs_minfree; /* minimum percentage of free blocks */
7168b5c1
KB
87
88/* These fields can be computed from the others. */
a63e2cc2 89 u_int64_t lfs_maxfilesize; /* maximum representable file size */
993707aa
KM
90 u_int32_t lfs_dbpseg; /* disk blocks per segment */
91 u_int32_t lfs_inopb; /* inodes per block */
92 u_int32_t lfs_ifpb; /* IFILE entries per block */
93 u_int32_t lfs_sepb; /* SEGUSE entries per block */
94 u_int32_t lfs_nindir; /* indirect pointers per block */
95 u_int32_t lfs_nseg; /* number of segments */
96 u_int32_t lfs_nspf; /* number of sectors per fragment */
97 u_int32_t lfs_cleansz; /* cleaner info size in blocks */
98 u_int32_t lfs_segtabsz; /* segment table size in blocks */
99
100 u_int32_t lfs_segmask; /* calculate offset within a segment */
101 u_int32_t lfs_segshift; /* fast mult/div for segments */
102 u_int32_t lfs_bmask; /* calc block offset from file offset */
103 u_int32_t lfs_bshift; /* calc block number from file offset */
104 u_int32_t lfs_ffmask; /* calc frag offset from file offset */
105 u_int32_t lfs_ffshift; /* fast mult/div for frag from file */
106 u_int32_t lfs_fbmask; /* calc frag offset from block offset */
107 u_int32_t lfs_fbshift; /* fast mult/div for frag from block */
108 u_int32_t lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
109 u_int32_t lfs_sushift; /* fast mult/div for segusage table */
110
111 int32_t lfs_maxsymlinklen; /* max length of an internal symlink */
7168b5c1 112
0b4d6502
KB
113#define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */
114#define LFS_MAXNUMSB 10 /* superblock disk offsets */
89e2bb79 115 ufs_daddr_t lfs_sboffs[LFS_MAXNUMSB];
993707aa
KM
116
117/* Checksum -- last valid disk field. */
118 u_int32_t lfs_cksum; /* checksum for superblock checking */
0b4d6502
KB
119
120/* These fields are set at mount time and are meaningless on disk. */
993707aa
KM
121 struct segment *lfs_sp; /* current segment being written */
122 struct vnode *lfs_ivnode; /* vnode for the ifile */
123 u_long lfs_seglock; /* single-thread the segment writer */
124 pid_t lfs_lockpid; /* pid of lock holder */
125 u_long lfs_iocount; /* number of ios pending */
126 u_long lfs_writer; /* don't allow any dirops to start */
127 u_long lfs_dirops; /* count of active directory ops */
128 u_long lfs_doifile; /* Write ifile blocks on next write */
129 u_long lfs_nactive; /* Number of segments since last ckp */
130 int8_t lfs_fmod; /* super block modified flag */
131 int8_t lfs_clean; /* file system is clean flag */
132 int8_t lfs_ronly; /* mounted read-only flag */
133 int8_t lfs_flags; /* currently unused flag */
134 u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */
d243d92d
KM
135
136 int32_t lfs_pad[40]; /* round to 512 bytes */
d5075120 137};
7168b5c1 138
0b4d6502 139/*
993707aa
KM
140 * Inode 0: out-of-band inode number
141 * Inode 1: IFILE inode number
142 * Inode 2: root inode
143 * Inode 3: lost+found inode number
0b4d6502 144 */
0c90e94d 145#define LFS_UNUSED_INUM 0 /* out of band inode number */
0d70dc17
KB
146#define LFS_IFILE_INUM 1 /* IFILE inode number */
147#define LOSTFOUNDINO 3 /* lost+found inode number */
148#define LFS_FIRST_INUM 4 /* first free inode number */
b6a5a267 149
0c67132e
KB
150/* Address calculations for metadata located in the inode */
151#define S_INDIR(fs) -NDADDR
5c4e1af0
CS
152#define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1)
153#define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1)
0c67132e 154
39cabb59
KB
155/* Unassigned disk address. */
156#define UNASSIGNED -1
157
cb87447c
KB
158/* Unused logical block number */
159#define LFS_UNUSED_LBN -1
160
d5075120
KB
161typedef struct ifile IFILE;
162struct ifile {
993707aa 163 u_int32_t if_version; /* inode version number */
0b4d6502 164#define LFS_UNUSED_DADDR 0 /* out-of-band daddr */
89e2bb79 165 ufs_daddr_t if_daddr; /* inode disk address */
993707aa 166 ino_t if_nextfree; /* next-unallocated inode */
d5075120 167};
7168b5c1 168
0c67132e
KB
169/*
170 * Cleaner information structure. This resides in the ifile and is used
171 * to pass information between the cleaner and the kernel.
172 */
173typedef struct _cleanerinfo {
993707aa
KM
174 u_int32_t clean; /* K: number of clean segments */
175 u_int32_t dirty; /* K: number of dirty segments */
0c67132e 176} CLEANERINFO;
7168b5c1 177
cf5ef508 178#define CLEANSIZE_SU(fs) \
0c67132e 179 ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift)
b6a5a267 180
b6a5a267
KB
181/*
182 * All summary blocks are the same size, so we can always read a summary
0c90e94d 183 * block easily from a segment.
b6a5a267
KB
184 */
185#define LFS_SUMMARY_SIZE 512
186
7168b5c1 187/* On-disk segment summary information */
d5075120
KB
188typedef struct segsum SEGSUM;
189struct segsum {
993707aa
KM
190 u_int32_t ss_sumsum; /* check sum of summary block */
191 u_int32_t ss_datasum; /* check sum of data */
89e2bb79 192 ufs_daddr_t ss_next; /* next segment */
993707aa
KM
193 u_int32_t ss_create; /* creation time stamp */
194 u_int16_t ss_nfinfo; /* number of file info structures */
195 u_int16_t ss_ninos; /* number of inodes in summary */
196
3ce71481
KB
197#define SS_DIROP 0x01 /* segment begins a dirop */
198#define SS_CONT 0x02 /* more partials to finish this write*/
993707aa
KM
199 u_int16_t ss_flags; /* used for directory operations */
200 u_int16_t ss_pad; /* extra space */
d3b72332 201 /* FINFO's and inode daddr's... */
d5075120 202};
7168b5c1 203
0b4d6502
KB
204/* NINDIR is the number of indirects in a file system block. */
205#define NINDIR(fs) ((fs)->lfs_nindir)
206
207/* INOPB is the number of inodes in a secondary storage block. */
208#define INOPB(fs) ((fs)->lfs_inopb)
209
0b4d6502
KB
210#define blksize(fs) ((fs)->lfs_bsize)
211#define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask)
212#define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb)
d9839b30 213#define dbtofsb(fs, b) ((b) >> (fs)->lfs_fsbtodb)
0b4d6502
KB
214#define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift)
215#define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift)
cf5ef508 216#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
d5075120 217 ((loc) >> (fs)->lfs_bshift)
39cabb59 218
cf5ef508 219#define datosn(fs, daddr) /* disk address to segment number */ \
0d70dc17 220 (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize))
cf5ef508 221#define sntoda(fs, sn) /* segment number to disk address */ \
89e2bb79 222 ((ufs_daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \
0d70dc17
KB
223 (fs)->lfs_sboffs[0]))
224
59526076 225/* Read in the block with the cleaner info from the ifile. */
cf5ef508
KB
226#define LFS_CLEANERINFO(CP, F, BP) { \
227 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
228 if (bread((F)->lfs_ivnode, \
89e2bb79 229 (ufs_daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \
cf5ef508
KB
230 panic("lfs: ifile read"); \
231 (CP) = (CLEANERINFO *)(BP)->b_data; \
59526076
KB
232}
233
0c67132e 234/* Read in the block with a specific inode from the ifile. */
cf5ef508
KB
235#define LFS_IENTRY(IP, F, IN, BP) { \
236 int _e; \
237 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
238 if (_e = bread((F)->lfs_ivnode, \
239 (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz,\
240 (F)->lfs_bsize, NOCRED, &(BP))) \
241 panic("lfs: ifile read %d", _e); \
242 (IP) = (IFILE *)(BP)->b_data + (IN) % (F)->lfs_ifpb; \
a9322048
KB
243}
244
0c67132e 245/* Read in the block with a specific segment usage entry from the ifile. */
cf5ef508
KB
246#define LFS_SEGENTRY(SP, F, IN, BP) { \
247 int _e; \
248 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
249 if (_e = bread((F)->lfs_ivnode, \
250 ((IN) >> (F)->lfs_sushift) + (F)->lfs_cleansz, \
251 (F)->lfs_bsize, NOCRED, &(BP))) \
252 panic("lfs: ifile read: %d", _e); \
253 (SP) = (SEGUSE *)(BP)->b_data + ((IN) & (F)->lfs_sepb - 1); \
0c67132e
KB
254}
255
cb87447c
KB
256/*
257 * Determine if there is enough room currently available to write db
258 * disk blocks. We need enough blocks for the new blocks, the current,
259 * inode blocks, a summary block, plus potentially the ifile inode and
260 * the segment usage table, plus an ifile page.
261 */
262#define LFS_FITS(fs, db) \
993707aa
KM
263 ((int32_t)((db + ((fs)->lfs_uinodes + INOPB((fs))) / \
264 INOPB((fs)) + fsbtodb(fs, 1) + LFS_SUMMARY_SIZE / DEV_BSIZE + \
cf5ef508 265 (fs)->lfs_segtabsz)) < (fs)->lfs_avail)
5ec8c51e 266
cb87447c
KB
267/* Determine if a buffer belongs to the ifile */
268#define IS_IFILE(bp) (VTOI(bp->b_vp)->i_number == LFS_IFILE_INUM)
cf5ef508 269
0c67132e
KB
270/*
271 * Structures used by lfs_bmapv and lfs_markv to communicate information
272 * about inodes and data blocks.
273 */
274typedef struct block_info {
275 ino_t bi_inode; /* inode # */
89e2bb79
KM
276 ufs_daddr_t bi_lbn; /* logical block w/in file */
277 ufs_daddr_t bi_daddr; /* disk address of block */
0c67132e 278 time_t bi_segcreate; /* origin segment create time */
0408cf24 279 int bi_version; /* file version number */
0c67132e
KB
280 void *bi_bp; /* data buffer */
281} BLOCK_INFO;
282
cb87447c
KB
283/* In-memory description of a segment about to be written. */
284struct segment {
993707aa 285 struct lfs *fs; /* file system pointer */
cb87447c
KB
286 struct buf **bpp; /* pointer to buffer array */
287 struct buf **cbpp; /* pointer to next available bp */
288 struct buf **start_bpp; /* pointer to first bp in this set */
993707aa
KM
289 struct buf *ibp; /* buffer pointer to inode page */
290 struct finfo *fip; /* current fileinfo pointer */
291 struct vnode *vp; /* vnode being gathered */
292 void *segsum; /* segment summary info */
293 u_int32_t ninodes; /* number of inodes in this segment */
294 u_int32_t seg_bytes_left; /* bytes left in segment */
295 u_int32_t sum_bytes_left; /* bytes left in summary block */
296 u_int32_t seg_number; /* number of this segment */
89e2bb79 297 ufs_daddr_t *start_lbp; /* beginning lbn for this set */
993707aa 298
cb87447c
KB
299#define SEGM_CKP 0x01 /* doing a checkpoint */
300#define SEGM_CLEAN 0x02 /* cleaner call; don't sort */
2a04b8fe 301#define SEGM_SYNC 0x04 /* wait for segment */
993707aa 302 u_int16_t seg_flags; /* run-time flags for this segment */
cb87447c 303};
17ed88a2 304
cf5ef508
KB
305#define ISSPACE(F, BB, C) \
306 (((C)->cr_uid == 0 && (F)->lfs_bfree >= (BB)) || \
17ed88a2
MS
307 ((C)->cr_uid != 0 && IS_FREESPACE(F, BB)))
308
cf5ef508 309#define IS_FREESPACE(F, BB) \
17ed88a2
MS
310 ((F)->lfs_bfree > ((F)->lfs_dsize * (F)->lfs_minfree / 100 + (BB)))
311
cf5ef508 312#define ISSPACE_XXX(F, BB) \
17ed88a2
MS
313 ((F)->lfs_bfree >= (BB))
314
2a04b8fe
MS
315#define DOSTATS
316#ifdef DOSTATS
317/* Statistics Counters */
318struct lfs_stats {
993707aa
KM
319 u_int segsused;
320 u_int psegwrites;
321 u_int psyncwrites;
322 u_int pcleanwrites;
323 u_int blocktot;
324 u_int cleanblocks;
325 u_int ncheckpoints;
326 u_int nwrites;
327 u_int nsync_writes;
328 u_int wait_exceeded;
329 u_int write_exceeded;
330 u_int flush_invoked;
2a04b8fe
MS
331};
332extern struct lfs_stats lfs_stats;
333#endif