Exemplo n.º 1
0
bool LinnDirectory::getLinnDirectoryEntry(LinnDirectoryEntry *dent,
					  const char *name)
{
    LinnSuperBlock *sb = fs->getSuperBlock();
    u64 offset;

    /* Loop all blocks. */
    for (u32 blk = 0; blk < LINN_INODE_NUM_BLOCKS(sb, inode); blk++)
    {
	/* Read directory entries. */
	for (u32 ent = 0; ent < LINN_DIRENT_PER_BLOCK(sb); ent++)
	{
	    /* Calculate offset to read. */
	    offset = (inode->block[blk] * sb->blockSize) +
		     (sizeof(LinnDirectoryEntry) * ent);

	    /* Get the next entry. */
	    if (fs->getStorage()->read(offset, dent,
				       sizeof(LinnDirectoryEntry)) < 0)
	    {
		return false;
	    }
	    /* Is it the entry we are looking for? */
	    if (strcmp(name, dent->name) == 0)
	    {
		return true;
	    }
	}
    }
    /* Not found. */
    return false;
}
Exemplo n.º 2
0
void LinnCreate::insertFile(char *inputFile, LinnInode *inode,
			    struct stat *st)
{
    int fd, bytes;
    le32 blockNr;
    bool stripped;
    char *tmpPath = strdup(inputFile);

    /* Get file handle. */
    stripped = openFile(tmpPath, st, &fd);

    /* Read blocks from the file. */
    while (true)
    {
	/* Grab a block. */
	blockNr = BLOCK(super);
    
	/* Read a block. */
	if ((bytes = read(fd, BLOCKPTR(u8, blockNr), super->blockSize)) < 0)
	{
	    printf("%s: failed to read() `%s': %s\n",
		    prog, inputFile, strerror(errno));
	    exit(EXIT_FAILURE);
	}
	/* End of file? */
	if (!bytes) break;
	
	/* Insert the block (direct). */
	if (LINN_INODE_NUM_BLOCKS(super, inode) <
	    LINN_INODE_DIR_BLOCKS)
	{
	    inode->block[LINN_INODE_NUM_BLOCKS(super,inode)] = blockNr;
	}
	/* Insert the block (indirect). */
	else if (LINN_INODE_NUM_BLOCKS(super, inode) <
		 LINN_INODE_DIR_BLOCKS + LINN_SUPER_NUM_PTRS(super))
	{
	    insertIndirect(&inode->block[LINN_INODE_IND_BLOCKS-1],
			    LINN_INODE_NUM_BLOCKS(super, inode) -
			    LINN_INODE_DIR_BLOCKS, blockNr, 1);
	}
	/* Insert the block (double indirect). */
	else if (LINN_INODE_NUM_BLOCKS(super, inode) <
		 LINN_INODE_DIR_BLOCKS + (LINN_SUPER_NUM_PTRS(super) *
					  LINN_SUPER_NUM_PTRS(super)))
	{
	    insertIndirect(&inode->block[LINN_INODE_DIND_BLOCKS-1],
			    LINN_INODE_NUM_BLOCKS(super, inode) -
			    LINN_INODE_DIR_BLOCKS, blockNr, 2);
	}
	/* Insert the blck (triple indirect). */
	else if (LINN_INODE_NUM_BLOCKS(super, inode) <
		 LINN_INODE_DIR_BLOCKS + (LINN_SUPER_NUM_PTRS(super) *
					  LINN_SUPER_NUM_PTRS(super) *
					  LINN_SUPER_NUM_PTRS(super)))
	{
	    insertIndirect(&inode->block[LINN_INODE_TIND_BLOCKS-1],
			    LINN_INODE_NUM_BLOCKS(super, inode) -
			    LINN_INODE_DIR_BLOCKS, blockNr, 3);
	}
	/* Maximum file capacity reached. */
	else
	{
	    printf("%s: maximum file size reached for `%s'\n",
		    prog, inputFile);
	    break;
	}
	/* Increment size appropriately. */
	inode->size += bytes;
    }
    /* Cleanup. */
    close(fd);
    if (stripped) unlink(tmpPath);
}
Exemplo n.º 3
0
Error LinnFile::read(IOBuffer & buffer, Size size, Size offset)
{
    LinnSuperBlock *sb;
    Size bytes = 0, blockNr = 0;
    u64 storageOffset, copyOffset = offset;
    u8 *block;
    Size total = 0;
    Error e;

#warning very inefficient. blocks are not cached from storage and thrown away each time.

    /* Initialize variables. */
    sb     = fs->getSuperBlock();
    block  = new u8[sb->blockSize];

    /* Skip ahead blocks. */
    while ((sb->blockSize * (blockNr + 1)) <= copyOffset)
    {
        blockNr++;
    }
    /* Adjust the copy offset within this block. */
    copyOffset -= sb->blockSize * blockNr;

    /* Loop all blocks. */
    while (blockNr < LINN_INODE_NUM_BLOCKS(sb, inode) &&
	   total < size && inode->size - (offset + total) > 0)
    {
	/* Calculate the offset in storage for this block. */
	storageOffset = fs->getOffset(inode, blockNr);

        /* Fetch the next block. */
        if (fs->getStorage()->read(storageOffset, block, sb->blockSize) < 0)
	{
	    delete block;
	    return EIO;
	}
	/* Calculate the number of bytes to copy. */
	bytes = sb->blockSize - copyOffset;
	
	/* Respect the inode size. */
	if (bytes > inode->size - (offset + total))
	{
	    bytes = inode->size - (offset + total);
	}
	/* Respect the remote process buffer. */
	if (bytes > size - total)
	{
	    bytes = size - total;
	}
        /* Copy into the buffer. */
	if ((e = buffer.write(block + copyOffset, bytes, total)) < 0)
	{
	    delete block;
	    return e;
	}
	/* Update state. */
	total      += bytes;
	copyOffset  = 0;
	blockNr++;
    }
    /* Success. */
    delete block;
    return (Error) total;
}