Home | History | Annotate | Line # | Download | only in lfs
lfs_accessors.h revision 1.6
      1 /*	$NetBSD: lfs_accessors.h,v 1.6 2015/08/02 18:14:16 dholland Exp $	*/
      2 
      3 /*  from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp  */
      4 /*  from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp  */
      5 /*  from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp  */
      6 
      7 /*-
      8  * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
      9  * All rights reserved.
     10  *
     11  * This code is derived from software contributed to The NetBSD Foundation
     12  * by Konrad E. Schroder <perseant (at) hhhh.org>.
     13  *
     14  * Redistribution and use in source and binary forms, with or without
     15  * modification, are permitted provided that the following conditions
     16  * are met:
     17  * 1. Redistributions of source code must retain the above copyright
     18  *    notice, this list of conditions and the following disclaimer.
     19  * 2. Redistributions in binary form must reproduce the above copyright
     20  *    notice, this list of conditions and the following disclaimer in the
     21  *    documentation and/or other materials provided with the distribution.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33  * POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 /*-
     36  * Copyright (c) 1991, 1993
     37  *	The Regents of the University of California.  All rights reserved.
     38  *
     39  * Redistribution and use in source and binary forms, with or without
     40  * modification, are permitted provided that the following conditions
     41  * are met:
     42  * 1. Redistributions of source code must retain the above copyright
     43  *    notice, this list of conditions and the following disclaimer.
     44  * 2. Redistributions in binary form must reproduce the above copyright
     45  *    notice, this list of conditions and the following disclaimer in the
     46  *    documentation and/or other materials provided with the distribution.
     47  * 3. Neither the name of the University nor the names of its contributors
     48  *    may be used to endorse or promote products derived from this software
     49  *    without specific prior written permission.
     50  *
     51  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     61  * SUCH DAMAGE.
     62  *
     63  *	@(#)lfs.h	8.9 (Berkeley) 5/8/95
     64  */
     65 /*
     66  * Copyright (c) 2002 Networks Associates Technology, Inc.
     67  * All rights reserved.
     68  *
     69  * This software was developed for the FreeBSD Project by Marshall
     70  * Kirk McKusick and Network Associates Laboratories, the Security
     71  * Research Division of Network Associates, Inc. under DARPA/SPAWAR
     72  * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
     73  * research program
     74  *
     75  * Copyright (c) 1982, 1989, 1993
     76  *	The Regents of the University of California.  All rights reserved.
     77  * (c) UNIX System Laboratories, Inc.
     78  * All or some portions of this file are derived from material licensed
     79  * to the University of California by American Telephone and Telegraph
     80  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
     81  * the permission of UNIX System Laboratories, Inc.
     82  *
     83  * Redistribution and use in source and binary forms, with or without
     84  * modification, are permitted provided that the following conditions
     85  * are met:
     86  * 1. Redistributions of source code must retain the above copyright
     87  *    notice, this list of conditions and the following disclaimer.
     88  * 2. Redistributions in binary form must reproduce the above copyright
     89  *    notice, this list of conditions and the following disclaimer in the
     90  *    documentation and/or other materials provided with the distribution.
     91  * 3. Neither the name of the University nor the names of its contributors
     92  *    may be used to endorse or promote products derived from this software
     93  *    without specific prior written permission.
     94  *
     95  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     96  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     97  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     98  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     99  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    100  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    101  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    102  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    103  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    104  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    105  * SUCH DAMAGE.
    106  *
    107  *	@(#)dinode.h	8.9 (Berkeley) 3/29/95
    108  */
    109 /*
    110  * Copyright (c) 1982, 1986, 1989, 1993
    111  *	The Regents of the University of California.  All rights reserved.
    112  * (c) UNIX System Laboratories, Inc.
    113  * All or some portions of this file are derived from material licensed
    114  * to the University of California by American Telephone and Telegraph
    115  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    116  * the permission of UNIX System Laboratories, Inc.
    117  *
    118  * Redistribution and use in source and binary forms, with or without
    119  * modification, are permitted provided that the following conditions
    120  * are met:
    121  * 1. Redistributions of source code must retain the above copyright
    122  *    notice, this list of conditions and the following disclaimer.
    123  * 2. Redistributions in binary form must reproduce the above copyright
    124  *    notice, this list of conditions and the following disclaimer in the
    125  *    documentation and/or other materials provided with the distribution.
    126  * 3. Neither the name of the University nor the names of its contributors
    127  *    may be used to endorse or promote products derived from this software
    128  *    without specific prior written permission.
    129  *
    130  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    131  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    132  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    133  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    134  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    135  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    136  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    137  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    138  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    139  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    140  * SUCH DAMAGE.
    141  *
    142  *	@(#)dir.h	8.5 (Berkeley) 4/27/95
    143  */
    144 
    145 #ifndef _UFS_LFS_LFS_ACCESSORS_H_
    146 #define _UFS_LFS_LFS_ACCESSORS_H_
    147 
    148 /*
    149  * Maximum length of a symlink that can be stored within the inode.
    150  */
    151 #define ULFS1_MAXSYMLINKLEN	((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int32_t))
    152 #define ULFS2_MAXSYMLINKLEN	((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int64_t))
    153 
    154 #define ULFS_MAXSYMLINKLEN(ip) \
    155 	((ip)->i_ump->um_fstype == ULFS1) ? \
    156 	ULFS1_MAXSYMLINKLEN : ULFS2_MAXSYMLINKLEN
    157 
    158 /*
    159  * "struct buf" associated definitions
    160  */
    161 
    162 # define LFS_LOCK_BUF(bp) do {						\
    163 	if (((bp)->b_flags & B_LOCKED) == 0 && bp->b_iodone == NULL) {	\
    164 		mutex_enter(&lfs_lock);					\
    165 		++locked_queue_count;					\
    166 		locked_queue_bytes += bp->b_bufsize;			\
    167 		mutex_exit(&lfs_lock);					\
    168 	}								\
    169 	(bp)->b_flags |= B_LOCKED;					\
    170 } while (0)
    171 
    172 # define LFS_UNLOCK_BUF(bp) do {					\
    173 	if (((bp)->b_flags & B_LOCKED) != 0 && bp->b_iodone == NULL) {	\
    174 		mutex_enter(&lfs_lock);					\
    175 		--locked_queue_count;					\
    176 		locked_queue_bytes -= bp->b_bufsize;			\
    177 		if (locked_queue_count < LFS_WAIT_BUFS &&		\
    178 		    locked_queue_bytes < LFS_WAIT_BYTES)		\
    179 			cv_broadcast(&locked_queue_cv);			\
    180 		mutex_exit(&lfs_lock);					\
    181 	}								\
    182 	(bp)->b_flags &= ~B_LOCKED;					\
    183 } while (0)
    184 
    185 /*
    186  * "struct inode" associated definitions
    187  */
    188 
    189 #define LFS_SET_UINO(ip, flags) do {					\
    190 	if (((flags) & IN_ACCESSED) && !((ip)->i_flag & IN_ACCESSED))	\
    191 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    192 	if (((flags) & IN_CLEANING) && !((ip)->i_flag & IN_CLEANING))	\
    193 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    194 	if (((flags) & IN_MODIFIED) && !((ip)->i_flag & IN_MODIFIED))	\
    195 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    196 	(ip)->i_flag |= (flags);					\
    197 } while (0)
    198 
    199 #define LFS_CLR_UINO(ip, flags) do {					\
    200 	if (((flags) & IN_ACCESSED) && ((ip)->i_flag & IN_ACCESSED))	\
    201 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    202 	if (((flags) & IN_CLEANING) && ((ip)->i_flag & IN_CLEANING))	\
    203 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    204 	if (((flags) & IN_MODIFIED) && ((ip)->i_flag & IN_MODIFIED))	\
    205 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    206 	(ip)->i_flag &= ~(flags);					\
    207 	if (lfs_sb_getuinodes((ip)->i_lfs) < 0) {			\
    208 		panic("lfs_uinodes < 0");				\
    209 	}								\
    210 } while (0)
    211 
    212 #define LFS_ITIMES(ip, acc, mod, cre) \
    213 	while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
    214 		lfs_itimes(ip, acc, mod, cre)
    215 
    216 /*
    217  * On-disk and in-memory checkpoint segment usage structure.
    218  */
    219 
    220 #define	SEGUPB(fs)	(lfs_sb_getsepb(fs))
    221 #define	SEGTABSIZE_SU(fs)						\
    222 	((lfs_sb_getnseg(fs) + SEGUPB(fs) - 1) / lfs_sb_getsepb(fs))
    223 
    224 #ifdef _KERNEL
    225 # define SHARE_IFLOCK(F) 						\
    226   do {									\
    227 	rw_enter(&(F)->lfs_iflock, RW_READER);				\
    228   } while(0)
    229 # define UNSHARE_IFLOCK(F)						\
    230   do {									\
    231 	rw_exit(&(F)->lfs_iflock);					\
    232   } while(0)
    233 #else /* ! _KERNEL */
    234 # define SHARE_IFLOCK(F)
    235 # define UNSHARE_IFLOCK(F)
    236 #endif /* ! _KERNEL */
    237 
    238 /* Read in the block with a specific segment usage entry from the ifile. */
    239 #define	LFS_SEGENTRY(SP, F, IN, BP) do {				\
    240 	int _e;								\
    241 	SHARE_IFLOCK(F);						\
    242 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    243 	if ((_e = bread((F)->lfs_ivnode,				\
    244 	    ((IN) / lfs_sb_getsepb(F)) + lfs_sb_getcleansz(F),		\
    245 	    lfs_sb_getbsize(F), 0, &(BP))) != 0)			\
    246 		panic("lfs: ifile read: %d", _e);			\
    247 	if (lfs_sb_getversion(F) == 1)					\
    248 		(SP) = (SEGUSE *)((SEGUSE_V1 *)(BP)->b_data +		\
    249 			((IN) & (lfs_sb_getsepb(F) - 1)));		\
    250 	else								\
    251 		(SP) = (SEGUSE *)(BP)->b_data + ((IN) % lfs_sb_getsepb(F)); \
    252 	UNSHARE_IFLOCK(F);						\
    253 } while (0)
    254 
    255 #define LFS_WRITESEGENTRY(SP, F, IN, BP) do {				\
    256 	if ((SP)->su_nbytes == 0)					\
    257 		(SP)->su_flags |= SEGUSE_EMPTY;				\
    258 	else								\
    259 		(SP)->su_flags &= ~SEGUSE_EMPTY;			\
    260 	(F)->lfs_suflags[(F)->lfs_activesb][(IN)] = (SP)->su_flags;	\
    261 	LFS_BWRITE_LOG(BP);						\
    262 } while (0)
    263 
    264 /*
    265  * Index file inode entries.
    266  */
    267 
    268 /*
    269  * LFSv1 compatibility code is not allowed to touch if_atime, since it
    270  * may not be mapped!
    271  */
    272 /* Read in the block with a specific inode from the ifile. */
    273 #define	LFS_IENTRY(IP, F, IN, BP) do {					\
    274 	int _e;								\
    275 	SHARE_IFLOCK(F);						\
    276 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    277 	if ((_e = bread((F)->lfs_ivnode,				\
    278 	(IN) / lfs_sb_getifpb(F) + lfs_sb_getcleansz(F) + lfs_sb_getsegtabsz(F), \
    279 	lfs_sb_getbsize(F), 0, &(BP))) != 0)				\
    280 		panic("lfs: ifile ino %d read %d", (int)(IN), _e);	\
    281 	if (lfs_sb_getversion(F) == 1)					\
    282 		(IP) = (IFILE *)((IFILE_V1 *)(BP)->b_data +		\
    283 				 (IN) % lfs_sb_getifpb(F));		\
    284 	else								\
    285 		(IP) = (IFILE *)(BP)->b_data + (IN) % lfs_sb_getifpb(F); \
    286 	UNSHARE_IFLOCK(F);						\
    287 } while (0)
    288 
    289 /*
    290  * Cleaner information structure.  This resides in the ifile and is used
    291  * to pass information from the kernel to the cleaner.
    292  */
    293 
    294 #define	CLEANSIZE_SU(fs)						\
    295 	((sizeof(CLEANERINFO) + lfs_sb_getbsize(fs) - 1) >> lfs_sb_getbshift(fs))
    296 
    297 /* Read in the block with the cleaner info from the ifile. */
    298 #define LFS_CLEANERINFO(CP, F, BP) do {					\
    299 	SHARE_IFLOCK(F);						\
    300 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    301 	if (bread((F)->lfs_ivnode,					\
    302 	    (daddr_t)0, lfs_sb_getbsize(F), 0, &(BP)))			\
    303 		panic("lfs: ifile read");				\
    304 	(CP) = (CLEANERINFO *)(BP)->b_data;				\
    305 	UNSHARE_IFLOCK(F);						\
    306 } while (0)
    307 
    308 /*
    309  * Synchronize the Ifile cleaner info with current avail and bfree.
    310  */
    311 #define LFS_SYNC_CLEANERINFO(cip, fs, bp, w) do {		 	\
    312     mutex_enter(&lfs_lock);						\
    313     if ((w) || (cip)->bfree != lfs_sb_getbfree(fs) ||		 	\
    314 	(cip)->avail != lfs_sb_getavail(fs) - fs->lfs_ravail -	 	\
    315 	fs->lfs_favail) {	 					\
    316 	(cip)->bfree = lfs_sb_getbfree(fs);			 	\
    317 	(cip)->avail = lfs_sb_getavail(fs) - fs->lfs_ravail -		\
    318 		fs->lfs_favail;					 	\
    319 	if (((bp)->b_flags & B_GATHERED) == 0) {		 	\
    320 		fs->lfs_flags |= LFS_IFDIRTY;				\
    321 	}								\
    322 	mutex_exit(&lfs_lock);						\
    323 	(void) LFS_BWRITE_LOG(bp); /* Ifile */			 	\
    324     } else {							 	\
    325 	mutex_exit(&lfs_lock);						\
    326 	brelse(bp, 0);						 	\
    327     }									\
    328 } while (0)
    329 
    330 /*
    331  * Get the head of the inode free list.
    332  * Always called with the segment lock held.
    333  */
    334 #define LFS_GET_HEADFREE(FS, CIP, BP, FREEP) do {			\
    335 	if (lfs_sb_getversion(FS) > 1) {				\
    336 		LFS_CLEANERINFO((CIP), (FS), (BP));			\
    337 		lfs_sb_setfreehd(FS, (CIP)->free_head);			\
    338 		brelse(BP, 0);						\
    339 	}								\
    340 	*(FREEP) = lfs_sb_getfreehd(FS);				\
    341 } while (0)
    342 
    343 #define LFS_PUT_HEADFREE(FS, CIP, BP, VAL) do {				\
    344 	lfs_sb_setfreehd(FS, VAL);					\
    345 	if (lfs_sb_getversion(FS) > 1) {				\
    346 		LFS_CLEANERINFO((CIP), (FS), (BP));			\
    347 		(CIP)->free_head = (VAL);				\
    348 		LFS_BWRITE_LOG(BP);					\
    349 		mutex_enter(&lfs_lock);					\
    350 		(FS)->lfs_flags |= LFS_IFDIRTY;				\
    351 		mutex_exit(&lfs_lock);					\
    352 	}								\
    353 } while (0)
    354 
    355 #define LFS_GET_TAILFREE(FS, CIP, BP, FREEP) do {			\
    356 	LFS_CLEANERINFO((CIP), (FS), (BP));				\
    357 	*(FREEP) = (CIP)->free_tail;					\
    358 	brelse(BP, 0);							\
    359 } while (0)
    360 
    361 #define LFS_PUT_TAILFREE(FS, CIP, BP, VAL) do {				\
    362 	LFS_CLEANERINFO((CIP), (FS), (BP));				\
    363 	(CIP)->free_tail = (VAL);					\
    364 	LFS_BWRITE_LOG(BP);						\
    365 	mutex_enter(&lfs_lock);						\
    366 	(FS)->lfs_flags |= LFS_IFDIRTY;					\
    367 	mutex_exit(&lfs_lock);						\
    368 } while (0)
    369 
    370 /*
    371  * On-disk segment summary information
    372  */
    373 
    374 #define SEGSUM_SIZE(fs) (lfs_sb_getversion(fs) == 1 ? sizeof(SEGSUM_V1) : sizeof(SEGSUM))
    375 
    376 /*
    377  * Super block.
    378  */
    379 
    380 /*
    381  * Generate accessors for the on-disk superblock fields with cpp.
    382  *
    383  * STRUCT_LFS is used by the libsa code to get accessors that work
    384  * with struct salfs instead of struct lfs.
    385  */
    386 
    387 #ifndef STRUCT_LFS
    388 #define STRUCT_LFS struct lfs
    389 #endif
    390 
    391 #define LFS_DEF_SB_ACCESSOR_FULL(type, type32, field) \
    392 	static __unused inline type				\
    393 	lfs_sb_get##field(STRUCT_LFS *fs)			\
    394 	{							\
    395 		return fs->lfs_dlfs.dlfs_##field;		\
    396 	}							\
    397 	static __unused inline void				\
    398 	lfs_sb_set##field(STRUCT_LFS *fs, type val)		\
    399 	{							\
    400 		fs->lfs_dlfs.dlfs_##field = val;		\
    401 	}							\
    402 	static __unused inline void				\
    403 	lfs_sb_add##field(STRUCT_LFS *fs, type val)		\
    404 	{							\
    405 		type32 *p = &fs->lfs_dlfs.dlfs_##field;		\
    406 		*p += val;					\
    407 	}							\
    408 	static __unused inline void				\
    409 	lfs_sb_sub##field(STRUCT_LFS *fs, type val)		\
    410 	{							\
    411 		type32 *p = &fs->lfs_dlfs.dlfs_##field;		\
    412 		*p -= val;					\
    413 	}
    414 
    415 #define LFS_DEF_SB_ACCESSOR(t, f) LFS_DEF_SB_ACCESSOR_FULL(t, t, f)
    416 
    417 #define lfs_magic lfs_dlfs.dlfs_magic
    418 LFS_DEF_SB_ACCESSOR(u_int32_t, version);
    419 LFS_DEF_SB_ACCESSOR_FULL(u_int64_t, u_int32_t, size);
    420 LFS_DEF_SB_ACCESSOR(u_int32_t, ssize);
    421 LFS_DEF_SB_ACCESSOR_FULL(u_int64_t, u_int32_t, dsize);
    422 LFS_DEF_SB_ACCESSOR(u_int32_t, bsize);
    423 LFS_DEF_SB_ACCESSOR(u_int32_t, fsize);
    424 LFS_DEF_SB_ACCESSOR(u_int32_t, frag);
    425 LFS_DEF_SB_ACCESSOR(u_int32_t, freehd);
    426 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, bfree);
    427 LFS_DEF_SB_ACCESSOR(u_int32_t, nfiles);
    428 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, avail);
    429 LFS_DEF_SB_ACCESSOR(int32_t, uinodes);
    430 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, idaddr);
    431 LFS_DEF_SB_ACCESSOR(u_int32_t, ifile);
    432 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, lastseg);
    433 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, nextseg);
    434 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, curseg);
    435 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, offset);
    436 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, lastpseg);
    437 LFS_DEF_SB_ACCESSOR(u_int32_t, inopf);
    438 LFS_DEF_SB_ACCESSOR(u_int32_t, minfree);
    439 LFS_DEF_SB_ACCESSOR(uint64_t, maxfilesize);
    440 LFS_DEF_SB_ACCESSOR(u_int32_t, fsbpseg);
    441 LFS_DEF_SB_ACCESSOR(u_int32_t, inopb);
    442 LFS_DEF_SB_ACCESSOR(u_int32_t, ifpb);
    443 LFS_DEF_SB_ACCESSOR(u_int32_t, sepb);
    444 LFS_DEF_SB_ACCESSOR(u_int32_t, nindir);
    445 LFS_DEF_SB_ACCESSOR(u_int32_t, nseg);
    446 LFS_DEF_SB_ACCESSOR(u_int32_t, nspf);
    447 LFS_DEF_SB_ACCESSOR(u_int32_t, cleansz);
    448 LFS_DEF_SB_ACCESSOR(u_int32_t, segtabsz);
    449 LFS_DEF_SB_ACCESSOR(u_int32_t, segmask);
    450 LFS_DEF_SB_ACCESSOR(u_int32_t, segshift);
    451 LFS_DEF_SB_ACCESSOR(u_int64_t, bmask);
    452 LFS_DEF_SB_ACCESSOR(u_int32_t, bshift);
    453 LFS_DEF_SB_ACCESSOR(u_int64_t, ffmask);
    454 LFS_DEF_SB_ACCESSOR(u_int32_t, ffshift);
    455 LFS_DEF_SB_ACCESSOR(u_int64_t, fbmask);
    456 LFS_DEF_SB_ACCESSOR(u_int32_t, fbshift);
    457 LFS_DEF_SB_ACCESSOR(u_int32_t, blktodb);
    458 LFS_DEF_SB_ACCESSOR(u_int32_t, fsbtodb);
    459 LFS_DEF_SB_ACCESSOR(u_int32_t, sushift);
    460 LFS_DEF_SB_ACCESSOR(int32_t, maxsymlinklen);
    461 LFS_DEF_SB_ACCESSOR(u_int32_t, cksum);
    462 LFS_DEF_SB_ACCESSOR(u_int16_t, pflags);
    463 LFS_DEF_SB_ACCESSOR(u_int32_t, nclean);
    464 LFS_DEF_SB_ACCESSOR(int32_t, dmeta);
    465 LFS_DEF_SB_ACCESSOR(u_int32_t, minfreeseg);
    466 LFS_DEF_SB_ACCESSOR(u_int32_t, sumsize);
    467 LFS_DEF_SB_ACCESSOR(u_int64_t, serial);
    468 LFS_DEF_SB_ACCESSOR(u_int32_t, ibsize);
    469 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, s0addr);
    470 LFS_DEF_SB_ACCESSOR(u_int64_t, tstamp);
    471 LFS_DEF_SB_ACCESSOR(u_int32_t, inodefmt);
    472 LFS_DEF_SB_ACCESSOR(u_int32_t, interleave);
    473 LFS_DEF_SB_ACCESSOR(u_int32_t, ident);
    474 LFS_DEF_SB_ACCESSOR(u_int32_t, resvseg);
    475 
    476 /* special-case accessors */
    477 
    478 /*
    479  * the v1 otstamp field lives in what's now dlfs_inopf
    480  */
    481 #define lfs_sb_getotstamp(fs) lfs_sb_getinopf(fs)
    482 #define lfs_sb_setotstamp(fs, val) lfs_sb_setinopf(fs, val)
    483 
    484 /*
    485  * lfs_sboffs is an array
    486  */
    487 static __unused inline int32_t
    488 lfs_sb_getsboff(STRUCT_LFS *fs, unsigned n)
    489 {
    490 #ifdef KASSERT /* ugh */
    491 	KASSERT(n < LFS_MAXNUMSB);
    492 #endif
    493 	return fs->lfs_dlfs.dlfs_sboffs[n];
    494 }
    495 static __unused inline void
    496 lfs_sb_setsboff(STRUCT_LFS *fs, unsigned n, int32_t val)
    497 {
    498 #ifdef KASSERT /* ugh */
    499 	KASSERT(n < LFS_MAXNUMSB);
    500 #endif
    501 	fs->lfs_dlfs.dlfs_sboffs[n] = val;
    502 }
    503 
    504 /*
    505  * lfs_fsmnt is a string
    506  */
    507 static __unused inline const char *
    508 lfs_sb_getfsmnt(STRUCT_LFS *fs)
    509 {
    510 	return fs->lfs_dlfs.dlfs_fsmnt;
    511 }
    512 
    513 /* LFS_NINDIR is the number of indirects in a file system block. */
    514 #define	LFS_NINDIR(fs)	(lfs_sb_getnindir(fs))
    515 
    516 /* LFS_INOPB is the number of inodes in a secondary storage block. */
    517 #define	LFS_INOPB(fs)	(lfs_sb_getinopb(fs))
    518 /* LFS_INOPF is the number of inodes in a fragment. */
    519 #define LFS_INOPF(fs)	(lfs_sb_getinopf(fs))
    520 
    521 #define	lfs_blkoff(fs, loc)	((int)((loc) & lfs_sb_getbmask(fs)))
    522 #define lfs_fragoff(fs, loc)    /* calculates (loc % fs->lfs_fsize) */ \
    523     ((int)((loc) & lfs_sb_getffmask(fs)))
    524 
    525 /* XXX: lowercase these as they're no longer macros */
    526 /* Frags to diskblocks */
    527 static __unused inline uint64_t
    528 LFS_FSBTODB(STRUCT_LFS *fs, uint64_t b)
    529 {
    530 #if defined(_KERNEL)
    531 	return b << (lfs_sb_getffshift(fs) - DEV_BSHIFT);
    532 #else
    533 	return b << lfs_sb_getfsbtodb(fs);
    534 #endif
    535 }
    536 /* Diskblocks to frags */
    537 static __unused inline uint64_t
    538 LFS_DBTOFSB(STRUCT_LFS *fs, uint64_t b)
    539 {
    540 #if defined(_KERNEL)
    541 	return b >> (lfs_sb_getffshift(fs) - DEV_BSHIFT);
    542 #else
    543 	return b >> lfs_sb_getfsbtodb(fs);
    544 #endif
    545 }
    546 
    547 #define	lfs_lblkno(fs, loc)	((loc) >> lfs_sb_getbshift(fs))
    548 #define	lfs_lblktosize(fs, blk)	((blk) << lfs_sb_getbshift(fs))
    549 
    550 /* Frags to bytes */
    551 static __unused inline uint64_t
    552 lfs_fsbtob(STRUCT_LFS *fs, uint64_t b)
    553 {
    554 	return b << lfs_sb_getffshift(fs);
    555 }
    556 /* Bytes to frags */
    557 static __unused inline uint64_t
    558 lfs_btofsb(STRUCT_LFS *fs, uint64_t b)
    559 {
    560 	return b >> lfs_sb_getffshift(fs);
    561 }
    562 
    563 #define lfs_numfrags(fs, loc)	/* calculates (loc / fs->lfs_fsize) */	\
    564 	((loc) >> lfs_sb_getffshift(fs))
    565 #define lfs_blkroundup(fs, size)/* calculates roundup(size, lfs_sb_getbsize(fs)) */ \
    566 	((off_t)(((size) + lfs_sb_getbmask(fs)) & (~lfs_sb_getbmask(fs))))
    567 #define lfs_fragroundup(fs, size)/* calculates roundup(size, fs->lfs_fsize) */ \
    568 	((off_t)(((size) + lfs_sb_getffmask(fs)) & (~lfs_sb_getffmask(fs))))
    569 #define lfs_fragstoblks(fs, frags)/* calculates (frags / fs->fs_frag) */ \
    570 	((frags) >> lfs_sb_getfbshift(fs))
    571 #define lfs_blkstofrags(fs, blks)/* calculates (blks * fs->fs_frag) */ \
    572 	((blks) << lfs_sb_getfbshift(fs))
    573 #define lfs_fragnum(fs, fsb)	/* calculates (fsb % fs->lfs_frag) */	\
    574 	((fsb) & ((fs)->lfs_frag - 1))
    575 #define lfs_blknum(fs, fsb)	/* calculates rounddown(fsb, fs->lfs_frag) */ \
    576 	((fsb) &~ ((fs)->lfs_frag - 1))
    577 #define lfs_dblksize(fs, dp, lbn) \
    578 	(((lbn) >= ULFS_NDADDR || (dp)->di_size >= ((lbn) + 1) << lfs_sb_getbshift(fs)) \
    579 	    ? lfs_sb_getbsize(fs) \
    580 	    : (lfs_fragroundup(fs, lfs_blkoff(fs, (dp)->di_size))))
    581 
    582 #define	lfs_segsize(fs)	(lfs_sb_getversion(fs) == 1 ?	     		\
    583 			   lfs_lblktosize((fs), lfs_sb_getssize(fs)) :	\
    584 			   lfs_sb_getssize(fs))
    585 /* XXX segtod produces a result in frags despite the 'd' */
    586 #define lfs_segtod(fs, seg) (lfs_btofsb(fs, lfs_segsize(fs)) * (seg))
    587 #define	lfs_dtosn(fs, daddr)	/* block address to segment number */	\
    588 	((uint32_t)(((daddr) - lfs_sb_gets0addr(fs)) / lfs_segtod((fs), 1)))
    589 #define lfs_sntod(fs, sn)	/* segment number to disk address */	\
    590 	((daddr_t)(lfs_segtod((fs), (sn)) + lfs_sb_gets0addr(fs)))
    591 
    592 /* XXX, blah. make this appear only if struct inode is defined */
    593 #ifdef _UFS_LFS_LFS_INODE_H_
    594 static __unused inline uint32_t
    595 lfs_blksize(STRUCT_LFS *fs, struct inode *ip, uint64_t lbn)
    596 {
    597 	if (lbn >= ULFS_NDADDR || ip->i_ffs1_size >= (lbn + 1) << lfs_sb_getbshift(fs)) {
    598 		return lfs_sb_getbsize(fs);
    599 	} else {
    600 		return lfs_fragroundup(fs, lfs_blkoff(fs, ip->i_ffs1_size));
    601 	}
    602 }
    603 #endif
    604 
    605 
    606 /*
    607  * Macros for determining free space on the disk, with the variable metadata
    608  * of segment summaries and inode blocks taken into account.
    609  */
    610 /*
    611  * Estimate number of clean blocks not available for writing because
    612  * they will contain metadata or overhead.  This is calculated as
    613  *
    614  *		E = ((C * M / D) * D + (0) * (T - D)) / T
    615  * or more simply
    616  *		E = (C * M) / T
    617  *
    618  * where
    619  * C is the clean space,
    620  * D is the dirty space,
    621  * M is the dirty metadata, and
    622  * T = C + D is the total space on disk.
    623  *
    624  * This approximates the old formula of E = C * M / D when D is close to T,
    625  * but avoids falsely reporting "disk full" when the sample size (D) is small.
    626  */
    627 #define LFS_EST_CMETA(F) (int32_t)((					\
    628 	(lfs_sb_getdmeta(F) * (int64_t)lfs_sb_getnclean(F)) / 		\
    629 	(lfs_sb_getnseg(F))))
    630 
    631 /* Estimate total size of the disk not including metadata */
    632 #define LFS_EST_NONMETA(F) (lfs_sb_getdsize(F) - lfs_sb_getdmeta(F) - LFS_EST_CMETA(F))
    633 
    634 /* Estimate number of blocks actually available for writing */
    635 #define LFS_EST_BFREE(F) (lfs_sb_getbfree(F) > LFS_EST_CMETA(F) ?	     \
    636 			  lfs_sb_getbfree(F) - LFS_EST_CMETA(F) : 0)
    637 
    638 /* Amount of non-meta space not available to mortal man */
    639 #define LFS_EST_RSVD(F) (int32_t)((LFS_EST_NONMETA(F) *			     \
    640 				   (u_int64_t)lfs_sb_getminfree(F)) /	     \
    641 				  100)
    642 
    643 /* Can credential C write BB blocks? XXX: kauth_cred_geteuid is abusive */
    644 #define ISSPACE(F, BB, C)						\
    645 	((((C) == NOCRED || kauth_cred_geteuid(C) == 0) &&		\
    646 	  LFS_EST_BFREE(F) >= (BB)) ||					\
    647 	 (kauth_cred_geteuid(C) != 0 && IS_FREESPACE(F, BB)))
    648 
    649 /* Can an ordinary user write BB blocks */
    650 #define IS_FREESPACE(F, BB)						\
    651 	  (LFS_EST_BFREE(F) >= (BB) + LFS_EST_RSVD(F))
    652 
    653 /*
    654  * The minimum number of blocks to create a new inode.  This is:
    655  * directory direct block (1) + ULFS_NIADDR indirect blocks + inode block (1) +
    656  * ifile direct block (1) + ULFS_NIADDR indirect blocks = 3 + 2 * ULFS_NIADDR blocks.
    657  */
    658 #define LFS_NRESERVE(F) (lfs_btofsb((F), (2 * ULFS_NIADDR + 3) << lfs_sb_getbshift(F)))
    659 
    660 
    661 
    662 #endif /* _UFS_LFS_LFS_ACCESSORS_H_ */
    663