Example #1
0
int kshell_ata_write(kshell_t *k, int argc, char **argv){
    if (argc != 3){
        dbg(DBG_DISK | DBG_TERM, "received wrong amount of arguments\n");
        kprintf(k, "Usage: <read_block> <string>\n");
        return -1;
    }

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int blocknum = toint(argv[1]);

    char *input_text = argv[2];
    char *data = (void *) page_alloc();

    if (data == NULL){
        kprintf(k, "not enough memory");
        return -1;
    }

    int i = 0;
    while (input_text[i] != NULL){
        data[i] = input_text[i];
        i++;
    }

    data[i] = '\0';

    int result = bd->bd_ops->write_block(bd, data, blocknum, 1);

    page_free((void *) data);

    return result;
}
Example #2
0
int kshell_ata_read(kshell_t *k, int argc, char **argv){
    if (argc != 3){
        dbg(DBG_DISK | DBG_TERM, "received wrong amount of arguments\n");
        kprintf(k, "Usage: <read_block> <num_blocks>\n");
        return -1;
    }

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int blocknum = toint(argv[1]);
    int count = toint(argv[2]);

    char *data = (char *) page_alloc_n(count);

    if (data == NULL){
        kprintf(k, "not enough memory");
        return -1;
    }

    int result = bd->bd_ops->read_block(bd, data, blocknum, count);

    char newline[2] = {'\n', '\0'};

    kprintf(k, data);
    kprintf(k, newline);

    page_free_n((void *) data, count);

    return result;
}
Example #3
0
static void test_large_block_reads(){
    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    int i;
    for (i = 1; i < 129; i++){
        char *readbuf = (char *) page_alloc_n(i);
        char *writebuf = (char *) page_alloc_n(i);

        int j;
        for (j = 0; j < (i * BLOCK_SIZE); j++){
            writebuf[j] = 'f';
        }

        int write_result = bd->bd_ops->write_block(bd, writebuf, 0, i);
        KASSERT(write_result == 0);

        int read_result = bd->bd_ops->read_block(bd, readbuf, 0, i);
        KASSERT(read_result == 0);

        int k;
        for (k = 0; k < (i * BLOCK_SIZE); k++){
            KASSERT(readbuf[k] == 'f');
        }

        page_free_n((void *) readbuf, i);
        page_free_n((void *) writebuf, i);
    }

    dbg(DBG_TESTPASS, "large read stress tests passed\n");
}
Example #4
0
void test_single_rw(){
    dbg(DBG_TEST | DBG_DISK, "testing reading and writing to disk\n");

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    KASSERT(bd != NULL);

    char *writebuf = (char *) page_alloc();
    char *readbuf = (char *) page_alloc();

    KASSERT(readbuf != NULL && writebuf != NULL && "not enough memory");

    unsigned int i;
    for (i = 0; i < BLOCK_SIZE; i++){
        writebuf[i] = 'o';
    }

    int block_to_write = 60;

    rw_args_t read_args = {bd, readbuf, block_to_write, 1};
    rw_args_t write_args = {bd, writebuf, block_to_write, 1};

    simple_write(write_args);
    simple_read(read_args);
 
    unsigned int j;
    for (j = 0; j < BLOCK_SIZE; j++){
        KASSERT(readbuf[j] == 'o');
    }

    page_free((void *) readbuf);
    page_free((void *) writebuf);

    dbg(DBG_TESTPASS, "all simple ata tests passed\n");
}
Example #5
0
/*
 * Read fs->fs_dev and set fs_op, fs_root, and fs_i.
 *
 * Point fs->fs_i to an s5fs_t*, and initialize it.  Be sure to
 * verify the superblock (using s5_check_super()).  Use vget() to get
 * the root vnode for fs_root.
 *
 * Return 0 on success, negative on failure.
 */
