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; }
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 {
/* 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; }
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 ); }
/* 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; }
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; }
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; }