File: [Development] / xfs-cmds / xfsdump / dump / inomap.h (download)
Revision 1.7, Tue Jan 31 15:47:31 2006 UTC (11 years, 8 months ago) by wkendall
Branch: MAIN
Changes since 1.6: +3 -0
lines
This mod adds a number of optimizations to increase the
performance of xfsdump and xfsrestore, especially on filesystems
with millions of inodes. Many small changes were made to
minimize the number of system calls required per inode.
Significant changes to xfsdump:
- Cache the gen number of each inode during the initial inode
scan so that a bulkstat single does not need to be done for
each inode when dumping directories.
- No longer retrieve the DMF attribute when estimating the dump
size of a file. Use information from the bulkstat instead.
- Retrieve DMF attribute by handle instead of doing
open/attr_getf/close.
- In determining where to split multi-stream dumps, take into
consideration the number of files and not just the file size.
This allows filesystems with large amounts of inodes but
relatively little data (DMF filesystem) to be split correctly.
Significant changes to xfsrestore:
- Buffer writes to the namreg file to eliminate 2 very small
write system calls per directory entry.
- Buffer writes to dirattr file to eliminate a small write system
call per directory.
- Speedup the check to see if a particular window of the tree
file is mapped. This allows xfsrestore to use more, smaller
windows which is beneficial if we can't fit them all in memory
and have to start unmapping them. This also makes the -w
option obsolete so that option now has no effect.
- Change the hash function to give a better distribution among
the hash buckets.
- Do not make an unnecessary unlink call if the file being
restored does not already exist.
|
/*
* 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 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#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 );
/* lookup a gen number for a given ino. */
extern gen_t i2g(xfs_ino_t ino);
#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 */