int
s5fs_mount(struct fs *fs)
{
        int num;
        blockdev_t *dev;
        s5fs_t *s5;
        pframe_t *vp;

        KASSERT(fs);

        if (sscanf(fs->fs_dev, "disk%d", &num) != 1) {
                return -EINVAL;
        }

        if (!(dev = blockdev_lookup(MKDEVID(1, num)))) {
                return -EINVAL;
        }

        /* allocate and initialize an s5fs_t: */
        s5 = (s5fs_t *)kmalloc(sizeof(s5fs_t));

        if (!s5)
                return -ENOMEM;

        /*     init s5f_disk: */
        s5->s5f_bdev  = dev;

        /*     init s5f_super: */
        pframe_get(S5FS_TO_VMOBJ(s5), S5_SUPER_BLOCK, &vp);

        KASSERT(vp);

        s5->s5f_super = (s5_super_t *)(vp->pf_addr);

        if (s5_check_super(s5->s5f_super)) {
                /* corrupt */
                kfree(s5);
                return -EINVAL;
        }

        pframe_pin(vp);

        /*     init s5f_mutex: */
        kmutex_init(&s5->s5f_mutex);

        /*     init s5f_fs: */
        s5->s5f_fs = fs;


        /* Init the members of fs that we (the fs-implementation) are
         * responsible for initializing: */
        fs->fs_i = s5;
        fs->fs_op = &s5fs_fsops;
        fs->fs_root = vget(fs, s5->s5f_super->s5s_root_inode);

        return 0;
}
Example #6
0
static void read_many_blocks(){
    dbg(DBG_TEST, "reading from LOTS of blocks, one at a time\n");

    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    char *writebuf = (char *) page_alloc();
    char *readbuf = (char *) page_alloc();

    KASSERT(writebuf != NULL && readbuf != NULL);

    unsigned int i;
    for (i = 0; i < BLOCK_SIZE; i++){
        writebuf[i] = 'z';
    }

    dbg(DBG_TEST, "reading from blocks before writing them\n");
    int j;
    for (j = 0; j < 1024; j++){
        int read_result = bd->bd_ops->read_block(bd, readbuf, j, 1);
        KASSERT(read_result == 0);
    }

    dbg(DBG_TEST, "writing to all the blocks\n");

    int k;
    for (k = 0; k < 1024; k++){
        int write_result = bd->bd_ops->write_block(bd, writebuf, k, 1);
        KASSERT(write_result == 0);
    }

    dbg(DBG_TEST, "reading from all the written-to blocks\n");
    int l;
    for (l = 0; l < 1024; l++){
        int read_result = bd->bd_ops->read_block(bd, readbuf, l, 1);
        KASSERT(read_result == 0);

        unsigned int m;
        for (m = 0; m < BLOCK_SIZE; m++){
            KASSERT(readbuf[m] == 'z');
        }
    }

    page_free((void *) writebuf);
    page_free((void *) readbuf);

    dbg(DBG_TESTPASS, "single-block stress tests passed\n");
}
Example #7
0
int
do_open(const char *filename, int oflags)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_open");*/
	if (oflags!=O_RDONLY && oflags!=O_WRONLY && oflags!=O_RDWR && oflags!=O_APPEND && oflags!= (O_RDONLY | O_CREAT) 
		&& oflags != (O_RDWR | O_CREAT) && oflags != (O_RDWR | O_APPEND))
	{
		return -EINVAL;
	}
	int fd = get_empty_fd(curproc);
	if( fd == -EMFILE){
		return -EMFILE;
	}
	file_t *f = fget(-1);
	if( f == NULL){
		return -ENOMEM;
	}
	curproc->p_files[fd] = f;
	/*Set file_t->f_mode to OR of FMODE_(READ|WRITE|APPEND) based on
         * oflags, which can be O_RDONLY, O_WRONLY or O_RDWR, possibly OR'd with
         * O_APPEND.
	*/
	/*FIXME check the logic below*/	
	if(oflags == O_RDONLY){
		f->f_mode = FMODE_READ;
	}else if(oflags == O_WRONLY){
		f->f_mode =  FMODE_WRITE;
	}else if(oflags == O_RDWR){
		f->f_mode = FMODE_READ | FMODE_WRITE;
	}else if(oflags == O_APPEND){
		f->f_mode = FMODE_WRITE | FMODE_APPEND;
	}else if(oflags == (O_RDONLY | O_CREAT)){
		f->f_mode = FMODE_READ;
	}else if(oflags == (O_RDWR | O_CREAT) ){
		f->f_mode = FMODE_READ | FMODE_WRITE;
	}else if(oflags == (O_RDWR | O_APPEND) ){
		f->f_mode = FMODE_READ | FMODE_WRITE | FMODE_APPEND;
	}

	vnode_t *pVnode;
	int s = open_namev(filename, oflags, &pVnode, NULL);
	if(s != 0){
		curproc->p_files[fd] = NULL;	
                fput(f);
		return s;
	}
        if(S_ISDIR(pVnode->vn_mode) && ((oflags & O_WRONLY) || (oflags & O_RDWR)) ){
		curproc->p_files[fd] = NULL;
		vput(pVnode);
                fput(f);
		return -EISDIR;
        }
	if(S_ISBLK(pVnode->vn_mode)){
	        if(!(pVnode->vn_bdev = blockdev_lookup(pVnode->vn_devid))){
			curproc->p_files[fd] = NULL;
			fput(f);
			vput(pVnode);
			return -ENXIO;
		}
	}
	if(S_ISCHR(pVnode->vn_mode)){
	        if(!(pVnode->vn_cdev = bytedev_lookup(pVnode->vn_devid))){
			curproc->p_files[fd] = NULL;
			fput(f);
			vput(pVnode);
			return -ENXIO;
		}
	}
	f->f_pos=0;
	f->f_vnode = pVnode;
        return fd;
}
Example #8
0
/*
 * s5fs_read_vnode:
 * s5fs_read_vnode will be passed a vnode_t*, which will have its vn_fs
 * and vn_vno fields initialized.
 * param *vnode: the pointer to the vnode object
 */
