Exemple #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;
}
Exemple #2
0
/* map_getset - locates and gets the state of the specified ino,
 * and optionally sets the state to a new value.
 */
static intgen_t
map_getset( xfs_ino_t ino, intgen_t newstate, bool_t setflag )
{
	hnk_t *hnkp;
	seg_t *segp;

	if ( ino > last_ino_added ) {
		return MAP_INO_UNUSED;
	}
	for ( hnkp = roothnkp ; hnkp != 0 ; hnkp = hnkp->nextp ) {
		if ( ino > hnkp->maxino ) {
			continue;
		}
		for ( segp = hnkp->seg; segp < hnkp->seg + SEGPERHNK ; segp++ ){
			if ( hnkp == tailhnkp && segp > lastsegp ) {
				return MAP_INO_UNUSED;
			}
			if ( ino < segp->base ) {
				return MAP_INO_UNUSED;
			}
			if ( ino < segp->base + INOPERSEG ) {
				intgen_t state;
				SEG_GET_BITS( segp, ino, state );
				if ( setflag ) {
					SEG_SET_BITS( segp, ino, newstate );
				}
				return state;
			}
		}
		return MAP_INO_UNUSED;
	}
	return MAP_INO_UNUSED;
}
Exemple #3
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 );
}
Exemple #4
0
/* calls the callback for all inos with an inomap state included
 * in the state mask. stops iteration when inos exhaused or cb
 * returns FALSE.
 */
void
inomap_cbiter( intgen_t statemask,
	       bool_t ( * cbfunc )( void *ctxp, xfs_ino_t ino ),
	       void *ctxp )
{
	hnk_t *hnkp;
	seg_t *segp;

	/* step through all hunks, segs, and inos
	 */
	for ( hnkp = roothnkp
	      ;
	      hnkp != 0
	      ;
	      hnkp = hnkp->nextp ) {
		for ( segp = hnkp->seg
		      ;
		      segp < hnkp->seg + SEGPERHNK
		      ;
		      segp++ ) {
			xfs_ino_t ino;
			if ( hnkp == tailhnkp && segp > lastsegp ) {
				return;
			}
			for ( ino = segp->base
			      ;
			      ino < segp->base + INOPERSEG
			      ;
			      ino++ ) {
				intgen_t state;
				if ( ino > last_ino_added ) {
					return;
				}
				SEG_GET_BITS( segp, ino, state );
				if ( statemask & ( 1 << state )) {
					bool_t ok;
					ok = ( cbfunc )( ctxp, ino );
					if ( ! ok ) {
						return;
					}
				}
			}
		}
	}
}
Exemple #5
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;
}
Exemple #6
0
/* mark all included non-dirs as MAP_NDR_NOREST
 */
void
inomap_sanitize( void )
{
	hnk_t *hnkp;
	seg_t *segp;

	/* step through all hunks, segs, and inos
	 */
	for ( hnkp = roothnkp
	      ;
	      hnkp != 0
	      ;
	      hnkp = hnkp->nextp ) {
		for ( segp = hnkp->seg
		      ;
		      segp < hnkp->seg + SEGPERHNK
		      ;
		      segp++ ) {
			xfs_ino_t ino;
			if ( hnkp == tailhnkp && segp > lastsegp ) {
				return;
			}
			for ( ino = segp->base
			      ;
			      ino < segp->base + INOPERSEG
			      ;
			      ino++ ) {
				intgen_t state;
				if ( ino > last_ino_added ) {
					return;
				}
				SEG_GET_BITS( segp, ino, state );
				if ( state == MAP_NDR_CHANGE ) {
					state = MAP_NDR_NOREST;
					SEG_SET_BITS( segp, ino, state );
				}
			}
		}
	}
}
Exemple #7
0
/* called to ask if any inos in the given range need to be restored.
 * range is inclusive
 */
bool_t
inomap_rst_needed( xfs_ino_t firstino, xfs_ino_t lastino )
{
	hnk_t *hnkp;
	seg_t *segp;

	/* if inomap not restored/resynced, just say yes
	 */
	if ( ! roothnkp ) {
		return BOOL_TRUE;
	}

	/* may be completely out of range
	 */
	if ( firstino > last_ino_added ) {
		return BOOL_FALSE;
	}

	/* find the hunk/seg containing first ino or any ino beyond
	 */
	for ( hnkp = roothnkp ; hnkp != 0 ; hnkp = hnkp->nextp ) {
		if ( firstino > hnkp->maxino ) {
			continue;
		}
		for ( segp = hnkp->seg; segp < hnkp->seg + SEGPERHNK ; segp++ ){
			if ( hnkp == tailhnkp && segp > lastsegp ) {
				return BOOL_FALSE;
			}
			if ( firstino < segp->base + INOPERSEG ) {
				goto begin;
			}
		}
	}
	return BOOL_FALSE;

begin:
	/* search until at least one ino is needed or until beyond last ino
	 */
	for ( ; ; ) {
		xfs_ino_t ino;

		if ( segp->base > lastino ) {
			return BOOL_FALSE;
		}
		for ( ino = segp->base ; ino < segp->base + INOPERSEG ; ino++ ){
			intgen_t state;
			if ( ino < firstino ) {
				continue;
			}
			if ( ino > lastino ) {
				return BOOL_FALSE;
			}
			SEG_GET_BITS( segp, ino, state );
			if ( state == MAP_NDR_CHANGE ) {
				return BOOL_TRUE;
			}
		}
		segp++;
		if ( hnkp == tailhnkp && segp > lastsegp ) {
			return BOOL_FALSE;
		}
		if ( segp >= hnkp->seg + SEGPERHNK ) {
			hnkp = hnkp->nextp;
			if ( ! hnkp ) {
				return BOOL_FALSE;
			}
			segp = hnkp->seg;
		}
	}
	/* NOTREACHED */
}