1 /* $NetBSD: lfs.h,v 1.95 2005/12/11 12:25:26 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Konrad E. Schroder <perseant@hhhh.org>. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 /*- 39 * Copyright (c) 1991, 1993 40 * The Regents of the University of California. All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. Neither the name of the University nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * @(#)lfs.h 8.9 (Berkeley) 5/8/95 67 */ 68 69 #ifndef _UFS_LFS_LFS_H_ 70 #define _UFS_LFS_LFS_H_ 71 72 /* 73 * Compile-time options for LFS. 74 */ 75 #define LFS_IFIND_RETRIES 16 76 #define LFS_LOGLENGTH 1024 /* size of debugging log */ 77 #define LFS_MAX_ACTIVE 10 /* Dirty segments before ckp forced */ 78 79 /* 80 * Fixed filesystem layout parameters 81 */ 82 #define LFS_LABELPAD 8192 /* LFS label size */ 83 #define LFS_SBPAD 8192 /* LFS superblock size */ 84 85 #define LFS_UNUSED_INUM 0 /* 0: out of band inode number */ 86 #define LFS_IFILE_INUM 1 /* 1: IFILE inode number */ 87 /* 2: Root inode number */ 88 #define LOSTFOUNDINO 3 /* 3: lost+found inode number */ 89 #define LFS_FIRST_INUM 4 /* 4: first free inode number */ 90 91 #define LFS_V1_SUMMARY_SIZE 512 /* V1 fixed summary size */ 92 #define LFS_DFL_SUMMARY_SIZE 512 /* Default summary size */ 93 94 #define LFS_MAX_DADDR 0x7fffffff /* Highest addressable fsb */ 95 96 #define LFS_MAXNAMLEN 255 /* maximum name length in a dir */ 97 98 /* Adjustable filesystem parameters */ 99 #define MIN_FREE_SEGS 2 100 #ifndef LFS_ATIME_IFILE 101 # define LFS_ATIME_IFILE 0 /* Store atime info in ifile (optional in LFSv1) */ 102 #endif 103 #define LFS_MARKV_MAXBLKCNT 65536 /* Max block count for lfs_markv() */ 104 105 /* Misc. definitions */ 106 #define BW_CLEAN 1 /* Flag for lfs_bwrite_ext() */ 107 #define PG_DELWRI PG_PAGER1 /* Local def for delayed pageout */ 108 109 /* Resource limits */ 110 #define LFS_MAX_BUFS ((nbuf >> 2) - 10) 111 #define LFS_WAIT_BUFS ((nbuf >> 1) - (nbuf >> 3) - 10) 112 #define LFS_INVERSE_MAX_BUFS(n) (((n) + 10) << 2) 113 #define LFS_MAX_BYTES ((bufmem_lowater >> 2) - 10 * PAGE_SIZE) 114 #define LFS_INVERSE_MAX_BYTES(n) (((n) + 10 * PAGE_SIZE) << 2) 115 #define LFS_WAIT_BYTES ((bufmem_lowater >> 1) - (bufmem_lowater >> 3) - 10 * PAGE_SIZE) 116 #define LFS_MAX_DIROP ((desiredvnodes >> 2) + (desiredvnodes >> 3)) 117 #define LFS_MAX_PAGES \ 118 (((uvmexp.active + uvmexp.inactive + uvmexp.free) * uvmexp.filemin) >> 8) 119 #define LFS_WAIT_PAGES \ 120 (((uvmexp.active + uvmexp.inactive + uvmexp.free) * uvmexp.filemax) >> 8) 121 #define LFS_BUFWAIT 2 /* How long to wait if over *_WAIT_* */ 122 123 /* 124 * Reserved blocks for lfs_malloc 125 */ 126 127 /* Structure to keep reserved blocks */ 128 typedef struct lfs_res_blk { 129 void *p; 130 LIST_ENTRY(lfs_res_blk) res; 131 int size; 132 char inuse; 133 } res_t; 134 135 /* Types for lfs_newbuf and lfs_malloc */ 136 #define LFS_NB_UNKNOWN -1 137 #define LFS_NB_SUMMARY 0 138 #define LFS_NB_SBLOCK 1 139 #define LFS_NB_IBLOCK 2 140 #define LFS_NB_CLUSTER 3 141 #define LFS_NB_CLEAN 4 142 #define LFS_NB_BLKIOV 5 143 #define LFS_NB_COUNT 6 /* always last */ 144 145 /* Number of reserved memory blocks of each type */ 146 #define LFS_N_SUMMARIES 2 147 #define LFS_N_SBLOCKS 1 /* Always 1, to throttle superblock writes */ 148 #define LFS_N_IBLOCKS 16 /* In theory ssize/bsize; in practice around 2 */ 149 #define LFS_N_CLUSTERS 16 /* In theory ssize/MAXPHYS */ 150 #define LFS_N_CLEAN 0 151 #define LFS_N_BLKIOV 1 152 153 /* Total count of "large" (non-pool) types */ 154 #define LFS_N_TOTAL (LFS_N_SUMMARIES + LFS_N_SBLOCKS + LFS_N_IBLOCKS + \ 155 LFS_N_CLUSTERS + LFS_N_CLEAN + LFS_N_BLKIOV) 156 157 /* Counts for pool types */ 158 #define LFS_N_CL LFS_N_CLUSTERS 159 #define LFS_N_BPP 2 160 #define LFS_N_SEG 2 161 162 /* 163 * "struct buf" associated definitions 164 */ 165 166 /* Unassigned disk addresses. */ 167 #define UNASSIGNED -1 168 #define UNWRITTEN -2 169 170 /* Unused logical block number */ 171 #define LFS_UNUSED_LBN -1 172 173 /* Determine if a buffer belongs to the ifile */ 174 #define IS_IFILE(bp) (VTOI(bp->b_vp)->i_number == LFS_IFILE_INUM) 175 176 # define LFS_LOCK_BUF(bp) do { \ 177 if (((bp)->b_flags & (B_LOCKED | B_CALL)) == 0) { \ 178 simple_lock(&lfs_subsys_lock); \ 179 ++locked_queue_count; \ 180 locked_queue_bytes += bp->b_bufsize; \ 181 simple_unlock(&lfs_subsys_lock); \ 182 } \ 183 (bp)->b_flags |= B_LOCKED; \ 184 } while (0) 185 186 # define LFS_UNLOCK_BUF(bp) do { \ 187 if (((bp)->b_flags & (B_LOCKED | B_CALL)) == B_LOCKED) { \ 188 simple_lock(&lfs_subsys_lock); \ 189 --locked_queue_count; \ 190 locked_queue_bytes -= bp->b_bufsize; \ 191 if (locked_queue_count < LFS_WAIT_BUFS && \ 192 locked_queue_bytes < LFS_WAIT_BYTES) \ 193 wakeup(&locked_queue_count); \ 194 simple_unlock(&lfs_subsys_lock); \ 195 } \ 196 (bp)->b_flags &= ~B_LOCKED; \ 197 } while (0) 198 199 #ifdef _KERNEL 200 201 extern u_long bufmem_lowater, bufmem_hiwater; /* XXX */ 202 203 # define LFS_IS_MALLOC_BUF(bp) (((bp)->b_flags & B_CALL) && \ 204 (bp)->b_iodone == lfs_callback) 205 206 # ifdef DEBUG 207 # define LFS_DEBUG_COUNTLOCKED(m) do { \ 208 if (lfs_debug_log_subsys[DLOG_LLIST]) { \ 209 lfs_countlocked(&locked_queue_count, &locked_queue_bytes, (m)); \ 210 wakeup(&locked_queue_count); \ 211 } \ 212 } while (0) 213 # else 214 # define LFS_DEBUG_COUNTLOCKED(m) 215 # endif 216 217 /* log for debugging writes to the Ifile */ 218 # ifdef DEBUG 219 struct lfs_log_entry { 220 const char *op; 221 const char *file; 222 int pid; 223 int line; 224 daddr_t block; 225 unsigned long flags; 226 }; 227 extern int lfs_lognum; 228 extern struct lfs_log_entry lfs_log[LFS_LOGLENGTH]; 229 # define LFS_BWRITE_LOG(bp) lfs_bwrite_log((bp), __FILE__, __LINE__) 230 # define LFS_ENTER_LOG(theop, thefile, theline, lbn, theflags, thepid) do {\ 231 int _s; \ 232 \ 233 simple_lock(&lfs_subsys_lock); \ 234 _s = splbio(); \ 235 lfs_log[lfs_lognum].op = theop; \ 236 lfs_log[lfs_lognum].file = thefile; \ 237 lfs_log[lfs_lognum].line = (theline); \ 238 lfs_log[lfs_lognum].pid = (thepid); \ 239 lfs_log[lfs_lognum].block = (lbn); \ 240 lfs_log[lfs_lognum].flags = (theflags); \ 241 lfs_lognum = (lfs_lognum + 1) % LFS_LOGLENGTH; \ 242 splx(_s); \ 243 simple_unlock(&lfs_subsys_lock); \ 244 } while (0) 245 246 # define LFS_BCLEAN_LOG(fs, bp) do { \ 247 if ((bp)->b_vp == (fs)->lfs_ivnode) \ 248 LFS_ENTER_LOG("clear", __FILE__, __LINE__, \ 249 bp->b_lblkno, bp->b_flags, curproc->p_pid);\ 250 } while (0) 251 252 /* Must match list in lfs_vfsops.c ! */ 253 # define DLOG_RF 0 /* roll forward */ 254 # define DLOG_ALLOC 1 /* inode alloc */ 255 # define DLOG_AVAIL 2 /* lfs_{,r,f}avail */ 256 # define DLOG_FLUSH 3 /* flush */ 257 # define DLOG_LLIST 4 /* locked list accounting */ 258 # define DLOG_WVNODE 5 /* vflush/writevnodes verbose */ 259 # define DLOG_VNODE 6 /* vflush/writevnodes */ 260 # define DLOG_SEG 7 /* segwrite */ 261 # define DLOG_SU 8 /* seguse accounting */ 262 # define DLOG_CLEAN 9 /* cleaner routines */ 263 # define DLOG_MOUNT 10 /* mount/unmount */ 264 # define DLOG_PAGE 11 /* putpages/gop_write */ 265 # define DLOG_DIROP 12 /* dirop accounting */ 266 # define DLOG_MALLOC 13 /* lfs_malloc accounting */ 267 # define DLOG_MAX 14 /* The terminator */ 268 # define DLOG(a) lfs_debug_log a 269 # else /* ! DEBUG */ 270 # define LFS_BCLEAN_LOG(fs, bp) 271 # define LFS_BWRITE_LOG(bp) VOP_BWRITE((bp)) 272 # define DLOG(a) 273 # endif /* ! DEBUG */ 274 #else /* ! _KERNEL */ 275 # define LFS_BWRITE_LOG(bp) VOP_BWRITE((bp)) 276 #endif /* _KERNEL */ 277 278 #ifdef _KERNEL 279 /* Filehandle structure for exported LFSes */ 280 struct lfid { 281 struct ufid lfid_ufid; 282 #define lfid_len lfid_ufid.ufid_len 283 #define lfid_ino lfid_ufid.ufid_ino 284 #define lfid_gen lfid_ufid.ufid_gen 285 uint32_t lfid_ident; 286 }; 287 #endif /* _KERNEL */ 288 289 /* 290 * "struct inode" associated definitions 291 */ 292 293 /* Address calculations for metadata located in the inode */ 294 #define S_INDIR(fs) -NDADDR 295 #define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1) 296 #define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1) 297 298 /* For convenience */ 299 #define IN_ALLMOD (IN_MODIFIED|IN_ACCESS|IN_CHANGE|IN_UPDATE|IN_MODIFY|IN_ACCESSED|IN_CLEANING) 300 301 #define LFS_SET_UINO(ip, flags) do { \ 302 simple_lock(&(ip)->i_lfs->lfs_interlock); \ 303 if (((flags) & IN_ACCESSED) && !((ip)->i_flag & IN_ACCESSED)) \ 304 ++(ip)->i_lfs->lfs_uinodes; \ 305 if (((flags) & IN_CLEANING) && !((ip)->i_flag & IN_CLEANING)) \ 306 ++(ip)->i_lfs->lfs_uinodes; \ 307 if (((flags) & IN_MODIFIED) && !((ip)->i_flag & IN_MODIFIED)) \ 308 ++(ip)->i_lfs->lfs_uinodes; \ 309 (ip)->i_flag |= (flags); \ 310 simple_unlock(&(ip)->i_lfs->lfs_interlock); \ 311 } while (0) 312 313 #define LFS_CLR_UINO(ip, flags) do { \ 314 simple_lock(&(ip)->i_lfs->lfs_interlock); \ 315 if (((flags) & IN_ACCESSED) && ((ip)->i_flag & IN_ACCESSED)) \ 316 --(ip)->i_lfs->lfs_uinodes; \ 317 if (((flags) & IN_CLEANING) && ((ip)->i_flag & IN_CLEANING)) \ 318 --(ip)->i_lfs->lfs_uinodes; \ 319 if (((flags) & IN_MODIFIED) && ((ip)->i_flag & IN_MODIFIED)) \ 320 --(ip)->i_lfs->lfs_uinodes; \ 321 (ip)->i_flag &= ~(flags); \ 322 if ((ip)->i_lfs->lfs_uinodes < 0) { \ 323 panic("lfs_uinodes < 0"); \ 324 } \ 325 simple_unlock(&(ip)->i_lfs->lfs_interlock); \ 326 } while (0) 327 328 #define LFS_ITIMES(ip, acc, mod, cre) \ 329 while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \ 330 lfs_itimes(ip, acc, mod, cre) 331 332 /* 333 * "struct vnode" associated definitions 334 */ 335 336 /* Heuristic emptiness measure */ 337 #define VPISEMPTY(vp) (LIST_EMPTY(&(vp)->v_dirtyblkhd) && \ 338 !((vp)->v_flag & VONWORKLST) && \ 339 VTOI(vp)->i_lfs_nbtree == 0) 340 341 /* XXX Shouldn't we use v_numoutput instead? */ 342 #define WRITEINPROG(vp) (!LIST_EMPTY(&(vp)->v_dirtyblkhd) && \ 343 !(VTOI(vp)->i_flag & (IN_MODIFIED | IN_ACCESSED | IN_CLEANING))) 344 345 346 /* 347 * On-disk and in-memory checkpoint segment usage structure. 348 */ 349 typedef struct segusage SEGUSE; 350 struct segusage { 351 u_int32_t su_nbytes; /* 0: number of live bytes */ 352 u_int32_t su_olastmod; /* 4: SEGUSE last modified timestamp */ 353 u_int16_t su_nsums; /* 8: number of summaries in segment */ 354 u_int16_t su_ninos; /* 10: number of inode blocks in seg */ 355 356 #define SEGUSE_ACTIVE 0x01 /* segment currently being written */ 357 #define SEGUSE_DIRTY 0x02 /* segment has data in it */ 358 #define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */ 359 #define SEGUSE_ERROR 0x08 /* cleaner: do not clean segment */ 360 #define SEGUSE_EMPTY 0x10 /* segment is empty */ 361 #define SEGUSE_INVAL 0x20 /* segment is invalid */ 362 u_int32_t su_flags; /* 12: segment flags */ 363 u_int64_t su_lastmod; /* 16: last modified timestamp */ 364 }; 365 366 typedef struct segusage_v1 SEGUSE_V1; 367 struct segusage_v1 { 368 u_int32_t su_nbytes; /* 0: number of live bytes */ 369 u_int32_t su_lastmod; /* 4: SEGUSE last modified timestamp */ 370 u_int16_t su_nsums; /* 8: number of summaries in segment */ 371 u_int16_t su_ninos; /* 10: number of inode blocks in seg */ 372 u_int32_t su_flags; /* 12: segment flags */ 373 }; 374 375 #define SEGUPB(fs) (fs->lfs_sepb) 376 #define SEGTABSIZE_SU(fs) \ 377 (((fs)->lfs_nseg + SEGUPB(fs) - 1) / (fs)->lfs_sepb) 378 379 #ifdef _KERNEL 380 # define SHARE_IFLOCK(F) \ 381 do { \ 382 simple_lock(&(F)->lfs_interlock); \ 383 lockmgr(&(F)->lfs_iflock, LK_SHARED, &(F)->lfs_interlock); \ 384 simple_unlock(&(F)->lfs_interlock); \ 385 } while(0) 386 # define UNSHARE_IFLOCK(F) \ 387 do { \ 388 simple_lock(&(F)->lfs_interlock); \ 389 lockmgr(&(F)->lfs_iflock, LK_RELEASE, &(F)->lfs_interlock); \ 390 simple_unlock(&(F)->lfs_interlock); \ 391 } while(0) 392 #else /* ! _KERNEL */ 393 # define SHARE_IFLOCK(F) 394 # define UNSHARE_IFLOCK(F) 395 #endif /* ! _KERNEL */ 396 397 /* Read in the block with a specific segment usage entry from the ifile. */ 398 #define LFS_SEGENTRY(SP, F, IN, BP) do { \ 399 int _e; \ 400 SHARE_IFLOCK(F); \ 401 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \ 402 if ((_e = bread((F)->lfs_ivnode, \ 403 ((IN) / (F)->lfs_sepb) + (F)->lfs_cleansz, \ 404 (F)->lfs_bsize, NOCRED, &(BP))) != 0) \ 405 panic("lfs: ifile read: %d", _e); \ 406 if ((F)->lfs_version == 1) \ 407 (SP) = (SEGUSE *)((SEGUSE_V1 *)(BP)->b_data + \ 408 ((IN) & ((F)->lfs_sepb - 1))); \ 409 else \ 410 (SP) = (SEGUSE *)(BP)->b_data + ((IN) % (F)->lfs_sepb); \ 411 UNSHARE_IFLOCK(F); \ 412 } while (0) 413 414 #define LFS_WRITESEGENTRY(SP, F, IN, BP) do { \ 415 if ((SP)->su_nbytes == 0) \ 416 (SP)->su_flags |= SEGUSE_EMPTY; \ 417 else \ 418 (SP)->su_flags &= ~SEGUSE_EMPTY; \ 419 (F)->lfs_suflags[(F)->lfs_activesb][(IN)] = (SP)->su_flags; \ 420 LFS_BWRITE_LOG(BP); \ 421 } while (0) 422 423 /* 424 * On-disk file information. One per file with data blocks in the segment. 425 */ 426 typedef struct finfo FINFO; 427 struct finfo { 428 u_int32_t fi_nblocks; /* number of blocks */ 429 u_int32_t fi_version; /* version number */ 430 u_int32_t fi_ino; /* inode number */ 431 u_int32_t fi_lastlength; /* length of last block in array */ 432 int32_t fi_blocks[1]; /* array of logical block numbers */ 433 }; 434 /* sizeof FINFO except fi_blocks */ 435 #define FINFOSIZE (sizeof(FINFO) - sizeof(int32_t)) 436 437 /* 438 * Index file inode entries. 439 */ 440 typedef struct ifile IFILE; 441 struct ifile { 442 u_int32_t if_version; /* inode version number */ 443 #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 444 int32_t if_daddr; /* inode disk address */ 445 u_int32_t if_nextfree; /* next-unallocated inode */ 446 u_int32_t if_atime_sec; /* Last access time, seconds */ 447 u_int32_t if_atime_nsec; /* and nanoseconds */ 448 }; 449 450 typedef struct ifile_v1 IFILE_V1; 451 struct ifile_v1 { 452 u_int32_t if_version; /* inode version number */ 453 int32_t if_daddr; /* inode disk address */ 454 u_int32_t if_nextfree; /* next-unallocated inode */ 455 #if LFS_ATIME_IFILE 456 struct timespec if_atime; /* Last access time */ 457 #endif 458 }; 459 460 /* 461 * LFSv1 compatibility code is not allowed to touch if_atime, since it 462 * may not be mapped! 463 */ 464 /* Read in the block with a specific inode from the ifile. */ 465 #define LFS_IENTRY(IP, F, IN, BP) do { \ 466 int _e; \ 467 SHARE_IFLOCK(F); \ 468 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \ 469 if ((_e = bread((F)->lfs_ivnode, \ 470 (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 471 (F)->lfs_bsize, NOCRED, &(BP))) != 0) \ 472 panic("lfs: ifile read %d", _e); \ 473 if ((F)->lfs_version == 1) \ 474 (IP) = (IFILE *)((IFILE_V1 *)(BP)->b_data + \ 475 (IN) % (F)->lfs_ifpb); \ 476 else \ 477 (IP) = (IFILE *)(BP)->b_data + (IN) % (F)->lfs_ifpb; \ 478 UNSHARE_IFLOCK(F); \ 479 } while (0) 480 481 /* 482 * Cleaner information structure. This resides in the ifile and is used 483 * to pass information from the kernel to the cleaner. 484 */ 485 typedef struct _cleanerinfo { 486 u_int32_t clean; /* number of clean segments */ 487 u_int32_t dirty; /* number of dirty segments */ 488 int32_t bfree; /* disk blocks free */ 489 int32_t avail; /* disk blocks available */ 490 u_int32_t free_head; /* head of the inode free list */ 491 u_int32_t free_tail; /* tail of the inode free list */ 492 } CLEANERINFO; 493 494 #define CLEANSIZE_SU(fs) \ 495 ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift) 496 497 /* Read in the block with the cleaner info from the ifile. */ 498 #define LFS_CLEANERINFO(CP, F, BP) do { \ 499 SHARE_IFLOCK(F); \ 500 VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \ 501 if (bread((F)->lfs_ivnode, \ 502 (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 503 panic("lfs: ifile read"); \ 504 (CP) = (CLEANERINFO *)(BP)->b_data; \ 505 UNSHARE_IFLOCK(F); \ 506 } while (0) 507 508 /* 509 * Synchronize the Ifile cleaner info with current avail and bfree. 510 */ 511 #define LFS_SYNC_CLEANERINFO(cip, fs, bp, w) do { \ 512 simple_lock(&(fs)->lfs_interlock); \ 513 if ((w) || (cip)->bfree != (fs)->lfs_bfree || \ 514 (cip)->avail != (fs)->lfs_avail - (fs)->lfs_ravail - \ 515 (fs)->lfs_favail) { \ 516 (cip)->bfree = (fs)->lfs_bfree; \ 517 (cip)->avail = (fs)->lfs_avail - (fs)->lfs_ravail - \ 518 (fs)->lfs_favail; \ 519 if (((bp)->b_flags & B_GATHERED) == 0) { \ 520 (fs)->lfs_flags |= LFS_IFDIRTY; \ 521 } \ 522 simple_unlock(&(fs)->lfs_interlock); \ 523 (void) LFS_BWRITE_LOG(bp); /* Ifile */ \ 524 } else { \ 525 simple_unlock(&(fs)->lfs_interlock); \ 526 brelse(bp); \ 527 } \ 528 } while (0) 529 530 /* 531 * Get the head of the inode free list. 532 * Always caled with the segment lock held. 533 */ 534 #define LFS_GET_HEADFREE(FS, CIP, BP, FREEP) do { \ 535 if ((FS)->lfs_version > 1) { \ 536 LFS_CLEANERINFO((CIP), (FS), (BP)); \ 537 (FS)->lfs_freehd = (CIP)->free_head; \ 538 brelse(BP); \ 539 } \ 540 *(FREEP) = (FS)->lfs_freehd; \ 541 } while (0) 542 543 #define LFS_PUT_HEADFREE(FS, CIP, BP, VAL) do { \ 544 (FS)->lfs_freehd = (VAL); \ 545 if ((FS)->lfs_version > 1) { \ 546 LFS_CLEANERINFO((CIP), (FS), (BP)); \ 547 (CIP)->free_head = (VAL); \ 548 LFS_BWRITE_LOG(BP); \ 549 simple_lock(&fs->lfs_interlock); \ 550 (FS)->lfs_flags |= LFS_IFDIRTY; \ 551 simple_unlock(&fs->lfs_interlock); \ 552 } \ 553 } while (0) 554 555 #define LFS_GET_TAILFREE(FS, CIP, BP, FREEP) do { \ 556 LFS_CLEANERINFO((CIP), (FS), (BP)); \ 557 *(FREEP) = (CIP)->free_tail; \ 558 brelse(BP); \ 559 } while (0) 560 561 #define LFS_PUT_TAILFREE(FS, CIP, BP, VAL) do { \ 562 LFS_CLEANERINFO((CIP), (FS), (BP)); \ 563 (CIP)->free_tail = (VAL); \ 564 LFS_BWRITE_LOG(BP); \ 565 simple_lock(&fs->lfs_interlock); \ 566 (FS)->lfs_flags |= LFS_IFDIRTY; \ 567 simple_unlock(&fs->lfs_interlock); \ 568 } while (0) 569 570 /* 571 * On-disk segment summary information 572 */ 573 typedef struct segsum_v1 SEGSUM_V1; 574 struct segsum_v1 { 575 u_int32_t ss_sumsum; /* 0: check sum of summary block */ 576 u_int32_t ss_datasum; /* 4: check sum of data */ 577 u_int32_t ss_magic; /* 8: segment summary magic number */ 578 #define SS_MAGIC 0x061561 579 int32_t ss_next; /* 12: next segment */ 580 u_int32_t ss_create; /* 16: creation time stamp */ 581 u_int16_t ss_nfinfo; /* 20: number of file info structures */ 582 u_int16_t ss_ninos; /* 22: number of inodes in summary */ 583 584 #define SS_DIROP 0x01 /* segment begins a dirop */ 585 #define SS_CONT 0x02 /* more partials to finish this write*/ 586 u_int16_t ss_flags; /* 24: used for directory operations */ 587 u_int16_t ss_pad; /* 26: extra space */ 588 /* FINFO's and inode daddr's... */ 589 }; 590 591 typedef struct segsum SEGSUM; 592 struct segsum { 593 u_int32_t ss_sumsum; /* 0: check sum of summary block */ 594 u_int32_t ss_datasum; /* 4: check sum of data */ 595 u_int32_t ss_magic; /* 8: segment summary magic number */ 596 int32_t ss_next; /* 12: next segment */ 597 u_int32_t ss_ident; /* 16: roll-forward fsid */ 598 #define ss_ocreate ss_ident /* ident is where create was in v1 */ 599 u_int16_t ss_nfinfo; /* 20: number of file info structures */ 600 u_int16_t ss_ninos; /* 22: number of inodes in summary */ 601 u_int16_t ss_flags; /* 24: used for directory operations */ 602 u_int8_t ss_pad[6]; /* 26: extra space */ 603 u_int64_t ss_serial; /* 32: serial number */ 604 u_int64_t ss_create; /* 40: time stamp */ 605 /* FINFO's and inode daddr's... */ 606 }; 607 608 #define SEGSUM_SIZE(fs) ((fs)->lfs_version == 1 ? sizeof(SEGSUM_V1) : sizeof(SEGSUM)) 609 610 611 /* 612 * On-disk super block. 613 */ 614 struct dlfs { 615 #define LFS_MAGIC 0x070162 616 u_int32_t dlfs_magic; /* 0: magic number */ 617 #define LFS_VERSION 2 618 u_int32_t dlfs_version; /* 4: version number */ 619 620 u_int32_t dlfs_size; /* 8: number of blocks in fs (v1) */ 621 /* number of frags in fs (v2) */ 622 u_int32_t dlfs_ssize; /* 12: number of blocks per segment (v1) */ 623 /* number of bytes per segment (v2) */ 624 u_int32_t dlfs_dsize; /* 16: number of disk blocks in fs */ 625 u_int32_t dlfs_bsize; /* 20: file system block size */ 626 u_int32_t dlfs_fsize; /* 24: size of frag blocks in fs */ 627 u_int32_t dlfs_frag; /* 28: number of frags in a block in fs */ 628 629 /* Checkpoint region. */ 630 u_int32_t dlfs_freehd; /* 32: start of the free list */ 631 int32_t dlfs_bfree; /* 36: number of free disk blocks */ 632 u_int32_t dlfs_nfiles; /* 40: number of allocated inodes */ 633 int32_t dlfs_avail; /* 44: blocks available for writing */ 634 int32_t dlfs_uinodes; /* 48: inodes in cache not yet on disk */ 635 int32_t dlfs_idaddr; /* 52: inode file disk address */ 636 u_int32_t dlfs_ifile; /* 56: inode file inode number */ 637 int32_t dlfs_lastseg; /* 60: address of last segment written */ 638 int32_t dlfs_nextseg; /* 64: address of next segment to write */ 639 int32_t dlfs_curseg; /* 68: current segment being written */ 640 int32_t dlfs_offset; /* 72: offset in curseg for next partial */ 641 int32_t dlfs_lastpseg; /* 76: address of last partial written */ 642 u_int32_t dlfs_inopf; /* 80: v1: time stamp; v2: inodes per frag */ 643 #define dlfs_otstamp dlfs_inopf 644 645 /* These are configuration parameters. */ 646 u_int32_t dlfs_minfree; /* 84: minimum percentage of free blocks */ 647 648 /* These fields can be computed from the others. */ 649 u_int64_t dlfs_maxfilesize; /* 88: maximum representable file size */ 650 u_int32_t dlfs_fsbpseg; /* 96: fsb per segment */ 651 u_int32_t dlfs_inopb; /* 100: inodes per block */ 652 u_int32_t dlfs_ifpb; /* 104: IFILE entries per block */ 653 u_int32_t dlfs_sepb; /* 108: SEGUSE entries per block */ 654 u_int32_t dlfs_nindir; /* 112: indirect pointers per block */ 655 u_int32_t dlfs_nseg; /* 116: number of segments */ 656 u_int32_t dlfs_nspf; /* 120: number of sectors per fragment */ 657 u_int32_t dlfs_cleansz; /* 124: cleaner info size in blocks */ 658 u_int32_t dlfs_segtabsz; /* 128: segment table size in blocks */ 659 u_int32_t dlfs_segmask; /* 132: calculate offset within a segment */ 660 u_int32_t dlfs_segshift; /* 136: fast mult/div for segments */ 661 u_int32_t dlfs_bshift; /* 140: calc block number from file offset */ 662 u_int32_t dlfs_ffshift; /* 144: fast mult/div for frag from file */ 663 u_int32_t dlfs_fbshift; /* 148: fast mult/div for frag from block */ 664 u_int64_t dlfs_bmask; /* 152: calc block offset from file offset */ 665 u_int64_t dlfs_ffmask; /* 160: calc frag offset from file offset */ 666 u_int64_t dlfs_fbmask; /* 168: calc frag offset from block offset */ 667 u_int32_t dlfs_blktodb; /* 176: blktodb and dbtoblk shift constant */ 668 u_int32_t dlfs_sushift; /* 180: fast mult/div for segusage table */ 669 670 int32_t dlfs_maxsymlinklen; /* 184: max length of an internal symlink */ 671 #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 672 #define LFS_MAXNUMSB 10 /* 188: superblock disk offsets */ 673 int32_t dlfs_sboffs[LFS_MAXNUMSB]; 674 675 u_int32_t dlfs_nclean; /* 228: Number of clean segments */ 676 u_char dlfs_fsmnt[MNAMELEN]; /* 232: name mounted on */ 677 #define LFS_PF_CLEAN 0x1 678 u_int16_t dlfs_pflags; /* 322: file system persistent flags */ 679 int32_t dlfs_dmeta; /* 324: total number of dirty summaries */ 680 u_int32_t dlfs_minfreeseg; /* 328: segs reserved for cleaner */ 681 u_int32_t dlfs_sumsize; /* 332: size of summary blocks */ 682 u_int64_t dlfs_serial; /* 336: serial number */ 683 u_int32_t dlfs_ibsize; /* 344: size of inode blocks */ 684 int32_t dlfs_start; /* 348: start of segment 0 */ 685 u_int64_t dlfs_tstamp; /* 352: time stamp */ 686 #define LFS_44INODEFMT 0 687 #define LFS_MAXINODEFMT 0 688 u_int32_t dlfs_inodefmt; /* 360: inode format version */ 689 u_int32_t dlfs_interleave; /* 364: segment interleave */ 690 u_int32_t dlfs_ident; /* 368: per-fs identifier */ 691 u_int32_t dlfs_fsbtodb; /* 372: fsbtodb abd dbtodsb shift constant */ 692 int8_t dlfs_pad[132]; /* 376: round to 512 bytes */ 693 /* Checksum -- last valid disk field. */ 694 u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */ 695 }; 696 697 /* 698 * In-memory super block. 699 */ 700 struct lfs { 701 struct dlfs lfs_dlfs; /* on-disk parameters */ 702 #define lfs_magic lfs_dlfs.dlfs_magic 703 #define lfs_version lfs_dlfs.dlfs_version 704 #define lfs_size lfs_dlfs.dlfs_size 705 #define lfs_ssize lfs_dlfs.dlfs_ssize 706 #define lfs_dsize lfs_dlfs.dlfs_dsize 707 #define lfs_bsize lfs_dlfs.dlfs_bsize 708 #define lfs_fsize lfs_dlfs.dlfs_fsize 709 #define lfs_frag lfs_dlfs.dlfs_frag 710 #define lfs_freehd lfs_dlfs.dlfs_freehd 711 #define lfs_bfree lfs_dlfs.dlfs_bfree 712 #define lfs_nfiles lfs_dlfs.dlfs_nfiles 713 #define lfs_avail lfs_dlfs.dlfs_avail 714 #define lfs_uinodes lfs_dlfs.dlfs_uinodes 715 #define lfs_idaddr lfs_dlfs.dlfs_idaddr 716 #define lfs_ifile lfs_dlfs.dlfs_ifile 717 #define lfs_lastseg lfs_dlfs.dlfs_lastseg 718 #define lfs_nextseg lfs_dlfs.dlfs_nextseg 719 #define lfs_curseg lfs_dlfs.dlfs_curseg 720 #define lfs_offset lfs_dlfs.dlfs_offset 721 #define lfs_lastpseg lfs_dlfs.dlfs_lastpseg 722 #define lfs_otstamp lfs_dlfs.dlfs_inopf 723 #define lfs_inopf lfs_dlfs.dlfs_inopf 724 #define lfs_minfree lfs_dlfs.dlfs_minfree 725 #define lfs_maxfilesize lfs_dlfs.dlfs_maxfilesize 726 #define lfs_fsbpseg lfs_dlfs.dlfs_fsbpseg 727 #define lfs_inopb lfs_dlfs.dlfs_inopb 728 #define lfs_ifpb lfs_dlfs.dlfs_ifpb 729 #define lfs_sepb lfs_dlfs.dlfs_sepb 730 #define lfs_nindir lfs_dlfs.dlfs_nindir 731 #define lfs_nseg lfs_dlfs.dlfs_nseg 732 #define lfs_nspf lfs_dlfs.dlfs_nspf 733 #define lfs_cleansz lfs_dlfs.dlfs_cleansz 734 #define lfs_segtabsz lfs_dlfs.dlfs_segtabsz 735 #define lfs_segmask lfs_dlfs.dlfs_segmask 736 #define lfs_segshift lfs_dlfs.dlfs_segshift 737 #define lfs_bmask lfs_dlfs.dlfs_bmask 738 #define lfs_bshift lfs_dlfs.dlfs_bshift 739 #define lfs_ffmask lfs_dlfs.dlfs_ffmask 740 #define lfs_ffshift lfs_dlfs.dlfs_ffshift 741 #define lfs_fbmask lfs_dlfs.dlfs_fbmask 742 #define lfs_fbshift lfs_dlfs.dlfs_fbshift 743 #define lfs_blktodb lfs_dlfs.dlfs_blktodb 744 #define lfs_fsbtodb lfs_dlfs.dlfs_fsbtodb 745 #define lfs_sushift lfs_dlfs.dlfs_sushift 746 #define lfs_maxsymlinklen lfs_dlfs.dlfs_maxsymlinklen 747 #define lfs_sboffs lfs_dlfs.dlfs_sboffs 748 #define lfs_cksum lfs_dlfs.dlfs_cksum 749 #define lfs_pflags lfs_dlfs.dlfs_pflags 750 #define lfs_fsmnt lfs_dlfs.dlfs_fsmnt 751 #define lfs_nclean lfs_dlfs.dlfs_nclean 752 #define lfs_dmeta lfs_dlfs.dlfs_dmeta 753 #define lfs_minfreeseg lfs_dlfs.dlfs_minfreeseg 754 #define lfs_sumsize lfs_dlfs.dlfs_sumsize 755 #define lfs_serial lfs_dlfs.dlfs_serial 756 #define lfs_ibsize lfs_dlfs.dlfs_ibsize 757 #define lfs_start lfs_dlfs.dlfs_start 758 #define lfs_tstamp lfs_dlfs.dlfs_tstamp 759 #define lfs_inodefmt lfs_dlfs.dlfs_inodefmt 760 #define lfs_interleave lfs_dlfs.dlfs_interleave 761 #define lfs_ident lfs_dlfs.dlfs_ident 762 763 /* These fields are set at mount time and are meaningless on disk. */ 764 struct segment *lfs_sp; /* current segment being written */ 765 struct vnode *lfs_ivnode; /* vnode for the ifile */ 766 u_int32_t lfs_seglock; /* single-thread the segment writer */ 767 pid_t lfs_lockpid; /* pid of lock holder */ 768 u_int32_t lfs_iocount; /* number of ios pending */ 769 u_int32_t lfs_writer; /* don't allow any dirops to start */ 770 u_int32_t lfs_dirops; /* count of active directory ops */ 771 u_int32_t lfs_doifile; /* Write ifile blocks on next write */ 772 u_int32_t lfs_nactive; /* Number of segments since last ckp */ 773 int8_t lfs_fmod; /* super block modified flag */ 774 int8_t lfs_ronly; /* mounted read-only flag */ 775 #define LFS_NOTYET 0x01 776 #define LFS_IFDIRTY 0x02 777 #define LFS_WARNED 0x04 778 #define LFS_UNDIROP 0x08 779 int8_t lfs_flags; /* currently unused flag */ 780 u_int16_t lfs_activesb; /* toggle between superblocks */ 781 daddr_t lfs_sbactive; /* disk address of current sb write */ 782 struct vnode *lfs_flushvp; /* vnode being flushed */ 783 struct vnode *lfs_unlockvp; /* being inactivated in lfs_segunlock */ 784 u_int32_t lfs_diropwait; /* # procs waiting on dirop flush */ 785 size_t lfs_devbsize; /* Device block size */ 786 size_t lfs_devbshift; /* Device block shift */ 787 struct lock lfs_fraglock; 788 struct lock lfs_iflock; /* Ifile lock */ 789 pid_t lfs_rfpid; /* Process ID of roll-forward agent */ 790 int lfs_nadirop; /* number of active dirop nodes */ 791 long lfs_ravail; /* blocks pre-reserved for writing */ 792 long lfs_favail; /* blocks pre-reserved for writing */ 793 res_t *lfs_resblk; /* Reserved memory for pageout */ 794 TAILQ_HEAD(, inode) lfs_dchainhd; /* dirop vnodes */ 795 TAILQ_HEAD(, inode) lfs_pchainhd; /* paging vnodes */ 796 #define LFS_RESHASH_WIDTH 17 797 LIST_HEAD(, lfs_res_blk) lfs_reshash[LFS_RESHASH_WIDTH]; 798 int lfs_pdflush; /* pagedaemon wants us to flush */ 799 u_int32_t **lfs_suflags; /* Segment use flags */ 800 #ifdef _KERNEL 801 struct pool lfs_clpool; /* Pool for struct lfs_cluster */ 802 struct pool lfs_bpppool; /* Pool for bpp */ 803 struct pool lfs_segpool; /* Pool for struct segment */ 804 #endif /* _KERNEL */ 805 #define LFS_MAX_CLEANIND 64 806 int32_t lfs_cleanint[LFS_MAX_CLEANIND]; /* Active cleaning intervals */ 807 int lfs_cleanind; /* Index into intervals */ 808 struct simplelock lfs_interlock; /* lock for lfs_seglock */ 809 int lfs_sleepers; /* # procs sleeping this fs */ 810 int lfs_pages; /* dirty pages blaming this fs */ 811 }; 812 813 /* NINDIR is the number of indirects in a file system block. */ 814 #define NINDIR(fs) ((fs)->lfs_nindir) 815 816 /* INOPB is the number of inodes in a secondary storage block. */ 817 #define INOPB(fs) ((fs)->lfs_inopb) 818 /* INOPF is the number of inodes in a fragment. */ 819 #define INOPF(fs) ((fs)->lfs_inopf) 820 821 #define blksize(fs, ip, lbn) \ 822 (((lbn) >= NDADDR || (ip)->i_ffs1_size >= ((lbn) + 1) << (fs)->lfs_bshift) \ 823 ? (fs)->lfs_bsize \ 824 : (fragroundup(fs, blkoff(fs, (ip)->i_ffs1_size)))) 825 #define blkoff(fs, loc) ((int)((loc) & (fs)->lfs_bmask)) 826 #define fragoff(fs, loc) /* calculates (loc % fs->lfs_fsize) */ \ 827 ((int)((loc) & (fs)->lfs_ffmask)) 828 #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 829 #define dbtofsb(fs, b) ((b) >> (fs)->lfs_fsbtodb) 830 #define fragstodb(fs, b) ((b) << ((fs)->lfs_blktodb - (fs)->lfs_fbshift)) 831 #define dbtofrags(fs, b) ((b) >> ((fs)->lfs_blktodb - (fs)->lfs_fbshift)) 832 #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 833 #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 834 /* Same as above, but named like dbtob(), btodb() */ 835 #define fsbtob(fs, b) ((b) << ((fs)->lfs_bshift - \ 836 (fs)->lfs_blktodb + (fs)->lfs_fsbtodb)) 837 #define btofsb(fs, b) ((b) >> ((fs)->lfs_bshift - \ 838 (fs)->lfs_blktodb + (fs)->lfs_fsbtodb)) 839 #define fsbtofrags(fs, b) ((b) >> ((fs)->lfs_blktodb - (fs)->lfs_fbshift - \ 840 (fs)->lfs_fsbtodb)) 841 #define fragstofsb(fs, b) ((b) << ((fs)->lfs_blktodb - (fs)->lfs_fbshift - \ 842 (fs)->lfs_fsbtodb)) 843 #define btofrags(fs, b) ((b) >> (fs)->lfs_ffshift) 844 #define numfrags(fs, loc) /* calculates (loc / fs->lfs_fsize) */ \ 845 ((loc) >> (fs)->lfs_ffshift) 846 #define blkroundup(fs, size) /* calculates roundup(size, fs->lfs_bsize) */ \ 847 ((off_t)(((size) + (fs)->lfs_bmask) & (~(fs)->lfs_bmask))) 848 #define fragroundup(fs, size) /* calculates roundup(size, fs->lfs_fsize) */ \ 849 ((off_t)(((size) + (fs)->lfs_ffmask) & (~(fs)->lfs_ffmask))) 850 #define fragstoblks(fs, frags) /* calculates (frags / fs->lfs_frag) */ \ 851 ((frags) >> (fs)->lfs_fbshift) 852 #define blkstofrags(fs, blks) /* calculates (blks * fs->lfs_frag) */ \ 853 ((blks) << (fs)->lfs_fbshift) 854 #define fragnum(fs, fsb) /* calculates (fsb % fs->lfs_frag) */ \ 855 ((fsb) & ((fs)->lfs_frag - 1)) 856 #define blknum(fs, fsb) /* calculates rounddown(fsb, fs->lfs_frag) */ \ 857 ((fsb) &~ ((fs)->lfs_frag - 1)) 858 #define dblksize(fs, dp, lbn) \ 859 (((lbn) >= NDADDR || (dp)->di_size >= ((lbn) + 1) << (fs)->lfs_bshift)\ 860 ? (fs)->lfs_bsize \ 861 : (fragroundup(fs, blkoff(fs, (dp)->di_size)))) 862 863 #define segsize(fs) ((fs)->lfs_version == 1 ? \ 864 lblktosize((fs), (fs)->lfs_ssize) : \ 865 (fs)->lfs_ssize) 866 #define segtod(fs, seg) (((fs)->lfs_version == 1 ? \ 867 (fs)->lfs_ssize << (fs)->lfs_blktodb : \ 868 btofsb((fs), (fs)->lfs_ssize)) * (seg)) 869 #define dtosn(fs, daddr) /* block address to segment number */ \ 870 ((uint32_t)(((daddr) - (fs)->lfs_start) / segtod((fs), 1))) 871 #define sntod(fs, sn) /* segment number to disk address */ \ 872 ((daddr_t)(segtod((fs), (sn)) + (fs)->lfs_start)) 873 874 /* 875 * Structures used by lfs_bmapv and lfs_markv to communicate information 876 * about inodes and data blocks. 877 */ 878 typedef struct block_info { 879 u_int32_t bi_inode; /* inode # */ 880 int32_t bi_lbn; /* logical block w/in file */ 881 int32_t bi_daddr; /* disk address of block */ 882 u_int64_t bi_segcreate; /* origin segment create time */ 883 int bi_version; /* file version number */ 884 void *bi_bp; /* data buffer */ 885 int bi_size; /* size of the block (if fragment) */ 886 } BLOCK_INFO; 887 888 /* Compatibility for 1.5 binaries */ 889 typedef struct block_info_15 { 890 u_int32_t bi_inode; /* inode # */ 891 int32_t bi_lbn; /* logical block w/in file */ 892 int32_t bi_daddr; /* disk address of block */ 893 u_int32_t bi_segcreate; /* origin segment create time */ 894 int bi_version; /* file version number */ 895 void *bi_bp; /* data buffer */ 896 int bi_size; /* size of the block (if fragment) */ 897 } BLOCK_INFO_15; 898 899 /* In-memory description of a segment about to be written. */ 900 struct segment { 901 struct lfs *fs; /* file system pointer */ 902 struct buf **bpp; /* pointer to buffer array */ 903 struct buf **cbpp; /* pointer to next available bp */ 904 struct buf **start_bpp; /* pointer to first bp in this set */ 905 struct buf *ibp; /* buffer pointer to inode page */ 906 struct ufs1_dinode *idp; /* pointer to ifile dinode */ 907 struct finfo *fip; /* current fileinfo pointer */ 908 struct vnode *vp; /* vnode being gathered */ 909 void *segsum; /* segment summary info */ 910 u_int32_t ninodes; /* number of inodes in this segment */ 911 int32_t seg_bytes_left; /* bytes left in segment */ 912 int32_t sum_bytes_left; /* bytes left in summary block */ 913 u_int32_t seg_number; /* number of this segment */ 914 int32_t *start_lbp; /* beginning lbn for this set */ 915 916 #define SEGM_CKP 0x01 /* doing a checkpoint */ 917 #define SEGM_CLEAN 0x02 /* cleaner call; don't sort */ 918 #define SEGM_SYNC 0x04 /* wait for segment */ 919 #define SEGM_PROT 0x08 /* don't inactivate at segunlock */ 920 #define SEGM_PAGEDAEMON 0x10 /* pagedaemon called us */ 921 #define SEGM_WRITERD 0x20 /* LFS writed called us */ 922 #define SEGM_FORCE_CKP 0x40 /* Force checkpoint right away */ 923 u_int16_t seg_flags; /* run-time flags for this segment */ 924 u_int32_t seg_iocount; /* number of ios pending */ 925 int ndupino; /* number of duplicate inodes */ 926 }; 927 928 #ifdef _KERNEL 929 struct lfs_cluster { 930 size_t bufsize; /* Size of kept data */ 931 struct buf **bpp; /* Array of kept buffers */ 932 int bufcount; /* Number of kept buffers */ 933 #define LFS_CL_MALLOC 0x00000001 934 #define LFS_CL_SHIFT 0x00000002 935 #define LFS_CL_SYNC 0x00000004 936 u_int32_t flags; /* Flags */ 937 struct lfs *fs; /* LFS that this belongs to */ 938 struct segment *seg; /* Segment structure, for LFS_CL_SYNC */ 939 }; 940 941 /* 942 * Splay tree containing block numbers allocated through lfs_balloc. 943 */ 944 struct lbnentry { 945 SPLAY_ENTRY(lbnentry) entry; 946 daddr_t lbn; 947 }; 948 #endif /* _KERNEL */ 949 950 /* 951 * LFS inode extensions. 952 */ 953 struct lfs_inode_ext { 954 off_t lfs_osize; /* size of file on disk */ 955 u_int32_t lfs_effnblocks; /* number of blocks when i/o completes */ 956 size_t lfs_fragsize[NDADDR]; /* size of on-disk direct blocks */ 957 TAILQ_ENTRY(inode) lfs_dchain; /* Dirop chain. */ 958 TAILQ_ENTRY(inode) lfs_pchain; /* Paging chain. */ 959 #define LFSI_NO_GOP_WRITE 0x01 960 u_int32_t lfs_iflags; /* Inode flags */ 961 daddr_t lfs_hiblk; /* Highest lbn held by inode */ 962 #ifdef _KERNEL 963 SPLAY_HEAD(lfs_splay, lbnentry) lfs_lbtree; /* Tree of balloc'd lbns */ 964 int lfs_nbtree; /* Size of tree */ 965 #endif 966 }; 967 #define i_lfs_osize inode_ext.lfs->lfs_osize 968 #define i_lfs_effnblks inode_ext.lfs->lfs_effnblocks 969 #define i_lfs_fragsize inode_ext.lfs->lfs_fragsize 970 #define i_lfs_dchain inode_ext.lfs->lfs_dchain 971 #define i_lfs_iflags inode_ext.lfs->lfs_iflags 972 #define i_lfs_hiblk inode_ext.lfs->lfs_hiblk 973 #define i_lfs_lbtree inode_ext.lfs->lfs_lbtree 974 #define i_lfs_nbtree inode_ext.lfs->lfs_nbtree 975 976 /* 977 * Macros for determining free space on the disk, with the variable metadata 978 * of segment summaries and inode blocks taken into account. 979 */ 980 /* Estimate number of clean blocks not available for writing */ 981 #define LFS_EST_CMETA(F) (int32_t)((((F)->lfs_dmeta * \ 982 (int64_t)(F)->lfs_nclean) / \ 983 ((F)->lfs_nseg - (F)->lfs_nclean))) 984 985 /* Estimate total size of the disk not including metadata */ 986 #define LFS_EST_NONMETA(F) ((F)->lfs_dsize - (F)->lfs_dmeta - LFS_EST_CMETA(F)) 987 988 /* Estimate number of blocks actually available for writing */ 989 #define LFS_EST_BFREE(F) ((F)->lfs_bfree > LFS_EST_CMETA(F) + (F)->lfs_dmeta ? (F)->lfs_bfree - LFS_EST_CMETA(F) - (F)->lfs_dmeta : 0) 990 991 /* Amount of non-meta space not available to mortal man */ 992 #define LFS_EST_RSVD(F) (int32_t)((LFS_EST_NONMETA(F) * \ 993 (u_int64_t)(F)->lfs_minfree) / \ 994 100) 995 996 /* Can credential C write BB blocks */ 997 #define ISSPACE(F, BB, C) \ 998 ((((C) == NOCRED || (C)->cr_uid == 0) && \ 999 LFS_EST_BFREE(F) >= (BB)) || \ 1000 ((C)->cr_uid != 0 && IS_FREESPACE(F, BB))) 1001 1002 /* Can an ordinary user write BB blocks */ 1003 #define IS_FREESPACE(F, BB) \ 1004 (LFS_EST_BFREE(F) >= (BB) + LFS_EST_RSVD(F)) 1005 1006 /* 1007 * The minimum number of blocks to create a new inode. This is: 1008 * directory direct block (1) + NIADDR indirect blocks + inode block (1) + 1009 * ifile direct block (1) + NIADDR indirect blocks = 3 + 2 * NIADDR blocks. 1010 */ 1011 #define LFS_NRESERVE(F) (btofsb((F), (2 * NIADDR + 3) << (F)->lfs_bshift)) 1012 1013 /* Statistics Counters */ 1014 struct lfs_stats { /* Must match sysctl list in lfs_vfsops.h ! */ 1015 u_int segsused; 1016 u_int psegwrites; 1017 u_int psyncwrites; 1018 u_int pcleanwrites; 1019 u_int blocktot; 1020 u_int cleanblocks; 1021 u_int ncheckpoints; 1022 u_int nwrites; 1023 u_int nsync_writes; 1024 u_int wait_exceeded; 1025 u_int write_exceeded; 1026 u_int flush_invoked; 1027 u_int vflush_invoked; 1028 u_int clean_inlocked; 1029 u_int clean_vnlocked; 1030 u_int segs_reclaimed; 1031 }; 1032 #ifdef _KERNEL 1033 extern struct lfs_stats lfs_stats; 1034 #endif 1035 1036 /* Fcntls to take the place of the lfs syscalls */ 1037 struct lfs_fcntl_markv { 1038 BLOCK_INFO *blkiov; /* blocks to relocate */ 1039 int blkcnt; /* number of blocks */ 1040 }; 1041 1042 #define LFCNSEGWAITALL _FCNR_FSPRIV('L', 0, struct timeval) 1043 #define LFCNSEGWAIT _FCNR_FSPRIV('L', 1, struct timeval) 1044 #define LFCNBMAPV _FCNRW_FSPRIV('L', 2, struct lfs_fcntl_markv) 1045 #define LFCNMARKV _FCNRW_FSPRIV('L', 3, struct lfs_fcntl_markv) 1046 #define LFCNRECLAIM _FCNO_FSPRIV('L', 4) 1047 #define LFCNIFILEFH _FCNW_FSPRIV('L', 5, struct fhandle) 1048 #define LFCNREWIND _FCNR_FSPRIV('L', 6, int) 1049 #define LFCNINVAL _FCNR_FSPRIV('L', 7, int) 1050 #define LFCNRESIZE _FCNR_FSPRIV('L', 8, int) 1051 /* Compat for NetBSD 2.x bug */ 1052 #define LFCNSEGWAITALL_COMPAT _FCNW_FSPRIV('L', 0, struct timeval) 1053 #define LFCNSEGWAIT_COMPAT _FCNW_FSPRIV('L', 1, struct timeval) 1054 1055 #ifdef _KERNEL 1056 /* XXX MP */ 1057 #define LFS_SEGLOCK_HELD(fs) \ 1058 ((fs)->lfs_seglock != 0 && (fs)->lfs_lockpid == curproc->p_pid) 1059 #endif /* _KERNEL */ 1060 1061 /* Debug segment lock */ 1062 #ifdef notyet 1063 # define ASSERT_SEGLOCK(fs) KASSERT(LFS_SEGLOCK_HELD(fs)) 1064 # define ASSERT_NO_SEGLOCK(fs) KASSERT(!LFS_SEGLOCK_HELD(fs)) 1065 # define ASSERT_DUNNO_SEGLOCK(fs) 1066 # define ASSERT_MAYBE_SEGLOCK(fs) 1067 #else /* !notyet */ 1068 # define ASSERT_DUNNO_SEGLOCK(fs) \ 1069 DLOG((DLOG_SEG, "lfs func %s seglock wrong (%d)\n", __func__, \ 1070 LFS_SEGLOCK_HELD(fs))) 1071 # define ASSERT_SEGLOCK(fs) do { \ 1072 if (!LFS_SEGLOCK_HELD(fs)) { \ 1073 DLOG((DLOG_SEG, "lfs func %s seglock wrong (0)\n", __func__)); \ 1074 } \ 1075 } while(0) 1076 # define ASSERT_NO_SEGLOCK(fs) do { \ 1077 if (LFS_SEGLOCK_HELD(fs)) { \ 1078 DLOG((DLOG_SEG, "lfs func %s seglock wrong (1)\n", __func__)); \ 1079 } \ 1080 } while(0) 1081 # define ASSERT_MAYBE_SEGLOCK(x) 1082 #endif /* !notyet */ 1083 1084 __BEGIN_DECLS 1085 void lfs_itimes(struct inode *, const struct timespec *, 1086 const struct timespec *, const struct timespec *); 1087 __END_DECLS 1088 1089 #endif /* !_UFS_LFS_LFS_H_ */ 1090