예제 #1
0
파일: inomap.c 프로젝트: jkkm/xfsdump
rv_t
inomap_dump( drive_t *drivep )
{
	seg_addr_t addr;
	hnk_t *hnkp;
	hnk_t tmphnkp;

	/* use write_buf to dump the hunks
	 */
	for ( addr.hnkoff = 0 ;
	      addr.hnkoff <= inomap.lastseg.hnkoff ;
	      addr.hnkoff++ ) {
		intgen_t rval;
		rv_t rv;
		drive_ops_t *dop = drivep->d_opsp;

		hnkp = inomap_addr2hnk( &addr );

		xlate_hnk(hnkp, &tmphnkp, 1);
		rval = write_buf( ( char * )&tmphnkp,
				  sizeof( tmphnkp ),
				  ( void * )drivep,
				  ( gwbfp_t )dop->do_get_write_buf,
				  ( wfp_t )dop->do_write );
		switch ( rval ) {
		case 0:
			rv = RV_OK;
			break;
		case DRIVE_ERROR_MEDIA:
		case DRIVE_ERROR_EOM:
			rv = RV_EOM;
			break;
		case DRIVE_ERROR_EOF:
			rv = RV_EOF;
			break;
		case DRIVE_ERROR_DEVICE:
			rv = RV_DRIVE;
			break;
		case DRIVE_ERROR_CORE:
		default:
			rv = RV_CORE;
			break;
		}
		if ( rv != RV_OK ) {
			return rv;
		}
	}

	return RV_OK;
}
예제 #2
0
파일: inomap.c 프로젝트: crossmeta/sgi
rv_t
inomap_restore_pers( drive_t *drivep,
		     content_inode_hdr_t *scrhdrp,
		     char *hkdir )
{
	drive_ops_t *dop = drivep->d_opsp;
	char *perspath;
	pers_t *persp;
	hnk_t *pershnkp;
	hnk_t *tmphnkp;
	intgen_t fd;
	/* REFERENCED */
	intgen_t nread;
	intgen_t rval;
	/* REFERENCED */
	intgen_t rval1;
	int i;
	bool_t ok;

	/* sanity checks
	 */
	ASSERT( INOPERSEG == ( sizeof( (( seg_t * )0 )->lobits ) * NBBY ));
	ASSERT( sizeof( hnk_t ) == HNKSZ );
	ASSERT( HNKSZ >= pgsz );
	ASSERT( ! ( HNKSZ % pgsz ));
	ASSERT( sizeof( pers_t ) <= PERSSZ );

	/* get inomap info from media hdr
	 */
	hnkcnt = scrhdrp->cih_inomap_hnkcnt;
	segcnt = scrhdrp->cih_inomap_segcnt;
	last_ino_added = scrhdrp->cih_inomap_lastino;

	/* truncate and open the backing store
	 */
	perspath = open_pathalloc( hkdir, PERS_NAME, 0 );
	( void )unlink( perspath );
	fd = open( perspath,
		   O_RDWR | O_CREAT,
		   S_IRUSR | S_IWUSR );
	if ( fd < 0 ) {
		mlog( MLOG_NORMAL | MLOG_ERROR,
		      "could not open %s: %s\n",
		      perspath,
		      strerror( errno ));
		return RV_ERROR;
	}

	/* mmap the persistent hdr and space for the map
	 */
	ASSERT( sizeof( hnk_t ) * ( size_t )hnkcnt >= pgsz );
	ASSERT( ! ( sizeof( hnk_t ) * ( size_t )hnkcnt % pgsz ));
	persp = ( pers_t * ) mmap_autogrow(
				     PERSSZ
				     +
				     sizeof( hnk_t ) * ( size_t )hnkcnt,
				     fd,
				     ( off64_t )0 );
	if ( persp == ( pers_t * )-1 ) {
		mlog( MLOG_NORMAL | MLOG_ERROR,
		      "unable to map %s: %s\n",
		      perspath,
		      strerror( errno ));
		return RV_ERROR;
	}

	/* load the pers hdr
	 */
	persp->hnkcnt = hnkcnt;
	persp->segcnt = segcnt;
	persp->last_ino_added = last_ino_added;

	tmphnkp = ( hnk_t * )calloc( ( size_t )hnkcnt, sizeof( hnk_t ));
	ASSERT( tmphnkp );

	/* read the map in from media
	 */
	nread = read_buf( ( char * )tmphnkp,
			  sizeof( hnk_t ) * ( size_t )hnkcnt,
			  ( void * )drivep,
			  ( rfp_t )dop->do_read,
			  ( rrbfp_t )dop->do_return_read_buf,
			  &rval );

	pershnkp = (hnk_t *)((char *)persp + PERSSZ);
	for(i = 0; i < hnkcnt; i++) {
		xlate_hnk(&tmphnkp[i], &pershnkp[i], 1);
	}
	free(tmphnkp);

	mlog(MLOG_NITTY, "inomap_restore_pers: pre-munmap\n");

	/* close up
	 */
	rval1 = munmap( ( void * )persp,
		        PERSSZ
		        +
		        sizeof( hnk_t ) * ( size_t )hnkcnt );
	ASSERT( ! rval1 );
	( void )close( fd );
	free( ( void * )perspath );

	mlog(MLOG_NITTY, "inomap_restore_pers: post-munmap\n");

	/* check the return code from read
	 */
	switch( rval ) {
	case 0:
		ASSERT( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt );
		ok = inomap_sync_pers( hkdir );
		if ( ! ok ) {
			return RV_ERROR;
		}
		return RV_OK;
	case DRIVE_ERROR_EOD:
	case DRIVE_ERROR_EOF:
	case DRIVE_ERROR_EOM:
	case DRIVE_ERROR_MEDIA:
	case DRIVE_ERROR_CORRUPTION:
		return RV_CORRUPT;
	case DRIVE_ERROR_DEVICE:
		return RV_DRIVE;
	case DRIVE_ERROR_CORE:
	default:
		return RV_CORE;
	}
}