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