static void
s5fs_read_vnode(vnode_t *vnode)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(vnode->vn_fs != NULL);
    
    kmutex_lock(&vnode->vn_mutex);
    pframe_t* page = NULL;
    
    int ret = pframe_get(S5FS_TO_VMOBJ(FS_TO_S5FS(vnode->vn_fs)),
                         S5_INODE_BLOCK(vnode->vn_vno), &page);
    
    KASSERT(ret == 0);
    KASSERT(page != NULL);
    
    pframe_pin(page);
    s5_inode_t* inode = ((s5_inode_t*)page->pf_addr) +
                        S5_INODE_OFFSET(vnode->vn_vno);
    
    inode->s5_linkcount++;
    s5_dirty_inode(VNODE_TO_S5FS(vnode), inode);
    vnode->vn_i   = inode;
    vnode->vn_len = inode->s5_size;
    
    switch(inode->s5_type)
    {
        case S5_TYPE_DIR:
        {
            vnode->vn_mode  = S_IFDIR;
            vnode->vn_ops   = &s5fs_dir_vops;
            break;
        }
        case S5_TYPE_DATA:
        {
            vnode->vn_mode  = S_IFREG;
            vnode->vn_ops   = &s5fs_file_vops;
            break;
        }
        case S5_TYPE_CHR:
        {
            vnode->vn_mode  = S_IFCHR;
            vnode->vn_ops   = NULL;
            vnode->vn_devid = (devid_t)(inode->s5_indirect_block);
            vnode->vn_cdev  = bytedev_lookup(vnode->vn_devid);
            break;
        }
        case S5_TYPE_BLK:
        {
            vnode->vn_mode  = S_IFBLK;
            vnode->vn_ops   = NULL;
            vnode->vn_devid = (devid_t)(inode->s5_indirect_block);
            vnode->vn_bdev  = blockdev_lookup(vnode->vn_devid);
            break;
        }
        default:
        {
            panic("inode %d has unknown/invalid type %d!!\n",
                  (int)vnode->vn_vno, (int)inode->s5_type);
        }
    }
    
    kmutex_unlock(&vnode->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
}
Example #9
0
void test_multiple_threads(){
    dbg(DBG_TEST | DBG_DISK, "testing reading and writing to disk with multiple threads\n");
    blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0));

    KASSERT (bd != NULL);

    char *readbuf1 = (char *) page_alloc_n(BLOCKS_TO_READ);
    char *readbuf2 = (char *) page_alloc_n(BLOCKS_TO_READ);
    char *writebuf1 = (char *) page_alloc_n(BLOCKS_TO_WRITE);
    char *writebuf2 = (char *) page_alloc_n(BLOCKS_TO_WRITE);

    KASSERT(readbuf1 != NULL && 
            readbuf2 != NULL &&
            writebuf2 != NULL &&
            writebuf2 != NULL &&
            "not enough memory");

    unsigned int i;
    for (i = 0; i < (BLOCK_SIZE * BLOCKS_TO_WRITE); i++){
        writebuf1[i] = 'a';
        writebuf2[i] = 'b';
    }

    /* create and run procs and threads for writing */
    rw_args_t write_args_1 = {bd, writebuf1, BLOCKNUM_1, BLOCKS_TO_WRITE};
    rw_args_t write_args_2 = {bd, writebuf2, BLOCKNUM_2, BLOCKS_TO_WRITE};

    proc_t *wp1 = proc_create("ata_write_proc_1");
    proc_t *wp2 = proc_create("ata_write_proc_2");

    kthread_t *wt1 = kthread_create(wp1, write_func, 0, (void *) &write_args_1); 
    kthread_t *wt2 = kthread_create(wp2, write_func, 0, (void *) &write_args_2);

    sched_make_runnable(wt1);
    sched_make_runnable(wt2);

    int status;
    do_waitpid(wp1->p_pid, 0, &status);
    do_waitpid(wp2->p_pid, 0, &status);

    /* create and run procs and threads for reading */
    rw_args_t read_args_1 = {bd, readbuf1, BLOCKNUM_1, BLOCKS_TO_READ};
    rw_args_t read_args_2 = {bd, readbuf2, BLOCKNUM_2, BLOCKS_TO_READ};

    proc_t *rp1 = proc_create("ata_read_proc_1");
    proc_t *rp2 = proc_create("ata_read_proc_2");

    kthread_t *rt1 = kthread_create(rp1, read_func, 0, (void *) &read_args_1);
    kthread_t *rt2 = kthread_create(rp2, read_func, 0, (void *) &read_args_2);

    sched_make_runnable(rt1);
    sched_make_runnable(rt2);

    do_waitpid(rp1->p_pid, 0, &status);
    do_waitpid(rp2->p_pid, 0, &status);

    /* make sure that we wrote and read properly */
    unsigned int j;
    for (j = 0; j < BLOCK_SIZE * BLOCKS_TO_READ; j++){
        KASSERT(readbuf1[j] == 'a');
        KASSERT(readbuf2[j] == 'b');
    }

    page_free_n((void *) readbuf1, BLOCKS_TO_READ);
    page_free_n((void *) readbuf2, BLOCKS_TO_READ);
    page_free_n((void *) writebuf1, BLOCKS_TO_WRITE);
    page_free_n((void *) writebuf2, BLOCKS_TO_WRITE);

    dbg(DBG_TESTPASS, "All multi-threaded read/write tests passed\n");
}