Exemple #1
0
int
DRead(struct dcache *adc, int page, struct DirBuffer *entry)
{
    /* Read a page from the disk. */
    struct buffer *tb, *tb2;
    struct osi_file *tfile;
    int code;

    AFS_STATCNT(DRead);

    memset(entry, 0, sizeof(struct DirBuffer));

    ObtainWriteLock(&afs_bufferLock, 256);

#define bufmatch(tb) (tb->page == page && tb->fid == adc->index)
#define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);}

    /* this apparently-complicated-looking code is simply an example of
     * a little bit of loop unrolling, and is a standard linked-list
     * traversal trick. It saves a few assignments at the the expense
     * of larger code size.  This could be simplified by better use of
     * macros.
     */
    if ((tb = phTable[pHash(adc->index, page)])) {
	if (bufmatch(tb)) {
	    ObtainWriteLock(&tb->lock, 257);
	    tb->lockers++;
	    ReleaseWriteLock(&afs_bufferLock);
	    tb->accesstime = timecounter++;
	    AFS_STATS(afs_stats_cmperf.bufHits++);
	    ReleaseWriteLock(&tb->lock);
	    entry->buffer = tb;
	    entry->data = tb->data;
	    return 0;
	} else {
	    struct buffer **bufhead;
	    bufhead = &(phTable[pHash(adc->index, page)]);
	    while ((tb2 = tb->hashNext)) {
		if (bufmatch(tb2)) {
		    buf_Front(bufhead, tb, tb2);
		    ObtainWriteLock(&tb2->lock, 258);
		    tb2->lockers++;
		    ReleaseWriteLock(&afs_bufferLock);
		    tb2->accesstime = timecounter++;
		    AFS_STATS(afs_stats_cmperf.bufHits++);
		    ReleaseWriteLock(&tb2->lock);
		    entry->buffer = tb2;
		    entry->data = tb2->data;
		    return 0;
		}
		if ((tb = tb2->hashNext)) {
		    if (bufmatch(tb)) {
			buf_Front(bufhead, tb2, tb);
			ObtainWriteLock(&tb->lock, 259);
			tb->lockers++;
			ReleaseWriteLock(&afs_bufferLock);
			tb->accesstime = timecounter++;
			AFS_STATS(afs_stats_cmperf.bufHits++);
			ReleaseWriteLock(&tb->lock);
			entry->buffer = tb;
			entry->data = tb->data;
			return 0;
		    }
		} else
		    break;
	    }
	}
    } else
	tb2 = NULL;

    AFS_STATS(afs_stats_cmperf.bufMisses++);
    /* can't find it */
    /* The last thing we looked at was either tb or tb2 (or nothing). That
     * is at least the oldest buffer on one particular hash chain, so it's
     * a pretty good place to start looking for the truly oldest buffer.
     */
    tb = afs_newslot(adc, page, (tb ? tb : tb2));
    if (!tb) {
	ReleaseWriteLock(&afs_bufferLock);
	return EIO;
    }
    ObtainWriteLock(&tb->lock, 260);
    tb->lockers++;
    ReleaseWriteLock(&afs_bufferLock);
    if (page * AFS_BUFFER_PAGESIZE >= adc->f.chunkBytes) {
	tb->fid = NULLIDX;
	afs_reset_inode(&tb->inode);
	tb->lockers--;
	ReleaseWriteLock(&tb->lock);
	return EIO;
    }
    tfile = afs_CFileOpen(&adc->f.inode);
    code =
	afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data,
		      AFS_BUFFER_PAGESIZE);
    afs_CFileClose(tfile);
    if (code < AFS_BUFFER_PAGESIZE) {
	tb->fid = NULLIDX;
	afs_reset_inode(&tb->inode);
	tb->lockers--;
	ReleaseWriteLock(&tb->lock);
	return EIO;
    }
    /* Note that findslot sets the page field in the buffer equal to
     * what it is searching for. */
    ReleaseWriteLock(&tb->lock);
    entry->buffer = tb;
    entry->data = tb->data;
    return 0;
}
Exemple #2
0
/**
 * read a page out of a directory object.
 *
 * @param[in] fid   directory object fid
 * @param[in] page  page in hash table to be read
 *
 * @return pointer to requested page in directory cache
 *    @retval NULL read failed
 */
void *
DRead(afs_int32 *fid, int page)
{
    /* Read a page from the disk. */
    struct buffer *tb, *tb2, **bufhead;

    ObtainWriteLock(&afs_bufferLock);
    calls++;

#define bufmatch(tb) (tb->page == page && FidEq(tb->fid, fid))
#define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);}

    /* this apparently-complicated-looking code is simply an example of
     * a little bit of loop unrolling, and is a standard linked-list
     * traversal trick. It saves a few assignments at the the expense
     * of larger code size.  This could be simplified by better use of
     * macros.  With the use of these LRU queues, the old one-cache is
     * probably obsolete.
     */
    if ((tb = phTable[pHash(fid)])) {	/* ASSMT HERE */
	if (bufmatch(tb)) {
	    ObtainWriteLock(&tb->lock);
	    tb->lockers++;
	    ReleaseWriteLock(&afs_bufferLock);
	    tb->accesstime = ++timecounter;
	    ReleaseWriteLock(&tb->lock);
	    return tb->data;
	} else {
	    bufhead = &(phTable[pHash(fid)]);
	    while ((tb2 = tb->hashNext)) {
		if (bufmatch(tb2)) {
		    buf_Front(bufhead, tb, tb2);
		    ObtainWriteLock(&tb2->lock);
		    tb2->lockers++;
		    ReleaseWriteLock(&afs_bufferLock);
		    tb2->accesstime = ++timecounter;
		    ReleaseWriteLock(&tb2->lock);
		    return tb2->data;
		}
		if ((tb = tb2->hashNext)) {	/* ASSIGNMENT HERE! */
		    if (bufmatch(tb)) {
			buf_Front(bufhead, tb2, tb);
			ObtainWriteLock(&tb->lock);
			tb->lockers++;
			ReleaseWriteLock(&afs_bufferLock);
			tb->accesstime = ++timecounter;
			ReleaseWriteLock(&tb->lock);
			return tb->data;
		    }
		} else
		    break;
	    }
	}
    } else
	tb2 = NULL;

    /* can't find it */
    /* The last thing we looked at was either tb or tb2 (or nothing). That
     * is at least the oldest buffer on one particular hash chain, so it's
     * a pretty good place to start looking for the truly oldest buffer.
     */
    tb = newslot(fid, page, (tb ? tb : tb2));
    ios++;
    ObtainWriteLock(&tb->lock);
    tb->lockers++;
    ReleaseWriteLock(&afs_bufferLock);
    if (ReallyRead(tb->fid, tb->page, tb->data)) {
	tb->lockers--;
	FidZap(tb->fid);	/* disaster */
	ReleaseWriteLock(&tb->lock);
	return 0;
    }
    /* Note that findslot sets the page field in the buffer equal to
     * what it is searching for.
     */
    ReleaseWriteLock(&tb->lock);
    return tb->data;
}
static short ppm_image_init_rev( LPBJF_IMAGEINFO lpbjfimage )
{
	FILE			*readfp;
	FILE			*tmpfp;
	unsigned char	buffer[50];
	unsigned char	*buf = NULL;
	unsigned char	**rawbuf = NULL;
	short			tmpflg;
	short			tmpformat;
	short			retbyte = 0;
	short			bpp = 3;
	long			width = 0;
	long			length = 0;
	long			maxvalue = 0;
	long			rstep = 0;
	long			RasterLength = 0;
	long			i;
	short			result = -1;
	char			ch;
	long			fp_offset;

	/*---
		We must init global parameters again, without isfirstcall and 
			ppm imageformat is inited in ppmraw_image_open
	---*/
	tmpflg    = lpbjfimage->isfirstcall;
	tmpformat = lpbjfimage->imageformat;
	tmpfp     = lpbjfimage->bmp;

	memset( (LPBJF_IMAGEINFO)lpbjfimage, 0, sizeof(BJF_IMAGEINFO) );

	lpbjfimage->isfirstcall = tmpflg;
	lpbjfimage->imageformat = tmpformat;
	lpbjfimage->bmp			= tmpfp;

	
	readfp = lpbjfimage->bmp;

	/*--- 
		when second page,
	---*/
	if ( lpbjfimage->isfirstcall ){
		lpbjfimage->isfirstcall = 0;
	}
	else{
		retbyte = fread( buffer, 2, 1, readfp );

		if ( !retbyte ){	/* end document */
			result = 0;
			goto onErr;
		}

		if ( bufmatch( (char *)PPMRAWSTART, (char*)buffer, 2 ) < 0 ) goto onErr;
	}

	/* skip "0x0A" after "P6" */
	if ( (ch = fgetc( readfp )) == EOF ) goto onErr;	

	readPPMParam( readfp, &width, &length, &maxvalue );
	
	if ( (!width) || (!length) ) goto onErr;
	
	RasterLength = width * bpp;
	
	/* parameter check */
	if ( maxvalue != 255 ) goto onErr;

	/*--- Get image raw data ( by MAXBUFSIZE unit ) ---*/
	rstep = MAXBUF / RasterLength;

	if ( rstep > length ){
		rstep = length;
	}

	if ( (buf = (unsigned char *)malloc( MAXBUF )) == NULL ) goto onErr;

	rawbuf = (unsigned char **)calloc( sizeof(unsigned char *), rstep );
	if ( rawbuf == NULL ) goto onErr;

	for( i=0; i<rstep; i++ ){
		rawbuf[i] = buf + RasterLength * i;
	} 

	fp_offset = RasterLength * ( length - rstep );
	
	if ( fseek( readfp, fp_offset, SEEK_CUR ) != 0 ){
		goto onErr;
	}
	if ( !fread( buf, RasterLength, rstep,  readfp ) ){
		goto onErr;
	}
	lpbjfimage->readraster += rstep;

	/* go back to read start point */
	if ( fseek( readfp, -( RasterLength * rstep ) , SEEK_CUR ) != 0 ){
		goto onErr;
	}


	/*--- Set cif Parameter ---*/
	lpbjfimage->width        = width;
	lpbjfimage->length       = length;
	lpbjfimage->bpp          = bpp;
	lpbjfimage->rasterlength = width * bpp;
	lpbjfimage->outputtype   = BJFOUTPUT_COLOR;
	lpbjfimage->xresolution  = 0;
	lpbjfimage->yresolution  = 0;
	lpbjfimage->bmpraw       = rawbuf;
	lpbjfimage->rstep        = rstep;
	lpbjfimage->top          = 0;

	result = 1;
onErr:
	return result;	
}	
/*---------------------------------------------------------------*/
int ppm_write_tmpfile( LPBJF_IMAGEINFO lpbjfimage, char *filename , char *outfile)
{
	FILE			*readfp = NULL;
	unsigned char	buffer[5];
	long			width = 0;
	long			length = 0;
	long			maxvalue = 0;
	short			bpp = 3;
	long			RasterLength = 0;	/* width of a raster */
	long			read_len = 0;
	long			imagesize = 0;
	short			retbyte;
	char			ch;
	unsigned char	*buf = NULL;
	long			parm_len = 0;
	int				fd = -1;
	int				w_size;
	long			block_num = 0;
	long			lastblock_size = 0;
	short			i;
	
	
	if ( filename != NULL ){
		if ( (readfp = fopen( filename, "rb" )) == NULL ) goto onErr;
		fread( buffer, 2, 1, readfp );
	}
	else {
		readfp = stdin;
	}

	
	/* check header */
	retbyte = fread( buffer, 2, 1, readfp );

	if ( !retbyte ){	/* end document */
		return CIF_FILE_END;	/* end document --> return */
	}

	if ( bufmatch( (char *)PPMRAWSTART, (char*)buffer, 2 ) < 0 ) goto onErr;

	/* make tempfile to output */
	fd = mkstemp(outfile);
	if(  fd  < 0 ){
		goto onErr;
	}

	/* write "P6" */
	w_size = write( fd , PPMRAWSTART , 2 );

	/* skip "0x0A" after "P6" */
	if ( (ch = fgetc( readfp )) == EOF ) goto onErr;	
	w_size = write( fd , &ch , 1 );


	/* read and write PPM parameter */
	parm_len = readwritePPMParam( readfp, &width, &length, &maxvalue , fd );

	if ( (!width) || (!length) ) goto onErr;
	
	/* parameter check */
	if ( maxvalue != 255 ) goto onErr;

	RasterLength = width * bpp;
	imagesize = RasterLength * length;

	/* allocate read buffer */
	if ( (buf = (unsigned char *)malloc( MAXBUF )) == NULL ) goto onErr;
	block_num = imagesize / MAXBUF;
	lastblock_size = imagesize % MAXBUF;

	/* read and write image raw data ( by MAXBUFSIZE unit ) */
	for( i=0 ; i<block_num ; i++ ){
		if ( !(read_len = fread( buf, 1, MAXBUF, readfp ) )){
			goto onErr;
		}
		w_size = write( fd , buf , MAXBUF );
	}
	
	if( lastblock_size > 0 ){
		if ( !(read_len = fread( buf, 1, lastblock_size, readfp ) )){
			goto onErr;
		}
		w_size = write( fd , buf , lastblock_size );
	}
	
	if( buf ) free(buf);
	close( fd );
	return fd;


onErr:
	if( fd >= 0 ){
		close( fd );
		unlink(outfile);
	}
	if( buf ) free(buf);
	return -1;
}
/*-------------------------------------------------------------*/
short bjf_image_open( LPBJF_IMAGEINFO lpbjfimage, char *filename )
/*-------------------------------------------------------------*/
{
	FILE				*tf = NULL;
	unsigned char		tbuf[10];
	short				result = -1;
	
	/*--- initialize image work parameter ---*/
	memset( (LPBJF_IMAGEINFO)lpbjfimage, 0, sizeof(BJF_IMAGEINFO) );
	
	/*-------------------------------*/
	/*		Select Image Format		 */
	/*-------------------------------*/
	/*---- in case input is stdin ---*/
	if ( filename == NULL ){
		if ( !fread( tbuf, 2, 1, stdin ) ) goto onErr;

		/*-- support ppm stdin --*/
		if ( bufmatch( (char *)PPMRAWSTART, (char *)tbuf, 2 ) > 0 ){
			lpbjfimage->imageformat = BJFIMAGE_PPM;
		}
		else {
			fprintf( stderr, "Error : not support this image format\n");
			goto onErr;
		}
	}
	/*--- in case input is file ---*/
	else{
		if ( (tf=fopen( filename, "rb" )) == NULL ) goto onErr; 

		/* top 4 byte of file */
		if ( !fread( tbuf, 8, 1, tf ) ) goto onErr;
		
		if ( tf != NULL ){
			fclose( tf );
			tf = NULL;
		}
	
		if ( bufmatch( (char*)PPMRAWSTART, (char *)tbuf, 2 ) > 0 )
			lpbjfimage->imageformat = BJFIMAGE_PPM;
		else{
			fprintf( stderr, "Error : not support this image format\n");
			goto onErr;
		}
	}

	/*--------------------------*/
	/*		Open Read Image		*/
	/*--------------------------*/
	switch( lpbjfimage->imageformat ){
		case BJFIMAGE_PPM:
			if ( ppm_image_open( lpbjfimage, filename  ) < 0 ) goto onErr;
			break;
		default:
			fprintf( stderr, "Error : not support this image format\n");
			goto onErr;
	}


	result = 0;
	return result;
	
onErr:
	if ( tf != NULL ) fclose( tf );
	return result;
}