/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef INOMAP_H
#define INOMAP_H
/* inomap.[hc] - inode map abstraction
*
* an inode map describes the inode numbers (inos) in a file system dump.
* the map identifies which inos are in-use by the fs, which of those are
* directories, and which are dumped.
*
* the map is represented as a list of map segments. a map segment is
* a 64-bit starting ino and two 64-bit bitmaps. the bitmaps describe
* the 64 inos beginning with the starting ino. two bits are available
* for each ino.
*/
/* inomap_build - this function allocates and constructs an in-memory
* representation of the bitmap. it prunes from the map inos of files not
* changed since the last dump, inos not identified by the subtree list,
* and directories not needed to represent a hierarchy containing
* changed inodes. it handles hard links; a file linked to multiple
* directory entries will not be pruned if at least one of those
* directories has an ancestor in the subtree list.
*
* it returns by reference an array of startpoints in the non-directory
* portion of the dump, as well as the count of dir and nondir inos
* makred as present and to be dumped. A startpoint identifies a non-dir ino,
* and a non-hole accumulated size position within that file. only very large
* files will contain a startpoint; in all other cases the startpoints will
* fall at file boundaries. returns BOOL_FALSE if error encountered (should
* abort the dump; else returns BOOL_TRUE.
*/
extern bool_t inomap_build( jdm_fshandle_t *fshandlep,
intgen_t fsfd,
xfs_bstat_t *rootstatp,
bool_t last,
time32_t lasttime,
bool_t resume,
time32_t resumetime,
size_t resumerangecnt,
drange_t *resumerangep,
char *subtreebuf[],
ix_t subtreecnt,
startpt_t startptp[],
size_t startptcnt,
ix_t *statphasep,
ix_t *statpassp,
size64_t statcnt,
size64_t *statdonep );
#ifdef SIZEEST
extern u_int64_t inomap_getsz( void );
#endif /* SIZEEST */
/* inomap_skip - tell inomap about inodes to skip in the dump
*/
extern void inomap_skip( xfs_ino_t ino );
/* inomap_writehdr - updates the write header with inomap-private info
* to be communicated to the restore side
*/
extern void inomap_writehdr( content_inode_hdr_t *scwhdrp );
/* inomap_dump - dumps the map to media - content-abstraction-knowledgable
*
* returns error from media write op
*/
extern rv_t inomap_dump( drive_t *drivep );
/* map state values
*/
#define MAP_INO_UNUSED 0 /* ino not in use by fs */
#define MAP_DIR_NOCHNG 1 /* dir, ino in use by fs, but not dumped */
#define MAP_NDR_NOCHNG 2 /* non-dir, ino in use by fs, but not dumped */
#define MAP_DIR_CHANGE 3 /* dir, changed since last dump */
#define MAP_NDR_CHANGE 4 /* non-dir, changed since last dump */
#define MAP_DIR_SUPPRT 5 /* dir, unchanged but needed for hierarchy */
#define MAP_RESERVED1 6 /* this state currently not used */
#define MAP_RESERVED2 7 /* this state currently not used */
/* map context and operators
*/
/* the inomap is implimented as a linked list of chunks. each chunk contains
* an array of map segments. a map segment contains a start ino and a
* bitmap of 64 3-bit state values (see MAP_... in inomap.h). the SEG_macros
* index and manipulate the 3-bit state values.
*/
struct seg {
xfs_ino_t base;
u_int64_t lobits;
u_int64_t mebits;
u_int64_t hibits;
};
typedef struct seg seg_t;
#define SEG_SET_BASE( segp, ino ) \
{ \
segp->base = ino; \
}
#ifdef OLDCODE
#define SEG_ADD_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
relino = ino - segp->base; \
segp->lobits |= ( u_int64_t )( ( state >> 0 ) & 1 ) << relino; \
segp->mebits |= ( u_int64_t )( ( state >> 1 ) & 1 ) << relino; \
segp->hibits |= ( u_int64_t )( ( state >> 2 ) & 1 ) << relino; \
}
#define SEG_SET_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
register u_int64_t clrmask; \
relino = ino - segp->base; \
clrmask = ~( ( u_int64_t )1 << relino ); \
segp->lobits &= clrmask; \
segp->mebits &= clrmask; \
segp->hibits &= clrmask; \
segp->lobits |= ( u_int64_t )( ( state >> 0 ) & 1 ) << relino; \
segp->mebits |= ( u_int64_t )( ( state >> 1 ) & 1 ) << relino; \
segp->hibits |= ( u_int64_t )( ( state >> 2 ) & 1 ) << relino; \
}
#define SEG_GET_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
relino = ino - segp->base; \
state = 0; \
state |= ( intgen_t )((( segp->lobits >> relino ) & 1 ) * 1 );\
state |= ( intgen_t )((( segp->mebits >> relino ) & 1 ) * 2 );\
state |= ( intgen_t )((( segp->hibits >> relino ) & 1 ) * 4 );\
}
#else /* OLDCODE */
/*
* The converse on MACROBITS are the functions defined in inomap.c
*/
#ifdef MACROBITS
#define SEG_ADD_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
register u_int64_t mask; \
relino = ino - segp->base; \
mask = ( u_int64_t )1 << relino; \
switch( state ) { \
case 0: \
break; \
case 1: \
segp->lobits |= mask; \
break; \
case 2: \
segp->mebits |= mask; \
break; \
case 3: \
segp->lobits |= mask; \
segp->mebits |= mask; \
break; \
case 4: \
segp->hibits |= mask; \
break; \
case 5: \
segp->lobits |= mask; \
segp->hibits |= mask; \
break; \
case 6: \
segp->mebits |= mask; \
segp->hibits |= mask; \
break; \
case 7: \
segp->lobits |= mask; \
segp->mebits |= mask; \
segp->hibits |= mask; \
break; \
} \
}
#define SEG_SET_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
register u_int64_t mask; \
register u_int64_t clrmask; \
relino = ino - segp->base; \
mask = ( u_int64_t )1 << relino; \
clrmask = ~mask; \
switch( state ) { \
case 0: \
segp->lobits &= clrmask; \
segp->mebits &= clrmask; \
segp->hibits &= clrmask; \
break; \
case 1: \
segp->lobits |= mask; \
segp->mebits &= clrmask; \
segp->hibits &= clrmask; \
break; \
case 2: \
segp->lobits &= clrmask; \
segp->mebits |= mask; \
segp->hibits &= clrmask; \
break; \
case 3: \
segp->lobits |= mask; \
segp->mebits |= mask; \
segp->hibits &= clrmask; \
break; \
case 4: \
segp->lobits &= clrmask; \
segp->mebits &= clrmask; \
segp->hibits |= mask; \
break; \
case 5: \
segp->lobits |= mask; \
segp->mebits &= clrmask; \
segp->hibits |= mask; \
break; \
case 6: \
segp->lobits &= clrmask; \
segp->mebits |= mask; \
segp->hibits |= mask; \
break; \
case 7: \
segp->lobits |= mask; \
segp->mebits |= mask; \
segp->hibits |= mask; \
break; \
} \
}
#define SEG_GET_BITS( segp, ino, state ) \
{ \
register xfs_ino_t relino; \
register u_int64_t mask; \
relino = ino - segp->base; \
mask = ( u_int64_t )1 << relino; \
if ( segp->lobits & mask ) { \
state = 1; \
} else { \
state = 0; \
} \
if ( segp->mebits & mask ) { \
state |= 2; \
} \
if ( segp->hibits & mask ) { \
state |= 4; \
} \
}
#endif /* MACROBITS */
#endif /* OLDCODE */
#define INOPERSEG ( sizeof( (( seg_t * )0 )->lobits ) * NBBY )
#define HNKSZ ( 4 * PGSZ )
#define SEGPERHNK ( ( HNKSZ / sizeof( seg_t )) - 1 )
struct hnk {
seg_t seg[ SEGPERHNK ];
xfs_ino_t maxino;
struct hnk *nextp;
char pad[sizeof( seg_t ) - sizeof( xfs_ino_t ) - sizeof( struct hnk * )];
};
typedef struct hnk hnk_t;
/* inomap_state - returns the map state of the given ino.
* highly optimized for monotonically increasing arguments to
* successive calls. requires a pointer to a context block, obtained from
* inomap_state_getcontext(), and released by inomap_state_freecontext().
*/
extern void *inomap_state_getcontext( void );
extern intgen_t inomap_state( void *contextp, xfs_ino_t ino );
extern void inomap_state_freecontext( void *contextp );
void inomap_state_postaccum( void *p );
#ifdef NOTUSED
/* inomap_iter_cb - will call the supplied function for each ino in
* the map matching a state in the state mask. if the callback returns
* FALSE, the iteration will be aborted and inomap_iter_cb() will
* return FALSE. the state mask is constructed by OR'ing bits in bit
* positions corresponding to the state values.
*/
extern bool_t inomap_iter_cb( void *contextp,
intgen_t statemask,
bool_t ( *funcp )( void *contextp,
xfs_ino_t ino,
intgen_t state ));
#endif /* NOTUSED */
#endif /* INOMAP_H */