Home | History | Annotate | Line # | Download | only in lfs
lfs_accessors.h revision 1.29
      1 /*	$NetBSD: lfs_accessors.h,v 1.29 2015/09/20 04:51:43 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 #if defined(_KERNEL_OPT)
    149 #include "opt_lfs.h"
    150 #endif
    151 
    152 #include <sys/bswap.h>
    153 
    154 #if !defined(_KERNEL) && !defined(_STANDALONE)
    155 #include <assert.h>
    156 #define KASSERT assert
    157 #endif
    158 
    159 /*
    160  * STRUCT_LFS is used by the libsa code to get accessors that work
    161  * with struct salfs instead of struct lfs, and by the cleaner to
    162  * get accessors that work with struct clfs.
    163  */
    164 
    165 #ifndef STRUCT_LFS
    166 #define STRUCT_LFS struct lfs
    167 #endif
    168 
    169 /*
    170  * byte order
    171  */
    172 
    173 /*
    174  * For now at least, the bootblocks shall not be endian-independent.
    175  * We can see later if it fits in the size budget. Also disable the
    176  * byteswapping if LFS_EI is off.
    177  *
    178  * Caution: these functions "know" that bswap16/32/64 are unsigned,
    179  * and if that changes will likely break silently.
    180  */
    181 
    182 #if defined(_STANDALONE) || (defined(_KERNEL) && !defined(LFS_EI))
    183 #define LFS_SWAP_int16_t(fs, val) (val)
    184 #define LFS_SWAP_int32_t(fs, val) (val)
    185 #define LFS_SWAP_int64_t(fs, val) (val)
    186 #define LFS_SWAP_uint16_t(fs, val) (val)
    187 #define LFS_SWAP_uint32_t(fs, val) (val)
    188 #define LFS_SWAP_uint64_t(fs, val) (val)
    189 #else
    190 #define LFS_SWAP_int16_t(fs, val) \
    191 	((fs)->lfs_dobyteswap ? (int16_t)bswap16(val) : (val))
    192 #define LFS_SWAP_int32_t(fs, val) \
    193 	((fs)->lfs_dobyteswap ? (int32_t)bswap32(val) : (val))
    194 #define LFS_SWAP_int64_t(fs, val) \
    195 	((fs)->lfs_dobyteswap ? (int64_t)bswap64(val) : (val))
    196 #define LFS_SWAP_uint16_t(fs, val) \
    197 	((fs)->lfs_dobyteswap ? bswap16(val) : (val))
    198 #define LFS_SWAP_uint32_t(fs, val) \
    199 	((fs)->lfs_dobyteswap ? bswap32(val) : (val))
    200 #define LFS_SWAP_uint64_t(fs, val) \
    201 	((fs)->lfs_dobyteswap ? bswap64(val) : (val))
    202 #endif
    203 
    204 /*
    205  * For handling directories we will need to know if the volume is
    206  * little-endian.
    207  */
    208 #if BYTE_ORDER == LITTLE_ENDIAN
    209 #define LFS_LITTLE_ENDIAN_ONDISK(fs) (!(fs)->lfs_dobyteswap)
    210 #else
    211 #define LFS_LITTLE_ENDIAN_ONDISK(fs) ((fs)->lfs_dobyteswap)
    212 #endif
    213 
    214 
    215 /*
    216  * directories
    217  */
    218 
    219 /*
    220  * The LFS_DIRSIZ macro gives the minimum record length which will hold
    221  * the directory entry.  This requires the amount of space in struct lfs_direct
    222  * without the d_name field, plus enough space for the name with a terminating
    223  * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
    224  */
    225 #define	LFS_DIRECTSIZ(namlen) \
    226 	(sizeof(struct lfs_dirheader) + (((namlen)+1 + 3) &~ 3))
    227 
    228 #if (BYTE_ORDER == LITTLE_ENDIAN)
    229 #define LFS_OLDDIRSIZ(oldfmt, dp, needswap)	\
    230     (((oldfmt) && !(needswap)) ?		\
    231     LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
    232 #else
    233 #define LFS_OLDDIRSIZ(oldfmt, dp, needswap)	\
    234     (((oldfmt) && (needswap)) ?			\
    235     LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
    236 #endif
    237 
    238 #define LFS_DIRSIZ(fs, dp) LFS_DIRECTSIZ(lfs_dir_getnamlen(fs, dp))
    239 
    240 /* Constants for the first argument of LFS_OLDDIRSIZ */
    241 #define LFS_OLDDIRFMT	1
    242 #define LFS_NEWDIRFMT	0
    243 
    244 #define LFS_NEXTDIR(fs, dp) \
    245 	((struct lfs_dirheader *)((char *)(dp) + lfs_dir_getreclen(fs, dp)))
    246 
    247 static __unused inline char *
    248 lfs_dir_nameptr(const STRUCT_LFS *fs, struct lfs_dirheader *dh)
    249 {
    250 	return (char *)(dh + 1);
    251 }
    252 
    253 static __unused inline uint32_t
    254 lfs_dir_getino(const STRUCT_LFS *fs, const struct lfs_dirheader *dh)
    255 {
    256 	return LFS_SWAP_uint32_t(fs, dh->dh_ino);
    257 }
    258 
    259 static __unused inline uint16_t
    260 lfs_dir_getreclen(const STRUCT_LFS *fs, const struct lfs_dirheader *dh)
    261 {
    262 	return LFS_SWAP_uint16_t(fs, dh->dh_reclen);
    263 }
    264 
    265 static __unused inline uint8_t
    266 lfs_dir_gettype(const STRUCT_LFS *fs, const struct lfs_dirheader *dh)
    267 {
    268 	if (fs->lfs_hasolddirfmt) {
    269 		return LFS_DT_UNKNOWN;
    270 	}
    271 	return dh->dh_type;
    272 }
    273 
    274 static __unused inline uint8_t
    275 lfs_dir_getnamlen(const STRUCT_LFS *fs, const struct lfs_dirheader *dh)
    276 {
    277 	if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
    278 		/* low-order byte of old 16-bit namlen field */
    279 		return dh->dh_type;
    280 	}
    281 	return dh->dh_namlen;
    282 }
    283 
    284 static __unused inline void
    285 lfs_dir_setino(STRUCT_LFS *fs, struct lfs_dirheader *dh, uint32_t ino)
    286 {
    287 	dh->dh_ino = LFS_SWAP_uint32_t(fs, ino);
    288 }
    289 
    290 static __unused inline void
    291 lfs_dir_setreclen(STRUCT_LFS *fs, struct lfs_dirheader *dh, uint16_t reclen)
    292 {
    293 	dh->dh_reclen = LFS_SWAP_uint16_t(fs, reclen);
    294 }
    295 
    296 static __unused inline void
    297 lfs_dir_settype(const STRUCT_LFS *fs, struct lfs_dirheader *dh, uint8_t type)
    298 {
    299 	if (fs->lfs_hasolddirfmt) {
    300 		/* do nothing */
    301 		return;
    302 	}
    303 	dh->dh_type = type;
    304 }
    305 
    306 static __unused inline void
    307 lfs_dir_setnamlen(const STRUCT_LFS *fs, struct lfs_dirheader *dh, uint8_t namlen)
    308 {
    309 	if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
    310 		/* low-order byte of old 16-bit namlen field */
    311 		dh->dh_type = namlen;
    312 	}
    313 	dh->dh_namlen = namlen;
    314 }
    315 
    316 static __unused inline void
    317 lfs_copydirname(STRUCT_LFS *fs, char *dest, const char *src,
    318 		unsigned namlen, unsigned reclen)
    319 {
    320 	unsigned spacelen;
    321 
    322 	KASSERT(reclen > sizeof(struct lfs_dirheader));
    323 	spacelen = reclen - sizeof(struct lfs_dirheader);
    324 
    325 	/* must always be at least 1 byte as a null terminator */
    326 	KASSERT(spacelen > namlen);
    327 
    328 	memcpy(dest, src, namlen);
    329 	memset(dest + namlen, '\0', spacelen - namlen);
    330 }
    331 
    332 /*
    333  * dinodes
    334  */
    335 
    336 /*
    337  * Maximum length of a symlink that can be stored within the inode.
    338  */
    339 #define LFS32_MAXSYMLINKLEN	((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int32_t))
    340 #define LFS64_MAXSYMLINKLEN	((ULFS_NDADDR + ULFS_NIADDR) * sizeof(int64_t))
    341 
    342 #define LFS_MAXSYMLINKLEN(fs) \
    343 	((fs)->lfs_is64 ? LFS64_MAXSYMLINKLEN : LFS32_MAXSYMLINKLEN)
    344 
    345 #define DINOSIZE(fs) ((fs)->lfs_is64 ? sizeof(struct lfs64_dinode) : sizeof(struct lfs32_dinode))
    346 
    347 #define DINO_IN_BLOCK(fs, base, ix) \
    348 	((union lfs_dinode *)((char *)(base) + DINOSIZE(fs) * (ix)))
    349 
    350 static __unused inline void
    351 lfs_copy_dinode(STRUCT_LFS *fs,
    352     union lfs_dinode *dst, const union lfs_dinode *src)
    353 {
    354 	/*
    355 	 * We can do structure assignment of the structs, but not of
    356 	 * the whole union, as the union is the size of the (larger)
    357 	 * 64-bit struct and on a 32-bit fs the upper half of it might
    358 	 * be off the end of a buffer or otherwise invalid.
    359 	 */
    360 	if (fs->lfs_is64) {
    361 		dst->u_64 = src->u_64;
    362 	} else {
    363 		dst->u_32 = src->u_32;
    364 	}
    365 }
    366 
    367 #define LFS_DEF_DINO_ACCESSOR(type, type32, field) \
    368 	static __unused inline type				\
    369 	lfs_dino_get##field(STRUCT_LFS *fs, union lfs_dinode *dip) \
    370 	{							\
    371 		if (fs->lfs_is64) {				\
    372 			return LFS_SWAP_##type(fs, dip->u_64.di_##field); \
    373 		} else {					\
    374 			return LFS_SWAP_##type32(fs, dip->u_32.di_##field); \
    375 		}						\
    376 	}							\
    377 	static __unused inline void				\
    378 	lfs_dino_set##field(STRUCT_LFS *fs, union lfs_dinode *dip, type val) \
    379 	{							\
    380 		if (fs->lfs_is64) {				\
    381 			type *p = &dip->u_64.di_##field;	\
    382 			(void)p;				\
    383 			dip->u_64.di_##field = LFS_SWAP_##type(fs, val); \
    384 		} else {					\
    385 			type32 *p = &dip->u_32.di_##field;	\
    386 			(void)p;				\
    387 			dip->u_32.di_##field = LFS_SWAP_##type32(fs, val); \
    388 		}						\
    389 	}							\
    390 
    391 LFS_DEF_DINO_ACCESSOR(uint16_t, uint16_t, mode);
    392 LFS_DEF_DINO_ACCESSOR(int16_t, int16_t, nlink);
    393 LFS_DEF_DINO_ACCESSOR(uint64_t, uint32_t, inumber);
    394 LFS_DEF_DINO_ACCESSOR(uint64_t, uint64_t, size);
    395 LFS_DEF_DINO_ACCESSOR(int64_t, int32_t, atime);
    396 LFS_DEF_DINO_ACCESSOR(int32_t, int32_t, atimensec);
    397 LFS_DEF_DINO_ACCESSOR(int64_t, int32_t, mtime);
    398 LFS_DEF_DINO_ACCESSOR(int32_t, int32_t, mtimensec);
    399 LFS_DEF_DINO_ACCESSOR(int64_t, int32_t, ctime);
    400 LFS_DEF_DINO_ACCESSOR(int32_t, int32_t, ctimensec);
    401 LFS_DEF_DINO_ACCESSOR(uint32_t, uint32_t, flags);
    402 LFS_DEF_DINO_ACCESSOR(uint64_t, uint32_t, blocks);
    403 LFS_DEF_DINO_ACCESSOR(int32_t, int32_t, gen);
    404 LFS_DEF_DINO_ACCESSOR(uint32_t, uint32_t, uid);
    405 LFS_DEF_DINO_ACCESSOR(uint32_t, uint32_t, gid);
    406 
    407 /* XXX this should be done differently (it's a fake field) */
    408 LFS_DEF_DINO_ACCESSOR(uint64_t, int32_t, rdev);
    409 
    410 static __unused inline daddr_t
    411 lfs_dino_getdb(STRUCT_LFS *fs, union lfs_dinode *dip, unsigned ix)
    412 {
    413 	KASSERT(ix < ULFS_NDADDR);
    414 	if (fs->lfs_is64) {
    415 		return dip->u_64.di_db[ix];
    416 	} else {
    417 		return dip->u_32.di_db[ix];
    418 	}
    419 }
    420 
    421 static __unused inline daddr_t
    422 lfs_dino_getib(STRUCT_LFS *fs, union lfs_dinode *dip, unsigned ix)
    423 {
    424 	KASSERT(ix < ULFS_NIADDR);
    425 	if (fs->lfs_is64) {
    426 		return dip->u_64.di_ib[ix];
    427 	} else {
    428 		return dip->u_32.di_ib[ix];
    429 	}
    430 }
    431 
    432 static __unused inline void
    433 lfs_dino_setdb(STRUCT_LFS *fs, union lfs_dinode *dip, unsigned ix, daddr_t val)
    434 {
    435 	KASSERT(ix < ULFS_NDADDR);
    436 	if (fs->lfs_is64) {
    437 		dip->u_64.di_db[ix] = val;
    438 	} else {
    439 		dip->u_32.di_db[ix] = val;
    440 	}
    441 }
    442 
    443 static __unused inline void
    444 lfs_dino_setib(STRUCT_LFS *fs, union lfs_dinode *dip, unsigned ix, daddr_t val)
    445 {
    446 	KASSERT(ix < ULFS_NIADDR);
    447 	if (fs->lfs_is64) {
    448 		dip->u_64.di_ib[ix] = val;
    449 	} else {
    450 		dip->u_32.di_ib[ix] = val;
    451 	}
    452 }
    453 
    454 /* birthtime is present only in the 64-bit inode */
    455 static __unused inline void
    456 lfs_dino_setbirthtime(STRUCT_LFS *fs, union lfs_dinode *dip,
    457     const struct timespec *ts)
    458 {
    459 	if (fs->lfs_is64) {
    460 		dip->u_64.di_birthtime = ts->tv_sec;
    461 		dip->u_64.di_birthnsec = ts->tv_nsec;
    462 	} else {
    463 		/* drop it on the floor */
    464 	}
    465 }
    466 
    467 /*
    468  * indirect blocks
    469  */
    470 
    471 static __unused inline daddr_t
    472 lfs_iblock_get(STRUCT_LFS *fs, void *block, unsigned ix)
    473 {
    474 	if (fs->lfs_is64) {
    475 		// XXX re-enable these asserts after reorging this file
    476 		//KASSERT(ix < lfs_sb_getbsize(fs) / sizeof(int64_t));
    477 		return (daddr_t)(((int64_t *)block)[ix]);
    478 	} else {
    479 		//KASSERT(ix < lfs_sb_getbsize(fs) / sizeof(int32_t));
    480 		/* must sign-extend or UNWRITTEN gets trashed */
    481 		return (daddr_t)(int64_t)(((int32_t *)block)[ix]);
    482 	}
    483 }
    484 
    485 static __unused inline void
    486 lfs_iblock_set(STRUCT_LFS *fs, void *block, unsigned ix, daddr_t val)
    487 {
    488 	if (fs->lfs_is64) {
    489 		//KASSERT(ix < lfs_sb_getbsize(fs) / sizeof(int64_t));
    490 		((int64_t *)block)[ix] = val;
    491 	} else {
    492 		//KASSERT(ix < lfs_sb_getbsize(fs) / sizeof(int32_t));
    493 		((int32_t *)block)[ix] = val;
    494 	}
    495 }
    496 
    497 /*
    498  * "struct buf" associated definitions
    499  */
    500 
    501 # define LFS_LOCK_BUF(bp) do {						\
    502 	if (((bp)->b_flags & B_LOCKED) == 0 && bp->b_iodone == NULL) {	\
    503 		mutex_enter(&lfs_lock);					\
    504 		++locked_queue_count;					\
    505 		locked_queue_bytes += bp->b_bufsize;			\
    506 		mutex_exit(&lfs_lock);					\
    507 	}								\
    508 	(bp)->b_flags |= B_LOCKED;					\
    509 } while (0)
    510 
    511 # define LFS_UNLOCK_BUF(bp) do {					\
    512 	if (((bp)->b_flags & B_LOCKED) != 0 && bp->b_iodone == NULL) {	\
    513 		mutex_enter(&lfs_lock);					\
    514 		--locked_queue_count;					\
    515 		locked_queue_bytes -= bp->b_bufsize;			\
    516 		if (locked_queue_count < LFS_WAIT_BUFS &&		\
    517 		    locked_queue_bytes < LFS_WAIT_BYTES)		\
    518 			cv_broadcast(&locked_queue_cv);			\
    519 		mutex_exit(&lfs_lock);					\
    520 	}								\
    521 	(bp)->b_flags &= ~B_LOCKED;					\
    522 } while (0)
    523 
    524 /*
    525  * "struct inode" associated definitions
    526  */
    527 
    528 #define LFS_SET_UINO(ip, flags) do {					\
    529 	if (((flags) & IN_ACCESSED) && !((ip)->i_flag & IN_ACCESSED))	\
    530 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    531 	if (((flags) & IN_CLEANING) && !((ip)->i_flag & IN_CLEANING))	\
    532 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    533 	if (((flags) & IN_MODIFIED) && !((ip)->i_flag & IN_MODIFIED))	\
    534 		lfs_sb_adduinodes((ip)->i_lfs, 1);			\
    535 	(ip)->i_flag |= (flags);					\
    536 } while (0)
    537 
    538 #define LFS_CLR_UINO(ip, flags) do {					\
    539 	if (((flags) & IN_ACCESSED) && ((ip)->i_flag & IN_ACCESSED))	\
    540 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    541 	if (((flags) & IN_CLEANING) && ((ip)->i_flag & IN_CLEANING))	\
    542 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    543 	if (((flags) & IN_MODIFIED) && ((ip)->i_flag & IN_MODIFIED))	\
    544 		lfs_sb_subuinodes((ip)->i_lfs, 1);			\
    545 	(ip)->i_flag &= ~(flags);					\
    546 	if (lfs_sb_getuinodes((ip)->i_lfs) < 0) {			\
    547 		panic("lfs_uinodes < 0");				\
    548 	}								\
    549 } while (0)
    550 
    551 #define LFS_ITIMES(ip, acc, mod, cre) \
    552 	while ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY)) \
    553 		lfs_itimes(ip, acc, mod, cre)
    554 
    555 /*
    556  * On-disk and in-memory checkpoint segment usage structure.
    557  */
    558 
    559 #define	SEGUPB(fs)	(lfs_sb_getsepb(fs))
    560 #define	SEGTABSIZE_SU(fs)						\
    561 	((lfs_sb_getnseg(fs) + SEGUPB(fs) - 1) / lfs_sb_getsepb(fs))
    562 
    563 #ifdef _KERNEL
    564 # define SHARE_IFLOCK(F) 						\
    565   do {									\
    566 	rw_enter(&(F)->lfs_iflock, RW_READER);				\
    567   } while(0)
    568 # define UNSHARE_IFLOCK(F)						\
    569   do {									\
    570 	rw_exit(&(F)->lfs_iflock);					\
    571   } while(0)
    572 #else /* ! _KERNEL */
    573 # define SHARE_IFLOCK(F)
    574 # define UNSHARE_IFLOCK(F)
    575 #endif /* ! _KERNEL */
    576 
    577 /* Read in the block with a specific segment usage entry from the ifile. */
    578 #define	LFS_SEGENTRY(SP, F, IN, BP) do {				\
    579 	int _e;								\
    580 	SHARE_IFLOCK(F);						\
    581 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    582 	if ((_e = bread((F)->lfs_ivnode,				\
    583 	    ((IN) / lfs_sb_getsepb(F)) + lfs_sb_getcleansz(F),		\
    584 	    lfs_sb_getbsize(F), 0, &(BP))) != 0)			\
    585 		panic("lfs: ifile read: %d", _e);			\
    586 	if (lfs_sb_getversion(F) == 1)					\
    587 		(SP) = (SEGUSE *)((SEGUSE_V1 *)(BP)->b_data +		\
    588 			((IN) & (lfs_sb_getsepb(F) - 1)));		\
    589 	else								\
    590 		(SP) = (SEGUSE *)(BP)->b_data + ((IN) % lfs_sb_getsepb(F)); \
    591 	UNSHARE_IFLOCK(F);						\
    592 } while (0)
    593 
    594 #define LFS_WRITESEGENTRY(SP, F, IN, BP) do {				\
    595 	if ((SP)->su_nbytes == 0)					\
    596 		(SP)->su_flags |= SEGUSE_EMPTY;				\
    597 	else								\
    598 		(SP)->su_flags &= ~SEGUSE_EMPTY;			\
    599 	(F)->lfs_suflags[(F)->lfs_activesb][(IN)] = (SP)->su_flags;	\
    600 	LFS_BWRITE_LOG(BP);						\
    601 } while (0)
    602 
    603 /*
    604  * FINFO (file info) entries.
    605  */
    606 
    607 /* Size of an on-disk block pointer, e.g. in an indirect block. */
    608 /* XXX: move to a more suitable location in this file */
    609 #define LFS_BLKPTRSIZE(fs) ((fs)->lfs_is64 ? sizeof(int64_t) : sizeof(int32_t))
    610 
    611 /* Size of an on-disk inode number. */
    612 /* XXX: move to a more suitable location in this file */
    613 #define LFS_INUMSIZE(fs) ((fs)->lfs_is64 ? sizeof(int64_t) : sizeof(int32_t))
    614 
    615 /* size of a FINFO, without the block pointers */
    616 #define	FINFOSIZE(fs)	((fs)->lfs_is64 ? sizeof(FINFO64) : sizeof(FINFO32))
    617 
    618 /* Full size of the provided FINFO record, including its block pointers. */
    619 #define FINFO_FULLSIZE(fs, fip) \
    620 	(FINFOSIZE(fs) + lfs_fi_getnblocks(fs, fip) * LFS_BLKPTRSIZE(fs))
    621 
    622 #define NEXT_FINFO(fs, fip) \
    623 	((FINFO *)((char *)(fip) + FINFO_FULLSIZE(fs, fip)))
    624 
    625 #define LFS_DEF_FI_ACCESSOR(type, type32, field) \
    626 	static __unused inline type				\
    627 	lfs_fi_get##field(STRUCT_LFS *fs, FINFO *fip)		\
    628 	{							\
    629 		if (fs->lfs_is64) {				\
    630 			return fip->u_64.fi_##field; 		\
    631 		} else {					\
    632 			return fip->u_32.fi_##field; 		\
    633 		}						\
    634 	}							\
    635 	static __unused inline void				\
    636 	lfs_fi_set##field(STRUCT_LFS *fs, FINFO *fip, type val) \
    637 	{							\
    638 		if (fs->lfs_is64) {				\
    639 			type *p = &fip->u_64.fi_##field;	\
    640 			(void)p;				\
    641 			fip->u_64.fi_##field = val;		\
    642 		} else {					\
    643 			type32 *p = &fip->u_32.fi_##field;	\
    644 			(void)p;				\
    645 			fip->u_32.fi_##field = val;		\
    646 		}						\
    647 	}							\
    648 
    649 LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, nblocks);
    650 LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, version);
    651 LFS_DEF_FI_ACCESSOR(uint64_t, uint32_t, ino);
    652 LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, lastlength);
    653 
    654 static __unused inline daddr_t
    655 lfs_fi_getblock(STRUCT_LFS *fs, FINFO *fip, unsigned index)
    656 {
    657 	void *firstblock;
    658 
    659 	firstblock = (char *)fip + FINFOSIZE(fs);
    660 	KASSERT(index < lfs_fi_getnblocks(fs, fip));
    661 	if (fs->lfs_is64) {
    662 		return ((int64_t *)firstblock)[index];
    663 	} else {
    664 		return ((int32_t *)firstblock)[index];
    665 	}
    666 }
    667 
    668 static __unused inline void
    669 lfs_fi_setblock(STRUCT_LFS *fs, FINFO *fip, unsigned index, daddr_t blk)
    670 {
    671 	void *firstblock;
    672 
    673 	firstblock = (char *)fip + FINFOSIZE(fs);
    674 	KASSERT(index < lfs_fi_getnblocks(fs, fip));
    675 	if (fs->lfs_is64) {
    676 		((int64_t *)firstblock)[index] = blk;
    677 	} else {
    678 		((int32_t *)firstblock)[index] = blk;
    679 	}
    680 }
    681 
    682 /*
    683  * Index file inode entries.
    684  */
    685 
    686 /*
    687  * LFSv1 compatibility code is not allowed to touch if_atime, since it
    688  * may not be mapped!
    689  */
    690 /* Read in the block with a specific inode from the ifile. */
    691 #define	LFS_IENTRY(IP, F, IN, BP) do {					\
    692 	int _e;								\
    693 	SHARE_IFLOCK(F);						\
    694 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    695 	if ((_e = bread((F)->lfs_ivnode,				\
    696 	(IN) / lfs_sb_getifpb(F) + lfs_sb_getcleansz(F) + lfs_sb_getsegtabsz(F), \
    697 	lfs_sb_getbsize(F), 0, &(BP))) != 0)				\
    698 		panic("lfs: ifile ino %d read %d", (int)(IN), _e);	\
    699 	if ((F)->lfs_is64) {						\
    700 		(IP) = (IFILE *)((IFILE64 *)(BP)->b_data +		\
    701 				 (IN) % lfs_sb_getifpb(F));		\
    702 	} else if (lfs_sb_getversion(F) > 1) {				\
    703 		(IP) = (IFILE *)((IFILE32 *)(BP)->b_data +		\
    704 				(IN) % lfs_sb_getifpb(F)); 		\
    705 	} else {							\
    706 		(IP) = (IFILE *)((IFILE_V1 *)(BP)->b_data +		\
    707 				 (IN) % lfs_sb_getifpb(F));		\
    708 	}								\
    709 	UNSHARE_IFLOCK(F);						\
    710 } while (0)
    711 #define LFS_IENTRY_NEXT(IP, F) do { \
    712 	if ((F)->lfs_is64) {						\
    713 		(IP) = (IFILE *)((IFILE64 *)(IP) + 1);			\
    714 	} else if (lfs_sb_getversion(F) > 1) {				\
    715 		(IP) = (IFILE *)((IFILE32 *)(IP) + 1);			\
    716 	} else {							\
    717 		(IP) = (IFILE *)((IFILE_V1 *)(IP) + 1);			\
    718 	}								\
    719 } while (0)
    720 
    721 #define LFS_DEF_IF_ACCESSOR(type, type32, field) \
    722 	static __unused inline type				\
    723 	lfs_if_get##field(STRUCT_LFS *fs, IFILE *ifp)		\
    724 	{							\
    725 		if (fs->lfs_is64) {				\
    726 			return ifp->u_64.if_##field; 		\
    727 		} else {					\
    728 			return ifp->u_32.if_##field; 		\
    729 		}						\
    730 	}							\
    731 	static __unused inline void				\
    732 	lfs_if_set##field(STRUCT_LFS *fs, IFILE *ifp, type val) \
    733 	{							\
    734 		if (fs->lfs_is64) {				\
    735 			type *p = &ifp->u_64.if_##field;	\
    736 			(void)p;				\
    737 			ifp->u_64.if_##field = val;		\
    738 		} else {					\
    739 			type32 *p = &ifp->u_32.if_##field;	\
    740 			(void)p;				\
    741 			ifp->u_32.if_##field = val;		\
    742 		}						\
    743 	}							\
    744 
    745 LFS_DEF_IF_ACCESSOR(u_int32_t, u_int32_t, version);
    746 LFS_DEF_IF_ACCESSOR(int64_t, int32_t, daddr);
    747 LFS_DEF_IF_ACCESSOR(u_int64_t, u_int32_t, nextfree);
    748 LFS_DEF_IF_ACCESSOR(u_int32_t, u_int32_t, atime_sec);
    749 LFS_DEF_IF_ACCESSOR(u_int32_t, u_int32_t, atime_nsec);
    750 
    751 /*
    752  * Cleaner information structure.  This resides in the ifile and is used
    753  * to pass information from the kernel to the cleaner.
    754  */
    755 
    756 #define	CLEANSIZE_SU(fs)						\
    757 	((((fs)->lfs_is64 ? sizeof(CLEANERINFO64) : sizeof(CLEANERINFO32)) + \
    758 		lfs_sb_getbsize(fs) - 1) >> lfs_sb_getbshift(fs))
    759 
    760 #define LFS_DEF_CI_ACCESSOR(type, type32, field) \
    761 	static __unused inline type				\
    762 	lfs_ci_get##field(STRUCT_LFS *fs, CLEANERINFO *cip)	\
    763 	{							\
    764 		if (fs->lfs_is64) {				\
    765 			return cip->u_64.field; 		\
    766 		} else {					\
    767 			return cip->u_32.field; 		\
    768 		}						\
    769 	}							\
    770 	static __unused inline void				\
    771 	lfs_ci_set##field(STRUCT_LFS *fs, CLEANERINFO *cip, type val) \
    772 	{							\
    773 		if (fs->lfs_is64) {				\
    774 			type *p = &cip->u_64.field;		\
    775 			(void)p;				\
    776 			cip->u_64.field = val;			\
    777 		} else {					\
    778 			type32 *p = &cip->u_32.field;		\
    779 			(void)p;				\
    780 			cip->u_32.field = val;			\
    781 		}						\
    782 	}							\
    783 
    784 LFS_DEF_CI_ACCESSOR(u_int32_t, u_int32_t, clean);
    785 LFS_DEF_CI_ACCESSOR(u_int32_t, u_int32_t, dirty);
    786 LFS_DEF_CI_ACCESSOR(int64_t, int32_t, bfree);
    787 LFS_DEF_CI_ACCESSOR(int64_t, int32_t, avail);
    788 LFS_DEF_CI_ACCESSOR(u_int64_t, u_int32_t, free_head);
    789 LFS_DEF_CI_ACCESSOR(u_int64_t, u_int32_t, free_tail);
    790 LFS_DEF_CI_ACCESSOR(u_int32_t, u_int32_t, flags);
    791 
    792 static __unused inline void
    793 lfs_ci_shiftcleantodirty(STRUCT_LFS *fs, CLEANERINFO *cip, unsigned num)
    794 {
    795 	lfs_ci_setclean(fs, cip, lfs_ci_getclean(fs, cip) - num);
    796 	lfs_ci_setdirty(fs, cip, lfs_ci_getdirty(fs, cip) + num);
    797 }
    798 
    799 static __unused inline void
    800 lfs_ci_shiftdirtytoclean(STRUCT_LFS *fs, CLEANERINFO *cip, unsigned num)
    801 {
    802 	lfs_ci_setdirty(fs, cip, lfs_ci_getdirty(fs, cip) - num);
    803 	lfs_ci_setclean(fs, cip, lfs_ci_getclean(fs, cip) + num);
    804 }
    805 
    806 /* Read in the block with the cleaner info from the ifile. */
    807 #define LFS_CLEANERINFO(CP, F, BP) do {					\
    808 	SHARE_IFLOCK(F);						\
    809 	VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS;			\
    810 	if (bread((F)->lfs_ivnode,					\
    811 	    (daddr_t)0, lfs_sb_getbsize(F), 0, &(BP)))			\
    812 		panic("lfs: ifile read");				\
    813 	(CP) = (CLEANERINFO *)(BP)->b_data;				\
    814 	UNSHARE_IFLOCK(F);						\
    815 } while (0)
    816 
    817 /*
    818  * Synchronize the Ifile cleaner info with current avail and bfree.
    819  */
    820 #define LFS_SYNC_CLEANERINFO(cip, fs, bp, w) do {		 	\
    821     mutex_enter(&lfs_lock);						\
    822     if ((w) || lfs_ci_getbfree(fs, cip) != lfs_sb_getbfree(fs) ||	\
    823 	lfs_ci_getavail(fs, cip) != lfs_sb_getavail(fs) - fs->lfs_ravail - \
    824 	fs->lfs_favail) {	 					\
    825 	lfs_ci_setbfree(fs, cip, lfs_sb_getbfree(fs));		 	\
    826 	lfs_ci_setavail(fs, cip, lfs_sb_getavail(fs) - fs->lfs_ravail -	\
    827 		fs->lfs_favail);				 	\
    828 	if (((bp)->b_flags & B_GATHERED) == 0) {		 	\
    829 		fs->lfs_flags |= LFS_IFDIRTY;				\
    830 	}								\
    831 	mutex_exit(&lfs_lock);						\
    832 	(void) LFS_BWRITE_LOG(bp); /* Ifile */			 	\
    833     } else {							 	\
    834 	mutex_exit(&lfs_lock);						\
    835 	brelse(bp, 0);						 	\
    836     }									\
    837 } while (0)
    838 
    839 /*
    840  * Get the head of the inode free list.
    841  * Always called with the segment lock held.
    842  */
    843 #define LFS_GET_HEADFREE(FS, CIP, BP, FREEP) do {			\
    844 	if (lfs_sb_getversion(FS) > 1) {				\
    845 		LFS_CLEANERINFO((CIP), (FS), (BP));			\
    846 		lfs_sb_setfreehd(FS, lfs_ci_getfree_head(FS, CIP));	\
    847 		brelse(BP, 0);						\
    848 	}								\
    849 	*(FREEP) = lfs_sb_getfreehd(FS);				\
    850 } while (0)
    851 
    852 #define LFS_PUT_HEADFREE(FS, CIP, BP, VAL) do {				\
    853 	lfs_sb_setfreehd(FS, VAL);					\
    854 	if (lfs_sb_getversion(FS) > 1) {				\
    855 		LFS_CLEANERINFO((CIP), (FS), (BP));			\
    856 		lfs_ci_setfree_head(FS, CIP, VAL);			\
    857 		LFS_BWRITE_LOG(BP);					\
    858 		mutex_enter(&lfs_lock);					\
    859 		(FS)->lfs_flags |= LFS_IFDIRTY;				\
    860 		mutex_exit(&lfs_lock);					\
    861 	}								\
    862 } while (0)
    863 
    864 #define LFS_GET_TAILFREE(FS, CIP, BP, FREEP) do {			\
    865 	LFS_CLEANERINFO((CIP), (FS), (BP));				\
    866 	*(FREEP) = lfs_ci_getfree_tail(FS, CIP);			\
    867 	brelse(BP, 0);							\
    868 } while (0)
    869 
    870 #define LFS_PUT_TAILFREE(FS, CIP, BP, VAL) do {				\
    871 	LFS_CLEANERINFO((CIP), (FS), (BP));				\
    872 	lfs_ci_setfree_tail(FS, CIP, VAL);				\
    873 	LFS_BWRITE_LOG(BP);						\
    874 	mutex_enter(&lfs_lock);						\
    875 	(FS)->lfs_flags |= LFS_IFDIRTY;					\
    876 	mutex_exit(&lfs_lock);						\
    877 } while (0)
    878 
    879 /*
    880  * On-disk segment summary information
    881  */
    882 
    883 #define SEGSUM_SIZE(fs) \
    884 	(fs->lfs_is64 ? sizeof(SEGSUM64) : \
    885 	 lfs_sb_getversion(fs) > 1 ? sizeof(SEGSUM32) : sizeof(SEGSUM_V1))
    886 
    887 /*
    888  * The SEGSUM structure is followed by FINFO structures. Get the pointer
    889  * to the first FINFO.
    890  *
    891  * XXX this can't be a macro yet; this file needs to be resorted.
    892  */
    893 #if 0
    894 static __unused inline FINFO *
    895 segsum_finfobase(STRUCT_LFS *fs, SEGSUM *ssp)
    896 {
    897 	return (FINFO *)((char *)ssp + SEGSUM_SIZE(fs));
    898 }
    899 #else
    900 #define SEGSUM_FINFOBASE(fs, ssp) \
    901 	((FINFO *)((char *)(ssp) + SEGSUM_SIZE(fs)));
    902 #endif
    903 
    904 #define LFS_DEF_SS_ACCESSOR(type, type32, field) \
    905 	static __unused inline type				\
    906 	lfs_ss_get##field(STRUCT_LFS *fs, SEGSUM *ssp)		\
    907 	{							\
    908 		if (fs->lfs_is64) {				\
    909 			return ssp->u_64.ss_##field; 		\
    910 		} else {					\
    911 			return ssp->u_32.ss_##field; 		\
    912 		}						\
    913 	}							\
    914 	static __unused inline void				\
    915 	lfs_ss_set##field(STRUCT_LFS *fs, SEGSUM *ssp, type val) \
    916 	{							\
    917 		if (fs->lfs_is64) {				\
    918 			type *p = &ssp->u_64.ss_##field;	\
    919 			(void)p;				\
    920 			ssp->u_64.ss_##field = val;		\
    921 		} else {					\
    922 			type32 *p = &ssp->u_32.ss_##field;	\
    923 			(void)p;				\
    924 			ssp->u_32.ss_##field = val;		\
    925 		}						\
    926 	}							\
    927 
    928 LFS_DEF_SS_ACCESSOR(uint32_t, uint32_t, sumsum);
    929 LFS_DEF_SS_ACCESSOR(uint32_t, uint32_t, datasum);
    930 LFS_DEF_SS_ACCESSOR(uint32_t, uint32_t, magic);
    931 LFS_DEF_SS_ACCESSOR(uint32_t, uint32_t, ident);
    932 LFS_DEF_SS_ACCESSOR(int64_t, int32_t, next);
    933 LFS_DEF_SS_ACCESSOR(uint16_t, uint16_t, nfinfo);
    934 LFS_DEF_SS_ACCESSOR(uint16_t, uint16_t, ninos);
    935 LFS_DEF_SS_ACCESSOR(uint16_t, uint16_t, flags);
    936 LFS_DEF_SS_ACCESSOR(uint64_t, uint32_t, reclino);
    937 LFS_DEF_SS_ACCESSOR(uint64_t, uint64_t, serial);
    938 LFS_DEF_SS_ACCESSOR(uint64_t, uint64_t, create);
    939 
    940 static __unused inline size_t
    941 lfs_ss_getsumstart(STRUCT_LFS *fs)
    942 {
    943 	/* These are actually all the same. */
    944 	if (fs->lfs_is64) {
    945 		return offsetof(SEGSUM64, ss_datasum);
    946 	} else /* if (lfs_sb_getversion(fs) > 1) */ {
    947 		return offsetof(SEGSUM32, ss_datasum);
    948 	} /* else {
    949 		return offsetof(SEGSUM_V1, ss_datasum);
    950 	} */
    951 	/*
    952 	 * XXX ^^^ until this file is resorted lfs_sb_getversion isn't
    953 	 * defined yet.
    954 	 */
    955 }
    956 
    957 static __unused inline uint32_t
    958 lfs_ss_getocreate(STRUCT_LFS *fs, SEGSUM *ssp)
    959 {
    960 	KASSERT(fs->lfs_is64 == 0);
    961 	/* XXX need to resort this file before we can do this */
    962 	//KASSERT(lfs_sb_getversion(fs) == 1);
    963 
    964 	return ssp->u_v1.ss_create;
    965 }
    966 
    967 static __unused inline void
    968 lfs_ss_setocreate(STRUCT_LFS *fs, SEGSUM *ssp, uint32_t val)
    969 {
    970 	KASSERT(fs->lfs_is64 == 0);
    971 	/* XXX need to resort this file before we can do this */
    972 	//KASSERT(lfs_sb_getversion(fs) == 1);
    973 
    974 	ssp->u_v1.ss_create = val;
    975 }
    976 
    977 
    978 /*
    979  * Super block.
    980  */
    981 
    982 /*
    983  * Generate accessors for the on-disk superblock fields with cpp.
    984  */
    985 
    986 #define LFS_DEF_SB_ACCESSOR_FULL(type, type32, field) \
    987 	static __unused inline type				\
    988 	lfs_sb_get##field(STRUCT_LFS *fs)			\
    989 	{							\
    990 		if (fs->lfs_is64) {				\
    991 			return fs->lfs_dlfs_u.u_64.dlfs_##field; \
    992 		} else {					\
    993 			return fs->lfs_dlfs_u.u_32.dlfs_##field; \
    994 		}						\
    995 	}							\
    996 	static __unused inline void				\
    997 	lfs_sb_set##field(STRUCT_LFS *fs, type val)		\
    998 	{							\
    999 		if (fs->lfs_is64) {				\
   1000 			fs->lfs_dlfs_u.u_64.dlfs_##field = val;	\
   1001 		} else {					\
   1002 			fs->lfs_dlfs_u.u_32.dlfs_##field = val;	\
   1003 		}						\
   1004 	}							\
   1005 	static __unused inline void				\
   1006 	lfs_sb_add##field(STRUCT_LFS *fs, type val)		\
   1007 	{							\
   1008 		if (fs->lfs_is64) {				\
   1009 			type *p64 = &fs->lfs_dlfs_u.u_64.dlfs_##field; \
   1010 			*p64 += val;				\
   1011 		} else {					\
   1012 			type32 *p32 = &fs->lfs_dlfs_u.u_32.dlfs_##field; \
   1013 			*p32 += val;				\
   1014 		}						\
   1015 	}							\
   1016 	static __unused inline void				\
   1017 	lfs_sb_sub##field(STRUCT_LFS *fs, type val)		\
   1018 	{							\
   1019 		if (fs->lfs_is64) {				\
   1020 			type *p64 = &fs->lfs_dlfs_u.u_64.dlfs_##field; \
   1021 			*p64 -= val;				\
   1022 		} else {					\
   1023 			type32 *p32 = &fs->lfs_dlfs_u.u_32.dlfs_##field; \
   1024 			*p32 -= val;				\
   1025 		}						\
   1026 	}
   1027 
   1028 #define LFS_DEF_SB_ACCESSOR(t, f) LFS_DEF_SB_ACCESSOR_FULL(t, t, f)
   1029 
   1030 #define LFS_DEF_SB_ACCESSOR_32ONLY(type, field, val64) \
   1031 	static __unused inline type				\
   1032 	lfs_sb_get##field(STRUCT_LFS *fs)			\
   1033 	{							\
   1034 		if (fs->lfs_is64) {				\
   1035 			return val64;				\
   1036 		} else {					\
   1037 			return fs->lfs_dlfs_u.u_32.dlfs_##field; \
   1038 		}						\
   1039 	}
   1040 
   1041 #define lfs_magic lfs_dlfs.dlfs_magic
   1042 LFS_DEF_SB_ACCESSOR(u_int32_t, version);
   1043 LFS_DEF_SB_ACCESSOR_FULL(u_int64_t, u_int32_t, size);
   1044 LFS_DEF_SB_ACCESSOR(u_int32_t, ssize);
   1045 LFS_DEF_SB_ACCESSOR_FULL(u_int64_t, u_int32_t, dsize);
   1046 LFS_DEF_SB_ACCESSOR(u_int32_t, bsize);
   1047 LFS_DEF_SB_ACCESSOR(u_int32_t, fsize);
   1048 LFS_DEF_SB_ACCESSOR(u_int32_t, frag);
   1049 LFS_DEF_SB_ACCESSOR_FULL(uint64_t, uint32_t, freehd);
   1050 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, bfree);
   1051 LFS_DEF_SB_ACCESSOR_FULL(uint64_t, uint32_t, nfiles);
   1052 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, avail);
   1053 LFS_DEF_SB_ACCESSOR(int32_t, uinodes);
   1054 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, idaddr);
   1055 LFS_DEF_SB_ACCESSOR_32ONLY(u_int32_t, ifile, LFS_IFILE_INUM);
   1056 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, lastseg);
   1057 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, nextseg);
   1058 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, curseg);
   1059 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, offset);
   1060 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, lastpseg);
   1061 LFS_DEF_SB_ACCESSOR(u_int32_t, inopf);
   1062 LFS_DEF_SB_ACCESSOR(u_int32_t, minfree);
   1063 LFS_DEF_SB_ACCESSOR(uint64_t, maxfilesize);
   1064 LFS_DEF_SB_ACCESSOR(u_int32_t, fsbpseg);
   1065 LFS_DEF_SB_ACCESSOR(u_int32_t, inopb);
   1066 LFS_DEF_SB_ACCESSOR(u_int32_t, ifpb);
   1067 LFS_DEF_SB_ACCESSOR(u_int32_t, sepb);
   1068 LFS_DEF_SB_ACCESSOR(u_int32_t, nindir);
   1069 LFS_DEF_SB_ACCESSOR(u_int32_t, nseg);
   1070 LFS_DEF_SB_ACCESSOR(u_int32_t, nspf);
   1071 LFS_DEF_SB_ACCESSOR(u_int32_t, cleansz);
   1072 LFS_DEF_SB_ACCESSOR(u_int32_t, segtabsz);
   1073 LFS_DEF_SB_ACCESSOR_32ONLY(u_int32_t, segmask, 0);
   1074 LFS_DEF_SB_ACCESSOR_32ONLY(u_int32_t, segshift, 0);
   1075 LFS_DEF_SB_ACCESSOR(u_int64_t, bmask);
   1076 LFS_DEF_SB_ACCESSOR(u_int32_t, bshift);
   1077 LFS_DEF_SB_ACCESSOR(u_int64_t, ffmask);
   1078 LFS_DEF_SB_ACCESSOR(u_int32_t, ffshift);
   1079 LFS_DEF_SB_ACCESSOR(u_int64_t, fbmask);
   1080 LFS_DEF_SB_ACCESSOR(u_int32_t, fbshift);
   1081 LFS_DEF_SB_ACCESSOR(u_int32_t, blktodb);
   1082 LFS_DEF_SB_ACCESSOR(u_int32_t, fsbtodb);
   1083 LFS_DEF_SB_ACCESSOR(u_int32_t, sushift);
   1084 LFS_DEF_SB_ACCESSOR(int32_t, maxsymlinklen);
   1085 LFS_DEF_SB_ACCESSOR(u_int32_t, cksum);
   1086 LFS_DEF_SB_ACCESSOR(u_int16_t, pflags);
   1087 LFS_DEF_SB_ACCESSOR(u_int32_t, nclean);
   1088 LFS_DEF_SB_ACCESSOR(int32_t, dmeta);
   1089 LFS_DEF_SB_ACCESSOR(u_int32_t, minfreeseg);
   1090 LFS_DEF_SB_ACCESSOR(u_int32_t, sumsize);
   1091 LFS_DEF_SB_ACCESSOR(u_int64_t, serial);
   1092 LFS_DEF_SB_ACCESSOR(u_int32_t, ibsize);
   1093 LFS_DEF_SB_ACCESSOR_FULL(int64_t, int32_t, s0addr);
   1094 LFS_DEF_SB_ACCESSOR(u_int64_t, tstamp);
   1095 LFS_DEF_SB_ACCESSOR(u_int32_t, inodefmt);
   1096 LFS_DEF_SB_ACCESSOR(u_int32_t, interleave);
   1097 LFS_DEF_SB_ACCESSOR(u_int32_t, ident);
   1098 LFS_DEF_SB_ACCESSOR(u_int32_t, resvseg);
   1099 
   1100 /* special-case accessors */
   1101 
   1102 /*
   1103  * the v1 otstamp field lives in what's now dlfs_inopf
   1104  */
   1105 #define lfs_sb_getotstamp(fs) lfs_sb_getinopf(fs)
   1106 #define lfs_sb_setotstamp(fs, val) lfs_sb_setinopf(fs, val)
   1107 
   1108 /*
   1109  * lfs_sboffs is an array
   1110  */
   1111 static __unused inline int32_t
   1112 lfs_sb_getsboff(STRUCT_LFS *fs, unsigned n)
   1113 {
   1114 #ifdef KASSERT /* ugh */
   1115 	KASSERT(n < LFS_MAXNUMSB);
   1116 #endif
   1117 	if (fs->lfs_is64) {
   1118 		return fs->lfs_dlfs_u.u_64.dlfs_sboffs[n];
   1119 	} else {
   1120 		return fs->lfs_dlfs_u.u_32.dlfs_sboffs[n];
   1121 	}
   1122 }
   1123 static __unused inline void
   1124 lfs_sb_setsboff(STRUCT_LFS *fs, unsigned n, int32_t val)
   1125 {
   1126 #ifdef KASSERT /* ugh */
   1127 	KASSERT(n < LFS_MAXNUMSB);
   1128 #endif
   1129 	if (fs->lfs_is64) {
   1130 		fs->lfs_dlfs_u.u_64.dlfs_sboffs[n] = val;
   1131 	} else {
   1132 		fs->lfs_dlfs_u.u_32.dlfs_sboffs[n] = val;
   1133 	}
   1134 }
   1135 
   1136 /*
   1137  * lfs_fsmnt is a string
   1138  */
   1139 static __unused inline const char *
   1140 lfs_sb_getfsmnt(STRUCT_LFS *fs)
   1141 {
   1142 	if (fs->lfs_is64) {
   1143 		return fs->lfs_dlfs_u.u_64.dlfs_fsmnt;
   1144 	} else {
   1145 		return fs->lfs_dlfs_u.u_32.dlfs_fsmnt;
   1146 	}
   1147 }
   1148 
   1149 static __unused inline void
   1150 lfs_sb_setfsmnt(STRUCT_LFS *fs, const char *str)
   1151 {
   1152 	if (fs->lfs_is64) {
   1153 		(void)strncpy(fs->lfs_dlfs_u.u_64.dlfs_fsmnt, str,
   1154 			sizeof(fs->lfs_dlfs_u.u_64.dlfs_fsmnt));
   1155 	} else {
   1156 		(void)strncpy(fs->lfs_dlfs_u.u_32.dlfs_fsmnt, str,
   1157 			sizeof(fs->lfs_dlfs_u.u_32.dlfs_fsmnt));
   1158 	}
   1159 }
   1160 
   1161 /* Highest addressable fsb */
   1162 #define LFS_MAX_DADDR(fs) \
   1163 	((fs)->lfs_is64 ? 0x7fffffffffffffff : 0x7fffffff)
   1164 
   1165 /* LFS_NINDIR is the number of indirects in a file system block. */
   1166 #define	LFS_NINDIR(fs)	(lfs_sb_getnindir(fs))
   1167 
   1168 /* LFS_INOPB is the number of inodes in a secondary storage block. */
   1169 #define	LFS_INOPB(fs)	(lfs_sb_getinopb(fs))
   1170 /* LFS_INOPF is the number of inodes in a fragment. */
   1171 #define LFS_INOPF(fs)	(lfs_sb_getinopf(fs))
   1172 
   1173 #define	lfs_blkoff(fs, loc)	((int)((loc) & lfs_sb_getbmask(fs)))
   1174 #define lfs_fragoff(fs, loc)    /* calculates (loc % fs->lfs_fsize) */ \
   1175     ((int)((loc) & lfs_sb_getffmask(fs)))
   1176 
   1177 /* XXX: lowercase these as they're no longer macros */
   1178 /* Frags to diskblocks */
   1179 static __unused inline uint64_t
   1180 LFS_FSBTODB(STRUCT_LFS *fs, uint64_t b)
   1181 {
   1182 #if defined(_KERNEL)
   1183 	return b << (lfs_sb_getffshift(fs) - DEV_BSHIFT);
   1184 #else
   1185 	return b << lfs_sb_getfsbtodb(fs);
   1186 #endif
   1187 }
   1188 /* Diskblocks to frags */
   1189 static __unused inline uint64_t
   1190 LFS_DBTOFSB(STRUCT_LFS *fs, uint64_t b)
   1191 {
   1192 #if defined(_KERNEL)
   1193 	return b >> (lfs_sb_getffshift(fs) - DEV_BSHIFT);
   1194 #else
   1195 	return b >> lfs_sb_getfsbtodb(fs);
   1196 #endif
   1197 }
   1198 
   1199 #define	lfs_lblkno(fs, loc)	((loc) >> lfs_sb_getbshift(fs))
   1200 #define	lfs_lblktosize(fs, blk)	((blk) << lfs_sb_getbshift(fs))
   1201 
   1202 /* Frags to bytes */
   1203 static __unused inline uint64_t
   1204 lfs_fsbtob(STRUCT_LFS *fs, uint64_t b)
   1205 {
   1206 	return b << lfs_sb_getffshift(fs);
   1207 }
   1208 /* Bytes to frags */
   1209 static __unused inline uint64_t
   1210 lfs_btofsb(STRUCT_LFS *fs, uint64_t b)
   1211 {
   1212 	return b >> lfs_sb_getffshift(fs);
   1213 }
   1214 
   1215 #define lfs_numfrags(fs, loc)	/* calculates (loc / fs->lfs_fsize) */	\
   1216 	((loc) >> lfs_sb_getffshift(fs))
   1217 #define lfs_blkroundup(fs, size)/* calculates roundup(size, lfs_sb_getbsize(fs)) */ \
   1218 	((off_t)(((size) + lfs_sb_getbmask(fs)) & (~lfs_sb_getbmask(fs))))
   1219 #define lfs_fragroundup(fs, size)/* calculates roundup(size, fs->lfs_fsize) */ \
   1220 	((off_t)(((size) + lfs_sb_getffmask(fs)) & (~lfs_sb_getffmask(fs))))
   1221 #define lfs_fragstoblks(fs, frags)/* calculates (frags / fs->fs_frag) */ \
   1222 	((frags) >> lfs_sb_getfbshift(fs))
   1223 #define lfs_blkstofrags(fs, blks)/* calculates (blks * fs->fs_frag) */ \
   1224 	((blks) << lfs_sb_getfbshift(fs))
   1225 #define lfs_fragnum(fs, fsb)	/* calculates (fsb % fs->lfs_frag) */	\
   1226 	((fsb) & ((fs)->lfs_frag - 1))
   1227 #define lfs_blknum(fs, fsb)	/* calculates rounddown(fsb, fs->lfs_frag) */ \
   1228 	((fsb) &~ ((fs)->lfs_frag - 1))
   1229 #define lfs_dblksize(fs, dp, lbn) \
   1230 	(((lbn) >= ULFS_NDADDR || lfs_dino_getsize(fs, dp) >= ((lbn) + 1) << lfs_sb_getbshift(fs)) \
   1231 	    ? lfs_sb_getbsize(fs) \
   1232 	    : (lfs_fragroundup(fs, lfs_blkoff(fs, lfs_dino_getsize(fs, dp)))))
   1233 
   1234 #define	lfs_segsize(fs)	(lfs_sb_getversion(fs) == 1 ?	     		\
   1235 			   lfs_lblktosize((fs), lfs_sb_getssize(fs)) :	\
   1236 			   lfs_sb_getssize(fs))
   1237 /* XXX segtod produces a result in frags despite the 'd' */
   1238 #define lfs_segtod(fs, seg) (lfs_btofsb(fs, lfs_segsize(fs)) * (seg))
   1239 #define	lfs_dtosn(fs, daddr)	/* block address to segment number */	\
   1240 	((uint32_t)(((daddr) - lfs_sb_gets0addr(fs)) / lfs_segtod((fs), 1)))
   1241 #define lfs_sntod(fs, sn)	/* segment number to disk address */	\
   1242 	((daddr_t)(lfs_segtod((fs), (sn)) + lfs_sb_gets0addr(fs)))
   1243 
   1244 /* XXX, blah. make this appear only if struct inode is defined */
   1245 #ifdef _UFS_LFS_LFS_INODE_H_
   1246 static __unused inline uint32_t
   1247 lfs_blksize(STRUCT_LFS *fs, struct inode *ip, uint64_t lbn)
   1248 {
   1249 	if (lbn >= ULFS_NDADDR || lfs_dino_getsize(fs, ip->i_din) >= (lbn + 1) << lfs_sb_getbshift(fs)) {
   1250 		return lfs_sb_getbsize(fs);
   1251 	} else {
   1252 		return lfs_fragroundup(fs, lfs_blkoff(fs, lfs_dino_getsize(fs, ip->i_din)));
   1253 	}
   1254 }
   1255 #endif
   1256 
   1257 /*
   1258  * union lfs_blocks
   1259  */
   1260 
   1261 static __unused inline void
   1262 lfs_blocks_fromvoid(STRUCT_LFS *fs, union lfs_blocks *bp, void *p)
   1263 {
   1264 	if (fs->lfs_is64) {
   1265 		bp->b64 = p;
   1266 	} else {
   1267 		bp->b32 = p;
   1268 	}
   1269 }
   1270 
   1271 static __unused inline void
   1272 lfs_blocks_fromfinfo(STRUCT_LFS *fs, union lfs_blocks *bp, FINFO *fip)
   1273 {
   1274 	void *firstblock;
   1275 
   1276 	firstblock = (char *)fip + FINFOSIZE(fs);
   1277 	if (fs->lfs_is64) {
   1278 		bp->b64 = (int64_t *)firstblock;
   1279 	}  else {
   1280 		bp->b32 = (int32_t *)firstblock;
   1281 	}
   1282 }
   1283 
   1284 static __unused inline daddr_t
   1285 lfs_blocks_get(STRUCT_LFS *fs, union lfs_blocks *bp, unsigned index)
   1286 {
   1287 	if (fs->lfs_is64) {
   1288 		return bp->b64[index];
   1289 	} else {
   1290 		return bp->b32[index];
   1291 	}
   1292 }
   1293 
   1294 static __unused inline void
   1295 lfs_blocks_set(STRUCT_LFS *fs, union lfs_blocks *bp, unsigned index, daddr_t val)
   1296 {
   1297 	if (fs->lfs_is64) {
   1298 		bp->b64[index] = val;
   1299 	} else {
   1300 		bp->b32[index] = val;
   1301 	}
   1302 }
   1303 
   1304 static __unused inline void
   1305 lfs_blocks_inc(STRUCT_LFS *fs, union lfs_blocks *bp)
   1306 {
   1307 	if (fs->lfs_is64) {
   1308 		bp->b64++;
   1309 	} else {
   1310 		bp->b32++;
   1311 	}
   1312 }
   1313 
   1314 static __unused inline int
   1315 lfs_blocks_eq(STRUCT_LFS *fs, union lfs_blocks *bp1, union lfs_blocks *bp2)
   1316 {
   1317 	if (fs->lfs_is64) {
   1318 		return bp1->b64 == bp2->b64;
   1319 	} else {
   1320 		return bp1->b32 == bp2->b32;
   1321 	}
   1322 }
   1323 
   1324 static __unused inline int
   1325 lfs_blocks_sub(STRUCT_LFS *fs, union lfs_blocks *bp1, union lfs_blocks *bp2)
   1326 {
   1327 	/* (remember that the pointers are typed) */
   1328 	if (fs->lfs_is64) {
   1329 		return bp1->b64 - bp2->b64;
   1330 	} else {
   1331 		return bp1->b32 - bp2->b32;
   1332 	}
   1333 }
   1334 
   1335 /*
   1336  * struct segment
   1337  */
   1338 
   1339 
   1340 /*
   1341  * Macros for determining free space on the disk, with the variable metadata
   1342  * of segment summaries and inode blocks taken into account.
   1343  */
   1344 /*
   1345  * Estimate number of clean blocks not available for writing because
   1346  * they will contain metadata or overhead.  This is calculated as
   1347  *
   1348  *		E = ((C * M / D) * D + (0) * (T - D)) / T
   1349  * or more simply
   1350  *		E = (C * M) / T
   1351  *
   1352  * where
   1353  * C is the clean space,
   1354  * D is the dirty space,
   1355  * M is the dirty metadata, and
   1356  * T = C + D is the total space on disk.
   1357  *
   1358  * This approximates the old formula of E = C * M / D when D is close to T,
   1359  * but avoids falsely reporting "disk full" when the sample size (D) is small.
   1360  */
   1361 #define LFS_EST_CMETA(F) (int32_t)((					\
   1362 	(lfs_sb_getdmeta(F) * (int64_t)lfs_sb_getnclean(F)) / 		\
   1363 	(lfs_sb_getnseg(F))))
   1364 
   1365 /* Estimate total size of the disk not including metadata */
   1366 #define LFS_EST_NONMETA(F) (lfs_sb_getdsize(F) - lfs_sb_getdmeta(F) - LFS_EST_CMETA(F))
   1367 
   1368 /* Estimate number of blocks actually available for writing */
   1369 #define LFS_EST_BFREE(F) (lfs_sb_getbfree(F) > LFS_EST_CMETA(F) ?	     \
   1370 			  lfs_sb_getbfree(F) - LFS_EST_CMETA(F) : 0)
   1371 
   1372 /* Amount of non-meta space not available to mortal man */
   1373 #define LFS_EST_RSVD(F) (int32_t)((LFS_EST_NONMETA(F) *			     \
   1374 				   (u_int64_t)lfs_sb_getminfree(F)) /	     \
   1375 				  100)
   1376 
   1377 /* Can credential C write BB blocks? XXX: kauth_cred_geteuid is abusive */
   1378 #define ISSPACE(F, BB, C)						\
   1379 	((((C) == NOCRED || kauth_cred_geteuid(C) == 0) &&		\
   1380 	  LFS_EST_BFREE(F) >= (BB)) ||					\
   1381 	 (kauth_cred_geteuid(C) != 0 && IS_FREESPACE(F, BB)))
   1382 
   1383 /* Can an ordinary user write BB blocks */
   1384 #define IS_FREESPACE(F, BB)						\
   1385 	  (LFS_EST_BFREE(F) >= (BB) + LFS_EST_RSVD(F))
   1386 
   1387 /*
   1388  * The minimum number of blocks to create a new inode.  This is:
   1389  * directory direct block (1) + ULFS_NIADDR indirect blocks + inode block (1) +
   1390  * ifile direct block (1) + ULFS_NIADDR indirect blocks = 3 + 2 * ULFS_NIADDR blocks.
   1391  */
   1392 #define LFS_NRESERVE(F) (lfs_btofsb((F), (2 * ULFS_NIADDR + 3) << lfs_sb_getbshift(F)))
   1393 
   1394 
   1395 
   1396 #endif /* _UFS_LFS_LFS_ACCESSORS_H_ */
   1397