Пример #1
0
/* Get pblock for a given inode and lblock.  If extent is not NULL, it will
 * store the length of extent, that is, the number of consecutive pblocks
 * that are also consecutive lblocks (not counting the requested one). */
uint64_t inode_get_data_pblock(struct ext4_inode *inode, uint32_t lblock, uint32_t *extent_len)
{
    if (extent_len) *extent_len = 1;

    if (inode->i_flags & EXT4_EXTENTS_FL) {
        return extent_get_pblock(&inode->i_block, lblock, extent_len);
    } else {
        ASSERT(lblock <= BYTES2BLOCKS(inode_get_size(inode)));

        if (lblock < EXT4_NDIR_BLOCKS) {
            return inode->i_block[lblock];
        } else if (lblock < MAX_IND_BLOCK) {
            uint32_t index_block = inode->i_block[EXT4_IND_BLOCK];
            return __inode_get_data_pblock_ind(lblock - EXT4_NDIR_BLOCKS, index_block);
        } else if (lblock < MAX_DIND_BLOCK) {
            uint32_t dindex_block = inode->i_block[EXT4_DIND_BLOCK];
            return __inode_get_data_pblock_dind(lblock - MAX_IND_BLOCK, dindex_block);
        } else if (lblock < MAX_TIND_BLOCK) {
            uint32_t tindex_block = inode->i_block[EXT4_TIND_BLOCK];
            return __inode_get_data_pblock_tind(lblock - MAX_DIND_BLOCK, tindex_block);
        } else {
            /* File-system corruption? */
            ASSERT(0);
        }
    }

    /* Should never reach here */
    ASSERT(0);
    return 0;
}
Пример #2
0
/*
 * _sdsset sets all bytes in an SDS data segment to a specified value.
 *
 * Both byte_offset and nbytes must be 512-word block multiples.
 *
 * Returns byte_offset on normal return.  If an error is encountered -1 is 
 * returned with the error code in errno.
 */
_sdsset(
int byte_offset,	/* Byte offset into SDS area */
int value,		/* Value to which all bytes should be set */
int nbytes)		/* Number of bytes to set */
{
#define _BUFFER_BLOCKS	10

	char bytebuf[_BUFFER_BLOCKS * BYTPBLOCK]; /* must be word-aligned */
	int  nblocks;
	int  blk_offset;
	int  ret;
	int  this_chunk;
	int  left;
	
	/* check that byte_offset and nbytes are on block boundaries */
	if ((byte_offset | nbytes) & (BYTPBLOCK - 1)) {
		errno = FDC_ERR_GRAN;
		return -1;
	}

	nblocks    = BYTES2BLOCKS(nbytes);
	blk_offset = BYTES2BLOCKS(byte_offset);
	
	(void)memset(bytebuf, value, MIN(nblocks, _BUFFER_BLOCKS) * BYTPBLOCK);

	left  = nblocks;
	while (left > 0) {
		this_chunk = MIN(left, _BUFFER_BLOCKS);

		ret = sswrite((long)bytebuf, blk_offset, this_chunk); 
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}

		left       -= this_chunk;
		blk_offset += this_chunk;
	}
	return byte_offset;
}
Пример #3
0
_sdsset_any(
int byte_offset,	/* Byte offset into SDS area */
int value,		/* Value to which all bytes should be set */
int nbytes)		/* Number of bytes to set */
{
#define _BUFFER_BLOCKS	10

	char bytebuf[_BUFFER_BLOCKS * BYTPBLOCK]; /* must be word-aligned */
	int  nblocks;
	int  blk_offset;
	int  ret;
	int  this_chunk;
	int  left;
	int  lblk_offset;	
	int  headbytes,tailbytes;
	int  orig_byte_offset;

	orig_byte_offset = byte_offset;
	nblocks    = BYTES2BLOCKS(nbytes);
	blk_offset = BYTES2BLOCKS(byte_offset);

	/* if byte_offset is not on a block boundary */
	if ((byte_offset) & (BYTPBLOCK - 1)) {

		headbytes = BYTPBLOCK - (byte_offset & (BYTPBLOCK -1 ));
			
		if (headbytes > nbytes)
			headbytes = nbytes;
		ret = ssread(bytebuf, blk_offset, 1);
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}
		memset(bytebuf + (byte_offset & (BYTPBLOCK-1)), value, headbytes);
		ret = sswrite(bytebuf, blk_offset, 1);	
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}
		nbytes -= headbytes;
		nblocks = BYTES2BLOCKS(nbytes);
		byte_offset += headbytes;
		blk_offset = BYTES2BLOCKS(byte_offset);
	}
	if (nbytes & (BYTPBLOCK - 1)){
		/* these will be the bytes left over at the end */
		tailbytes = nbytes & (BYTPBLOCK - 1);
		lblk_offset = BYTES2BLOCKS(byte_offset + nbytes -1);
		ret = ssread(bytebuf, lblk_offset, 1);
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}
		memset(bytebuf, value, tailbytes);
		ret = sswrite(bytebuf, lblk_offset, 1);
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}
		nbytes -= tailbytes;
	}
	if (nbytes & (BYTPBLOCK -1 )){
		abort();
	}
	
	(void)memset(bytebuf, value, MIN(nblocks, _BUFFER_BLOCKS) * BYTPBLOCK);

	left  = nblocks;
	while (left > 0) {
		this_chunk = MIN(left, _BUFFER_BLOCKS);

		ret = sswrite((long)bytebuf, blk_offset, this_chunk); 
		if (ret == -1) {
			errno = FDC_ERR_SDSIO;
			return -1;
		}

		left       -= this_chunk;
		blk_offset += this_chunk;
	}
	return orig_byte_offset;
}