160 lines
5.7 KiB
C
160 lines
5.7 KiB
C
/*
|
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2013
|
|
* The President and Fellows of Harvard College.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef IBMACROS_H
|
|
#define IBMACROS_H
|
|
|
|
/*
|
|
* Indirect block access macros
|
|
*
|
|
* These are macros for working with the direct and indirect block
|
|
* pointers in the inode. The scheme here supports a range of possible
|
|
* configurations, because sometimes adding large file support to SFS
|
|
* is part of an assignment; there is and should be no obligation to
|
|
* pick any particular layout, and we'd like sfsck to build and run
|
|
* seamlessly provided that the values declared in kern/sfs.h are
|
|
* correct.
|
|
*
|
|
* SFS_NDIRECT, SFS_NINDIRECT, SFS_NDINDIRECT, and SFS_NTINDIRECT
|
|
* should always be defined. If zero, no corresponding field is
|
|
* assumed to exist in the inode. If one, the field is assumed to
|
|
* be a single value and not an array. If greater than one, the
|
|
* field is assumed to be an array.
|
|
*/
|
|
|
|
#ifndef SFS_NDIRECT
|
|
#error "SFS_NDIRECT not defined"
|
|
#endif
|
|
#ifndef SFS_NINDIRECT
|
|
#error "SFS_NINDIRECT not defined"
|
|
#endif
|
|
#ifndef SFS_NDINDIRECT
|
|
#error "SFS_NDINDIRECT not defined"
|
|
#endif
|
|
#ifndef SFS_NTINDIRECT
|
|
#error "SFS_NTINDIRECT not defined"
|
|
#endif
|
|
|
|
/*
|
|
* For x in D, I, II, III (direct, indirect, 2x/3x indirect) we
|
|
* provide:
|
|
*
|
|
* NUM_x the number of blocks of this type
|
|
* GET_x retrieve the i'th block of this type
|
|
* SET_x lvalue for the i'th block of this type
|
|
* RANGE_x size of the block range mapped with one block of this type
|
|
* INOMAX_x maximum block number mapped by using this type in the inode
|
|
*
|
|
* It is important that the accessor macros (SET_x/GET_x) not refer to
|
|
* a nonexistent field of the inode in the case where there are zero
|
|
* blocks of that type, as that will lead to compile failure. Hence the
|
|
* lengthy definitions. So far I haven't thought any useful cpp hackery
|
|
* to make them more concise.
|
|
*/
|
|
|
|
/* numbers */
|
|
|
|
#define NUM_D SFS_NDIRECT
|
|
#define NUM_I SFS_NINDIRECT
|
|
#define NUM_II SFS_NDINDIRECT
|
|
#define NUM_III SFS_NTINDIRECT
|
|
|
|
/* blocks */
|
|
|
|
#if NUM_D == 0
|
|
#define GET_D(sfi, i) GET0_x(sfi, sfi_direct, i)
|
|
#define SET_D(sfi, i) SET0_x(sfi, sfi_direct, i)
|
|
#elif NUM_D == 1
|
|
#define GET_D(sfi, i) GET1_x(sfi, sfi_direct, i)
|
|
#define SET_D(sfi, i) SET1_x(sfi, sfi_direct, i)
|
|
#else
|
|
#define GET_D(sfi, i) GETN_x(sfi, sfi_direct, i)
|
|
#define SET_D(sfi, i) SETN_x(sfi, sfi_direct, i)
|
|
#endif
|
|
|
|
#if NUM_I == 0
|
|
#define GET_I(sfi, i) GET0_x(sfi, sfi_indirect, i)
|
|
#define SET_I(sfi, i) SET0_x(sfi, sfi_indirect, i)
|
|
#elif NUM_I == 1
|
|
#define GET_I(sfi, i) GET1_x(sfi, sfi_indirect, i)
|
|
#define SET_I(sfi, i) SET1_x(sfi, sfi_indirect, i)
|
|
#else
|
|
#define GET_I(sfi, i) GETN_x(sfi, sfi_indirect, i)
|
|
#define SET_I(sfi, i) SETN_x(sfi, sfi_indirect, i)
|
|
#endif
|
|
|
|
#if NUM_II == 0
|
|
#define GET_II(sfi, i) GET0_x(sfi, sfi_dindirect, i)
|
|
#define SET_II(sfi, i) SET0_x(sfi, sfi_dindirect, i)
|
|
#elif NUM_II == 1
|
|
#define GET_II(sfi, i) GET1_x(sfi, sfi_dindirect, i)
|
|
#define SET_II(sfi, i) SET1_x(sfi, sfi_dindirect, i)
|
|
#else
|
|
#define GET_II(sfi, i) GETN_x(sfi, sfi_dindirect, i)
|
|
#define SET_II(sfi, i) SETN_x(sfi, sfi_dindirect, i)
|
|
#endif
|
|
|
|
#if NUM_III == 0
|
|
#define GET_III(sfi, i) GET0_x(sfi, sfi_tindirect, i)
|
|
#define SET_III(sfi, i) SET0_x(sfi, sfi_tindirect, i)
|
|
#elif NUM_III == 1
|
|
#define GET_III(sfi, i) GET1_x(sfi, sfi_tindirect, i)
|
|
#define SET_III(sfi, i) SET1_x(sfi, sfi_tindirect, i)
|
|
#else
|
|
#define GET_III(sfi, i) GETN_x(sfi, sfi_tindirect, i)
|
|
#define SET_III(sfi, i) SETN_x(sfi, sfi_tindirect, i)
|
|
#endif
|
|
|
|
/* the generic forms of the block macros */
|
|
|
|
#define GET0_x(sfi, field, i) ((void)(i), (void)(sfi), 0)
|
|
#define GET1_x(sfi, field, i) ((void)(i), (sfi)->field)
|
|
#define GETN_x(sfi, field, i) ((sfi)->field[(i)])
|
|
|
|
#define SET0_x(sfi, field, i) (*((void)(i), (void)(sfi), (uint32_t *)NULL))
|
|
#define SET1_x(sfi, field, i) (*((void)(i), &(sfi)->field))
|
|
#define SETN_x(sfi, field, i) ((sfi)->field[(i)])
|
|
|
|
/* region sizes */
|
|
|
|
#define RANGE_D 1
|
|
#define RANGE_I (RANGE_D * SFS_DBPERIDB)
|
|
#define RANGE_II (RANGE_I * SFS_DBPERIDB)
|
|
#define RANGE_III (RANGE_II * SFS_DBPERIDB)
|
|
|
|
/* max blocks */
|
|
|
|
#define INOMAX_D NUM_D
|
|
#define INOMAX_I (INOMAX_D + SFS_DBPERIDB * NUM_I)
|
|
#define INOMAX_II (INOMAX_I + SFS_DBPERIDB * NUM_II)
|
|
#define INOMAX_III (INOMAX_II + SFS_DBPERIDB * NUM_III)
|
|
|
|
|
|
#endif /* IBMACROS_H */
|