예제 #1
0
/*
 * s5fs_dirtypage:
 * A hook; an attempt is being made to dirty the page
 * belonging to 'vnode' that contains 'offset'. (If the
 * underlying fs supports sparse blocks/pages, and the page
 * containing this offset is currently sparse, this is
 * where an attempt should be made to allocate a block in
 * the underlying fs for that block/page). Return zero on
 * success and nonzero otherwise.
 * param vnode: the pointer to the vnode object
 * param offset: the arbitrary offset of that file (bytes offset)
 * return: the block number or 0; negative number for failure
 */
static int
s5fs_dirtypage(vnode_t *vnode, off_t offset)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    
    int disk_number = 0;
    int sparse      = 0;
    if ((sparse = s5_seek_to_block(vnode, offset, 0)) < 0)
    {
        return sparse;
        
    }
    else if (sparse > 0)
    {
        /* find the page */
        return 0;
    }
    
    if ((disk_number = s5_seek_to_block(vnode, offset, 1)) < 0)
    {
        return disk_number;
    }
    
    /* Dirty the page */
    
    s5_dirty_inode(VNODE_TO_S5FS(vnode), VNODE_TO_S5INODE(vnode));
    
    dbg(DBG_S5FS, "}\n");
    
    return 0;
}
예제 #2
0
/*
 * s5fs_fillpage:
 * Read the page of 'vnode' containing 'offset' into the
 * page-aligned and page-sized buffer pointed to by
 * 'pagebuf'.
 * param *vnode: the pointer to the vnode object
 * param offset: the arbitrary offset of that file (bytes offset)
 * param pagebuf: the buffer for storing the data you have read
 * return: number of bytes that have been read, or negative number for errors
 */
static int
s5fs_fillpage(vnode_t *vnode, off_t offset, void *pagebuf)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(pagebuf != NULL);
    
    int disk_number = 0;
    if ((disk_number = s5_seek_to_block(vnode, offset, 0)) < 0)
    {
        return disk_number;
    }
    if (disk_number == 0)
    {
        memset(pagebuf, 0, PAGE_SIZE);
        return 0;
    }
    
    /* If the disk_number is zero, ignore pagebuf */
    int ret = VNODE_TO_S5FS(vnode)->s5f_bdev->bd_ops->read_block(
              VNODE_TO_S5FS(vnode)->s5f_bdev, pagebuf, disk_number, 1);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
예제 #3
0
/*
 * if this offset is NOT within a sparse region of the file
 *     return 0;
 *
 * attempt to make the region containing this offset no longer
 * sparse
 *     - attempt to allocate a free block
 *     - if no free blocks available, return -ENOSPC
 *     - associate this block with the inode; alter the inode as
 *       appropriate
 *         - dirty the page containing this inode
 *
 * Much of this can be done with s5_seek_to_block()
 */
static int
s5fs_dirtypage(vnode_t *vnode, off_t offset)
{
    int blocknum = s5_seek_to_block(vnode, offset, 0);

    switch (blocknum){
        case -EFBIG:
        case -ENOSPC:
            return blocknum;
        default: 
            /* do nothing */;
    }

    KASSERT(blocknum >= 0 && "forgot to handle an error case");

    return (blocknum == 0) ? s5_seek_to_block(vnode, offset, 1) : 0;
}
예제 #4
0
/*
 * Like fillpage, but for writing.
 */
static int
s5fs_cleanpage(vnode_t *vnode, off_t offset, void *pagebuf)
{
    int blocknum = s5_seek_to_block(vnode, offset, 1);

    switch (blocknum){
        case -EFBIG:
        case -ENOSPC:
            return blocknum;
        default:
            /* do nothing */;
    }

    KASSERT(blocknum > 0 && "forgot to handle an error case");

    blockdev_t *bd = ((s5fs_t *) vnode->vn_fs->fs_i)->s5f_bdev;
    return bd->bd_ops->write_block(bd, (char *) pagebuf, blocknum, 1/*S5_BLOCK_SIZE*/);
}
예제 #5
0
/*
 * s5fs_cleanpage:
 * Write the contents of the page-aligned and page-sized
 * buffer pointed to by 'pagebuf' to the page of 'vnode'
 * containing 'offset'.
 * param *vnode: the pointer to the vnode object
 * param offset: the arbitrary offset of that file (bytes offset)
 * param pagebuf: the source buffer
 * return: number of bytes that have been written, or negative number for errors
 */
static int
s5fs_cleanpage(vnode_t *vnode, off_t offset, void *pagebuf)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(pagebuf != NULL);
    
    /* Alloc */
    int disk_number = 0;
    if ((disk_number = s5_seek_to_block(vnode, offset, 0)) < 0)
    {
        return disk_number;/* error */
    }
    /* If the disk_number is zero, ignore pagebuf */
    int ret = VNODE_TO_S5FS(vnode)->s5f_bdev->bd_ops->write_block(
              VNODE_TO_S5FS(vnode)->s5f_bdev, pagebuf, disk_number, 1);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
예제 #6
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * You'll probably want to use s5_seek_to_block and the device's
 * read_block function.
 */
static int
s5fs_fillpage(vnode_t *vnode, off_t offset, void *pagebuf)
{
    int blocknum = s5_seek_to_block(vnode, offset, 0);

    switch (blocknum){
        case -EFBIG:
        case -ENOSPC:
            return blocknum;
        default:
            /* do nothing */;
    }

    KASSERT(blocknum >= 0 && "forgot to handle an error case");

    if (blocknum == 0){
        bytedev_t *bd = bytedev_lookup(MEM_ZERO_DEVID);
        return bd->cd_ops->read(bd, 0, pagebuf, S5_BLOCK_SIZE);
    } else {
        blockdev_t *bd = ((s5fs_t *) vnode->vn_fs->fs_i)->s5f_bdev;
        return bd->bd_ops->read_block(bd, (char *) pagebuf, blocknum, 1/*S5_BLOCK_SIZE*/);
    }
}