Ejemplo n.º 1
0
static xfs_ino_t
inomap_iter( void *contextp, intgen_t statemask )
{
	xfs_ino_t ino, endino;
	seg_t *segp;
	seg_addr_t *addrp = (seg_addr_t *)contextp;

	for ( ;
	      addrp->hnkoff <= inomap.lastseg.hnkoff;
	      addrp->hnkoff++, addrp->segoff = 0, addrp->inooff = 0 ) {

		for ( ;
		      addrp->segoff <= inomap_lastseg(addrp->hnkoff);
		      addrp->segoff++, addrp->inooff = 0 ) {

			segp = inomap_addr2seg( addrp );

			ino = segp->base + addrp->inooff;
			endino = segp->base + INOPERSEG;
			for ( ; ino < endino ; ino++, addrp->inooff++ ) {
				intgen_t st;
				st = SEG_GET_BITS( segp, ino );
				if ( statemask & ( 1 << st )) {
					addrp->inooff++; /* for next call */
					return ino;
				}
			}
		}
	}

	return INO64MAX;
}
Ejemplo n.º 2
0
static void
inomap_set_gen(void *contextp, xfs_ino_t ino, gen_t gen)
{
	seg_addr_t *addrp;
	seg_addr_t addr;
	seg_t *segp;
	i2gseg_t *i2gsegp;
	xfs_ino_t relino;

	addrp = contextp ? (seg_addr_t *)contextp : &addr;
	if ( !inomap_find_seg( addrp, ino ) )
		return;

	segp = inomap_addr2seg( addrp );
	i2gsegp = &inomap.i2gmap[inomap_addr2segix( addrp )];

	relino = ino - segp->base;
	i2gsegp->s_valid |= (u_int64_t)1 << relino;
	i2gsegp->s_lower[ relino ] = ( u_char_t )( gen & 0xff );
	if ( relino & 1 ) {
		/* odd, goes in high nibble */
		i2gsegp->s_upper[relino / 2] &= ( u_char_t )( 0x0f );
		i2gsegp->s_upper[relino / 2] |=
			( u_char_t )( ( gen >> 4 ) & 0xf0 );
	} else {
Ejemplo n.º 3
0
/* use binary search to find the hunk containing the given
 * inode, and then binary search the hunk to find the correct
 * segment, if any. use the supplied addr as the starting
 * point for the search.
 */
static bool_t
inomap_find_seg( seg_addr_t *addrp, xfs_ino_t ino )
{
	seg_t *segp;
	intgen_t lower;
	intgen_t upper;

	if ( !inomap_validaddr( addrp ) ) {
		inomap_reset_context( addrp );
	}

	if ( !inomap_find_hnk( addrp, ino ) )
		return BOOL_FALSE;

	/* find the correct segment */
	lower = 0;
	upper = inomap_lastseg(addrp->hnkoff);

	while ( upper >= lower ) {
		segp = inomap_addr2seg( addrp );

		if ( segp->base > ino ) {
			upper = addrp->segoff - 1;
		} else if ( segp->base + INOPERSEG <= ino ) {
			lower = addrp->segoff + 1;
		} else {
			return BOOL_TRUE;
		}

		addrp->segoff = lower + ((upper - lower) / 2);
	}

	return BOOL_FALSE;
}
Ejemplo n.º 4
0
intgen_t
inomap_get_state( void *contextp, xfs_ino_t ino )
{
	seg_addr_t *addrp;
	seg_addr_t addr;
	seg_t *segp;

	addrp = contextp ? (seg_addr_t *)contextp : &addr;
	if ( !inomap_find_seg( addrp, ino ) )
		return MAP_INO_UNUSED;

	segp = inomap_addr2seg( addrp );

	return SEG_GET_BITS( segp, ino );
}
Ejemplo n.º 5
0
/* called for every inode group in the filesystem in increasing inode
 * order. adds a new segment to the inomap and ino-to-gen map.
 */
static intgen_t
cb_add_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp )
{
	hnk_t *hunk;
	seg_t *segp;
	seg_addr_t *lastsegp = &inomap.lastseg;

	/* if out of segments on the current hnk or this is the first segment */
	lastsegp->segoff++;
	if (lastsegp->segoff == SEGPERHNK || lastsegp->segoff == 0) {
		lastsegp->hnkoff++;
		lastsegp->segoff = 0;

		if (lastsegp->hnkoff == inomap.hnkmaplen) {
			intgen_t numsegs;
			intgen_t oldsize;

			inomap.hnkmaplen++;
			inomap.hnkmap = (hnk_t *)
				realloc(inomap.hnkmap, inomap.hnkmaplen * HNKSZ);

			numsegs = inomap.hnkmaplen * SEGPERHNK;
			inomap.i2gmap = (i2gseg_t *)
				realloc(inomap.i2gmap, numsegs * sizeof(i2gseg_t));

			if (!inomap.hnkmap || !inomap.i2gmap)
				return -1;

			/* zero the new portion of the i2gmap */
			oldsize = (numsegs - SEGPERHNK) * sizeof(i2gseg_t);

			memset(inomap.i2gmap + oldsize,
			       0,
			       SEGPERHNK * sizeof(i2gseg_t));
		}

		memset(inomap_addr2hnk( lastsegp ), 0, HNKSZ);
	}

	hunk = inomap_addr2hnk( lastsegp );
	hunk->maxino = inogrp->xi_startino + INOPERSEG - 1;

	segp = inomap_addr2seg( lastsegp );
	segp->base = inogrp->xi_startino;

	return 0;
}
Ejemplo n.º 6
0
static intgen_t
inomap_set_state( void *contextp, xfs_ino_t ino, intgen_t state )
{
	intgen_t oldstate;
	seg_addr_t *addrp;
	seg_addr_t addr;
	seg_t *segp;

	addrp = contextp ? (seg_addr_t *)contextp : &addr;
	if ( !inomap_find_seg( addrp, ino ) )
		return MAP_INO_UNUSED;

	segp = inomap_addr2seg( addrp );

	oldstate = SEG_GET_BITS( segp, ino );
	SEG_SET_BITS( segp, ino, state );

	return oldstate;
}
Ejemplo n.º 7
0
static void
inomap_set_gen(void *contextp, xfs_ino_t ino, gen_t gen)
{
	seg_addr_t *addrp;
	seg_addr_t addr;
	seg_t *segp;
	i2gseg_t *i2gsegp;
	xfs_ino_t relino;

	addrp = contextp ? (seg_addr_t *)contextp : &addr;
	if ( !inomap_find_seg( addrp, ino ) )
		return;

	segp = inomap_addr2seg( addrp );
	i2gsegp = &inomap.i2gmap[inomap_addr2segix( addrp )];

	relino = ino - segp->base;
	i2gsegp->s_valid |= (u_int64_t)1 << relino;
	i2gsegp->s_gen[relino] = gen;
}