kernels/linux-2.4.0/fs/cramfs/inode.c
/*
 * Returns a pointer to a buffer containing at least LEN bytes of
 * filesystem starting at byte offset OFFSET into the filesystem.
 */
Returns a pointer to a buffer containing at least LEN bytes of
filesystem starting at byte offset OFFSET into the filesystem.
Returns a pointer to a buffer containing at least LEN bytes of filesystem starting at byte offset OFFSET into the filesystem .
static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
{
	struct buffer_head * bh_array[BLKS_PER_BUF];
	unsigned i, blocknr, buffer;
	char *data;
	if (!len)
		return NULL;
	blocknr = offset >> PAGE_CACHE_SHIFT;
	offset &= PAGE_CACHE_SIZE - 1;
	for (i = 0; i < READ_BUFFERS; i++) {
		unsigned int blk_offset;
		if (buffer_dev[i] != sb)
			continue;
		if (blocknr < buffer_blocknr[i])
			continue;
		blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_CACHE_SHIFT;
		blk_offset += offset;
		if (blk_offset + len > BUFFER_SIZE)
			continue;
		return read_buffers[i] + blk_offset;
	}
	for (i = 0; i < BLKS_PER_BUF; i++)
		bh_array[i] = bread(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE);
	buffer = next_buffer;
	next_buffer = NEXT_BUFFER(buffer);
	buffer_blocknr[buffer] = blocknr;
	buffer_dev[buffer] = sb;
	data = read_buffers[buffer];
	for (i = 0; i < BLKS_PER_BUF; i++) {
		struct buffer_head * bh = bh_array[i];
		if (bh) {
			memcpy(data, bh->b_data, PAGE_CACHE_SIZE);
			bforget(bh);
		} else
			memset(data, 0, PAGE_CACHE_SIZE);
		data += PAGE_CACHE_SIZE;
	}
	return read_buffers[buffer] + offset;
}
static void * cramfs_read ( struct super_block * sb , unsigned int offset , unsigned int len ) { struct buffer_head * bh_array [ BLKS_PER_BUF ] ; unsigned i , blocknr , buffer ; char * data ; if ( ! len ) return NULL ; blocknr = offset >> PAGE_CACHE_SHIFT ; offset &= PAGE_CACHE_SIZE - 1 ; for ( i = 0 ; i < READ_BUFFERS ; i ++ ) { unsigned int blk_offset ; if ( buffer_dev [ i ] != sb ) continue ; if ( blocknr < buffer_blocknr [ i ] ) continue ; blk_offset = ( blocknr - buffer_blocknr [ i ] ) << PAGE_CACHE_SHIFT ; blk_offset += offset ; if ( blk_offset + len > BUFFER_SIZE ) continue ; return read_buffers [ i ] + blk_offset ; } for ( i = 0 ; i < BLKS_PER_BUF ; i ++ ) bh_array [ i ] = bread ( sb -> s_dev , blocknr + i , PAGE_CACHE_SIZE ) ; buffer = next_buffer ; next_buffer = NEXT_BUFFER ( buffer ) ; buffer_blocknr [ buffer ] = blocknr ; buffer_dev [ buffer ] = sb ; data = read_buffers [ buffer ] ; for ( i = 0 ; i < BLKS_PER_BUF ; i ++ ) { struct buffer_head * bh = bh_array [ i ] ; if ( bh ) { memcpy ( data , bh -> b_data , PAGE_CACHE_SIZE ) ; bforget ( bh ) ; } else memset ( data , 0 , PAGE_CACHE_SIZE ) ; data += PAGE_CACHE_SIZE ; } return read_buffers [ buffer ] + offset ; }
Returns a pointer to a buffer containing at least LEN bytes of
 filesystem starting at byte offset OFFSET into the filesystem.
Returns a pointer to a buffer containing at least LEN bytes of filesystem starting at byte offset OFFSET into the filesystem .
/* Check if an existing buffer already has the data.. */ /* Ok, read in BLKS_PER_BUF pages completely first. */ /* Ok, copy them to the staging area without sleeping. */