📄 pblkf.c
字号:
*/ rc = pblHtDelete( pblblockhash ); if( !rc ) { /* * the hash table was empty and is deleted now */ pblblockhash = 0; } else { /* * the hash table was not deleted because it is not * empty, clear the error */ pbl_errno = 0; } return( 0 );}/*------------------------------------------------------------------------------ FUNCTION: pblBlockHashFind DESCRIPTION: Find a block reference in the hash table RETURNS: PBLBLOCK_t * retptr == 0: block not found otherwise: pointer to block in memory------------------------------------------------------------------------------*/static PBLBLOCK_t * pblBlockHashFind( long blockno, long bf ){ PBLBLOCKHASHKEY_t key; PBLBLOCKREF_t * ref; memset( &key, 0, sizeof( key )); key.blockno = blockno; key.bf = bf; /* * if there is no hash table yet, the reference is not found */ if( !pblblockhash ) { return( 0 ); } /* * see whether we have the reference */ ref = pblHtLookup( pblblockhash, &key, sizeof( key )); if( !ref ) { if( pbl_errno == PBL_ERROR_NOT_FOUND ) { pbl_errno = 0; } return( 0 ); } return( ref->block );}/* * BIGFILE functions *//* * find a filehandle of a filesystem file */static PBLBIGFILEHANDLE_t * pbf_fh_find( int bf, int n ){ PBLBIGFILEHANDLE_t * entry; /* * file system handles are kept in an LRU list */ for( entry = pbf_ft_head; entry; entry = entry->next ) { if( bf == entry->bf && n == entry->n ) { if( entry != pbf_ft_head ) { PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, entry, next, prev ); PBL_LIST_PUSH( pbf_ft_head, pbf_ft_tail, entry, next, prev ); } return( entry ); } } return( 0 );}/* * close files with the filesystem */static void pbf_fh_close( int bf, int n ){ PBLBIGFILEHANDLE_t * entry; PBLBIGFILEHANDLE_t * tmp; if( n < 0 ) { /* * close all file handles of this big file */ for( entry = pbf_ft_head; entry; ) { tmp = entry; entry = entry->next; if( bf == tmp->bf ) { close( tmp->fh ); PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, tmp, next, prev ); PBL_FREE( tmp ); } } return; } /* * close a particular file handle */ entry = pbf_fh_find( bf, n ); if( !entry ) { return; } close( entry->fh ); PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, entry, next, prev ); PBL_FREE( entry );}/* * create the bigfile path of a file * bigfiles are stored in multiple filesystem files * if the first one is called "file.ext", * the others have names like "file_0002.ext" etc. */static char * pbf_fh_path( char * name, long n ){ char * path; char * dotptr; if( n < 1 ) { /* * the name of the first file does not change */ path = strdup( name ); if( !path ) { pbl_errno = PBL_ERROR_OUT_OF_MEMORY; return( 0 ); } return( path ); } path = pbl_malloc( "pbf_fh_path path", 6 + strlen( name )); if( !path ) { return( 0 ); } /* * see if there is a ".ext" after the last slash */ dotptr = strrchr( name, '.' ); if( dotptr ) { if( strchr( dotptr, '/' ) || strchr( dotptr, '\\' )) { dotptr = 0; } } /* * build the filename, start counting at one */ n++; if( dotptr ) { memcpy( path, name, dotptr - name ); snprintf( path + ( dotptr - name ), 6, "_%04lx", 0xffff & n ); strcat( path, dotptr ); } else { strcpy( path, name ); snprintf( path + strlen( path ), 6, "_%04lx", 0xffff & n ); } return( path );}/* * open a file with the file system */static int pbf_fh_open( char * name, int mode, int bf, int n ){ PBLBIGFILEHANDLE_t * entry; int fh = -1; int i; char * path; /* * look in LRU list of open filesystem files */ entry = pbf_fh_find( bf, n ); if( entry ) { if( entry->mode != mode ) { /* * the file was found, but the open mode is wrong, close the file */ pbf_fh_close( bf, n ); entry = 0; } else { /* * the file is open in the right mode, use the file handle */ return( entry->fh ); } } /* * open the file */ path = pbf_fh_path( name, n ); if( !path ) { return( -1 ); } for( i = 0; i < 3; i++ ) { fh = open( path, mode, S_IREAD | S_IWRITE ); if( -1 == fh && pbf_ft_tail ) { /* * maybe the process or the system ran out of filehandles * close one file and try again */ pbf_fh_close( pbf_ft_tail->bf, pbf_ft_tail->n ); continue; } break; } PBL_FREE( path ); if( -1 == fh ) { pbl_errno = PBL_ERROR_OPEN; return( -1 ); } /* * create and link the file handle list entry */ entry = pbl_malloc0( "pbf_fh_open *entry", sizeof( *entry )); if( !entry ) { close( fh ); return( 0 ); } entry->fh = fh; entry->mode = mode; entry->bf = bf; entry->n = n; PBL_LIST_PUSH( pbf_ft_head, pbf_ft_tail, entry, next, prev ); return( entry->fh );}/* * close a bigfile */static int pbf_close( int bf ){ if( bf < 0 || bf >= PBL_NFILES ) { return( -1 ); } /* * close all filesystem files */ pbf_fh_close( bf, -1 ); PBL_FREE( pbf_pool[ bf ].name ); pbf_pool[ bf ].name = 0; return( 0 );}/* * open a bigfile */static int pbf_open(char * name,int update,long blocksperfile,long blocksize){ int fh = -1; int mode; int i; char * path; path = pbf_fh_path( name, 0 ); if( !path ) { return( -1 ); } if( update ) { mode = O_CREAT | O_BINARY | O_RDWR; } else { mode = O_BINARY | O_RDONLY; } /* * find a slot in the big file pool that is free */ for( i = 0; i < PBL_NFILES; i++ ) { if( pbf_pool[ i ].name ) { continue; } /* * reserve the slot */ pbf_pool[ i ].mode = mode; pbf_pool[ i ].nextblockno = -1; pbf_pool[ i ].blocksperfile = blocksperfile; pbf_pool[ i ].blocksize = blocksize; /* * open the first filesystem file */ fh = pbf_fh_open( path, mode, i, 0 ); if( -1 == fh ) { PBL_FREE( path ); pbl_errno = PBL_ERROR_OPEN; return( -1 ); } pbf_pool[ i ].name = path; return( i ); } PBL_FREE( path ); pbl_errno = PBL_ERROR_OPEN; return( -1 );}/* * file io for a bigfile */static int pbf_blockio(int bf,int blockwrite,long blockno,unsigned char * buffer){ long rc = -1; long n; int fh; int i; int j; long offset; if( bf < 0 || bf >= PBL_NFILES || !pbf_pool[ bf ].name ) { pbl_errno = PBL_ERROR_BAD_FILE; return( -1 ); } /* * make sure the n'th filesystem file is open */ n = blockno / pbf_pool[ bf ].blocksperfile; fh = pbf_fh_open( pbf_pool[ bf ].name, pbf_pool[ bf ].mode, bf, n ); if( -1 == fh ) { pbl_errno = PBL_ERROR_READ; return( -1 ); } blockno %= pbf_pool[ bf ].blocksperfile; offset = blockno * pbf_pool[ bf ].blocksize; if( blockwrite ) { /* * try the write more than once if needed */ for( i = 0; i < 3; i++ ) { /* * try the seek more than once if needed */ for( j = 0; j < 3; j++ ) { rc = lseek( fh, offset, SEEK_SET ); if( offset != rc ) { continue; } break; } if( offset != rc ) { pbl_errno = PBL_ERROR_SEEK; return( -1 ); } rc = write( fh, buffer, (unsigned int) pbf_pool[ bf ].blocksize ); if( rc != pbf_pool[ bf ].blocksize ) { if( errno == EINTR ) { continue; } pbl_errno = PBL_ERROR_WRITE; return( -1 ); } break; } if( i >= 3 ) { pbl_errno = PBL_ERROR_WRITE; return( -1 ); } pblnwrites++; } else { /* * try the read more than once if needed */ for( i = 0; i < 3; i++ ) { /* * try the seek more than once if needed */ for( j = 0; j < 3; j++ ) { rc = lseek( fh, offset, SEEK_SET ); if( offset != rc ) { continue; } break; } if( offset != rc ) { pbl_errno = PBL_ERROR_SEEK; return( -1 ); } rc = read( fh, buffer, (unsigned int) pbf_pool[ bf ].blocksize ); if( rc < 0 ) { if( errno == EINTR ) { continue; } pbl_errno = PBL_ERROR_READ; return( -1 ); } pblnreads++; if( rc != pbf_pool[ bf ].blocksize ) { if( errno == EINTR ) { continue; } pbl_errno = PBL_ERROR_BAD_FILE; return( -1 ); } break; } if( i >= 3 ) { pbl_errno = PBL_ERROR_READ; return( -1 ); } } return( 0 );}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -