/* This tests is for the reader writer test, it reads a value, and
* checks to make sure that it is the same value that is expected.
*/
void *reader(int arg1, void *arg2) {
	kmutex_lock(&reader_mutex);
	kmutex_lock(&mutex);
	num_readers++;
	if(num_readers == 1)
	{
		kmutex_lock(&writer_mutex);
	}
	kmutex_unlock(&mutex);
	kmutex_unlock(&reader_mutex);

	sched_switch();

	dbg_print("reader_test: Expected to Read: %i, Did Read: %i\n", arg1, rwval);
	KASSERT(arg1 == rwval);

	kmutex_lock(&mutex);
	num_readers--;
	if(num_readers == 0)
	{
		kmutex_unlock(&writer_mutex);
	}
	kmutex_unlock(&mutex);

	return NULL;
}
示例#2
0
static void test_normal_locking(){
    dbg(DBG_TEST, "testing normal mutex behavior\n");

    kmutex_t m;
    kmutex_init(&m);

    proc_t *kmutex_proc = proc_create("kmutex_test_proc");
    kthread_t *kmutex_thread = kthread_create(kmutex_proc, lock_kmutex_func,
                                          NULL, (void *) &m);

    sched_make_runnable(kmutex_thread);

    kmutex_lock(&m);
    
    /* let kmutex_proc attempt to lock the mutex */
    yield();

    kmutex_unlock(&m);

    /* lock and unlock the mutex with nobody on it's wait queue */
    kmutex_lock(&m);
    kmutex_unlock(&m);

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

    dbg(DBG_TESTPASS, "normal kmutex tests passed!\n");
}
示例#3
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * When this function returns, the inode refcount on the parent should be
 * decremented (since ".." in the removed directory no longer references
 * it). Remember that the directory must be empty (except for "." and
 * "..").
 *
 * You probably want to use s5_find_dirent() and s5_remove_dirent().
 */
static int
s5fs_rmdir(vnode_t *parent, const char *name, size_t namelen)
{
    KASSERT(!(namelen == 1 && name[0] == '.'));
    KASSERT(!(namelen == 2 && name[0] == '.' && name[1] == '.'));
    KASSERT(parent->vn_ops->rmdir != NULL);

    kmutex_lock(&parent->vn_mutex);

    int ino = s5_find_dirent(parent, name, namelen);

    /* we check in do_rmdir to make sure the directory exists */
    KASSERT(ino != -ENOENT);

    if (ino < 0){
        dbg(DBG_S5FS, "error finding child dir to delete\n");
        kmutex_unlock(&parent->vn_mutex);
        return ino;
    }

    vnode_t *child = vget(VNODE_TO_S5FS(parent)->s5f_fs, ino);
    kmutex_lock(&child->vn_mutex);

    int dot_lookup_res = s5_find_dirent(child, ".", 1);
    int dotdot_lookup_res = s5_find_dirent(child, "..", 2);

    KASSERT(dot_lookup_res != -ENOENT && dotdot_lookup_res != -ENOENT);

    if (dot_lookup_res < 0 || dotdot_lookup_res < 0){
        dbg(DBG_S5FS, "error reading dirents of directory to delete\n");
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&parent->vn_mutex);
        return (dot_lookup_res < 0) ? dot_lookup_res : dotdot_lookup_res;
    }

    KASSERT((unsigned) child->vn_len >= 2 * sizeof(s5_dirent_t));

    if ((unsigned) child->vn_len > 2 * sizeof(s5_dirent_t)){
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&parent->vn_mutex);
        return -ENOTEMPTY;
    }

    vput(child);

    VNODE_TO_S5INODE(parent)->s5_linkcount--;
    s5_dirty_inode(VNODE_TO_S5FS(parent), VNODE_TO_S5INODE(parent));

    kmutex_unlock(&child->vn_mutex);
    kmutex_unlock(&parent->vn_mutex);
    return s5_remove_dirent(parent, name, namelen);
}
示例#4
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * This function is similar to s5fs_create, but it creates a special
 * file specified by 'devid'.
 *
 * You probably want to use s5_alloc_inode, s5_link(), vget(), and vput().
 */
static int
s5fs_mknod(vnode_t *dir, const char *name, size_t namelen, int mode, devid_t devid)
{
    KASSERT(namelen < NAME_LEN);

    kmutex_lock(&dir->vn_mutex);

    fs_t *fs = VNODE_TO_S5FS(dir)->s5f_fs;

    int ino;

    if (S_ISCHR(mode)){
        ino = s5_alloc_inode(fs, S5_TYPE_CHR, devid);
    } else if (S_ISBLK(mode)){
        ino = s5_alloc_inode(fs, S5_TYPE_BLK, devid);
    } else {
        panic("invalid mode");
    }

    if (ino < 0){
        dbg(DBG_S5FS, "unable to alloc a new inode\n");
        kmutex_unlock(&dir->vn_mutex);
        return ino;
    }
    
    vnode_t *child = vget(fs, ino);

    kmutex_lock(&child->vn_mutex);

    /* make sure the state of the new vnode is correct */
    assert_new_vnode_state(child, ino, S_ISCHR(mode) ? S5_TYPE_CHR : S5_TYPE_BLK,
            devid);
    
    int link_res = s5_link(dir, child, name, namelen);

    if (link_res < 0){
        dbg(DBG_S5FS, "error creating entry for new directory in parent dir\n");
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&dir->vn_mutex);
        /*s5_free_inode(child);*/
        return link_res;
    }

    vput(child);

    KASSERT(child->vn_refcount == 0);
    KASSERT(VNODE_TO_S5INODE(child)->s5_linkcount == 1);

    kmutex_unlock(&child->vn_mutex);
    kmutex_unlock(&dir->vn_mutex);
    return 0;
}
/* This test writes to the value and makes sure that there are no race conditions */
void *writer(int arg1, void *arg2) {
	kmutex_lock(&reader_mutex);
	kmutex_lock(&writer_mutex);

	sched_switch();

	rwval++;

	kmutex_unlock(&writer_mutex);
	kmutex_unlock(&reader_mutex);
	return NULL;
}
示例#6
0
static void test_locking_and_cancelling(){
    dbg(DBG_TEST, "testing kmutex behavior with cancellation\n");

    kmutex_t m;
    kmutex_init(&m);

    proc_t *kmutex_proc = proc_create("kmutex_sleep_test_proc");
    kthread_t *kmutex_thread =  kthread_create(kmutex_proc, 
                                        cancellable_lock_kmutex,
                                        NULL, 
                                        (void *) &m);

    sched_make_runnable(kmutex_thread);

    kmutex_lock(&m);

    /* let kmutex_proc attempt to lock the mutex */
    yield();

    kthread_cancel(kmutex_thread, 0);

    kmutex_unlock(&m);

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

    dbg(DBG_TESTPASS, "kmutex cancellation tests passed!\n");
}
示例#7
0
static void *
remove_my_node(int arg1, void *arg2) {
	int counter = 10;
	dbg(DBG_TEST, "Invoke remove_mynode\n");

	int rand_number, i=0;	

	while (counter > 0) {
		check_sleep("remove");

		kmutex_lock(&mynode.my_mutex);

		check_sleep("remove");
		
		if (mynode.length > 0) {
			mynode.length--;
			counter--;
		}

		dbg(DBG_TEST, "Remove node: %d\n", mynode.length);		
		kmutex_unlock(&mynode.my_mutex);
	}
	
	return NULL;
}
示例#8
0
static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
{
	struct smscore_registry_entry_t *entry;
	struct list_head *next;

	kmutex_lock(&g_smscore_registrylock);
	for (next = g_smscore_registry.next; next != &g_smscore_registry; next
			= next->next) {
		entry = (struct smscore_registry_entry_t *) next;
		if (!strcmp(entry->devpath, devpath)) {
			kmutex_unlock(&g_smscore_registrylock);
			return entry;
		}
	}
	entry = kmalloc(
			sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
	if (entry) {
		entry->mode = default_mode;
		if(strlen(devpath) >= 32)
		{
			sms_err(" strlen(devpath) >= 32\n");
			return NULL;
		}
		strcpy(entry->devpath, devpath);
		list_add(&entry->entry, &g_smscore_registry);
	} else
		sms_err("failed to create smscore_registry.");
	kmutex_unlock(&g_smscore_registrylock);
	return entry;
}
示例#9
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * Here you need to use s5_read_file() to read a s5_dirent_t from a directory
 * and copy that data into the given dirent. The value of d_off is dependent on
 * your implementation and may or may not b e necessary.  Finally, return the
 * number of bytes read.
 */
static int s5fs_readdir(vnode_t *vnode, off_t offset, struct dirent *d)
{
    static int s5_dirent_size = sizeof(s5_dirent_t);

    KASSERT(vnode != NULL);
    KASSERT(d != NULL);
    KASSERT(offset <= vnode->vn_len);

    if (offset == vnode->vn_len){
        return 0;
    }    

    kmutex_lock(&vnode->vn_mutex);

    s5_dirent_t s5d;

    int read_res = s5_read_file(vnode, offset, (char *) &s5d, s5_dirent_size);

    KASSERT(read_res <= s5_dirent_size && "read too much!");

    if (read_res == s5_dirent_size){
        d->d_ino = s5d.s5d_inode;
        d->d_off = offset + s5_dirent_size;
        strcpy(d->d_name, s5d.s5d_name);
    } else {
        KASSERT(read_res < 0 && "bad offset or incomplete read");
        dbg(DBG_S5FS, "error reading dirent from file\n");
    }

    kmutex_unlock(&vnode->vn_mutex);
    return read_res;
}
示例#10
0
/*
 * s5fs_lookup:
 * s5fs_lookup sets *result to the vnode in dir with the specified name.
 * param *base: the vnode object of the base directory
 * param *name: name string
 * param namelen: the length of the name
 * param **result: *result points to the vnode in dir with the specified name
 * return: 0 on success; negative number on a variety of errors
 */
int
s5fs_lookup(vnode_t *base, const char *name, size_t namelen, vnode_t **result)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(base != NULL);
    KASSERT(name != NULL);
    KASSERT(namelen <= S5_NAME_LEN-1);
    
    kmutex_lock(&base->vn_mutex);
    
    int inode_number = 0;
    if ((inode_number = s5_find_dirent(base, name, namelen)) < 0)
    {
        kmutex_unlock(&base->vn_mutex);
        return inode_number;
    }
    /* May block here */
    /* No modification, no need to lock */
    *result = vget(base->vn_fs, inode_number);
    
    kmutex_unlock(&base->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
    return 0;
}
示例#11
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * When this function returns, the inode refcount of the linked file
 * should be incremented.
 *
 * You probably want to use s5_link().
 */
static int
s5fs_link(vnode_t *child, vnode_t *parent, const char *name, size_t namelen)
{
    KASSERT(parent->vn_ops->mkdir != NULL);
    KASSERT(child->vn_ops->mkdir == NULL);

    kmutex_lock(&parent->vn_mutex);
    kmutex_lock(&child->vn_mutex);

    int ret = s5_link(parent, child, name, namelen);

    kmutex_unlock(&child->vn_mutex);
    kmutex_unlock(&parent->vn_mutex);

    return ret;
}
void smsnet_onremove(void *context)
{
	kmutex_lock(&g_smsnet_clientslock);

	smsnet_unregister_client((struct smsnet_client_t *)context);

	kmutex_unlock(&g_smsnet_clientslock);
}
示例#13
0
/* Simply call s5_write_file. */
static int
s5fs_write(vnode_t *vnode, off_t offset, const void *buf, size_t len)
{
    kmutex_lock(&vnode->vn_mutex);
    int ret = s5_write_file(vnode, offset, buf, len);
    kmutex_unlock(&vnode->vn_mutex);
    return ret;
}
示例#14
0
/* This function is deceptivly simple, just return the vnode's
 * mmobj_t through the ret variable. Remember to watch the
 * refcount.
 *
 * Don't worry about this until VM.
 */
static int
s5fs_mmap(vnode_t *file, vmarea_t *vma, mmobj_t **ret)
{
    kmutex_lock(&file->vn_mutex);
    *ret = &file->vn_mmobj;
    kmutex_unlock(&file->vn_mutex);
    return 0;
}
示例#15
0
static void * lock_kmutex_func(int arg1, void *arg2){

    kmutex_t *m = (kmutex_t *) arg2;

    kmutex_lock(m);
    kmutex_unlock(m);

    return NULL;
}
示例#16
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * When this function returns, the inode refcount of the file should be 2
 * and the vnode refcount should be 1.
 *
 * You probably want to use s5_alloc_inode(), s5_link(), and vget().
 */
static int
s5fs_create(vnode_t *dir, const char *name, size_t namelen, vnode_t **result)
{
    KASSERT(namelen < NAME_LEN);

    kmutex_lock(&dir->vn_mutex);

    fs_t *fs = VNODE_TO_S5FS(dir)->s5f_fs;

    int ino = s5_alloc_inode(fs, S5_TYPE_DATA, NULL);

    if (ino < 0){
        dbg(DBG_S5FS, "unable to alloc a new inode\n");
        kmutex_unlock(&dir->vn_mutex);
        return ino;
    }

    vnode_t *child = vget(fs, ino);

    kmutex_lock(&child->vn_mutex);

    /* make sure the state of the new vnode is correct */
    assert_new_vnode_state(child, ino, S5_TYPE_DATA, 0);
    
    int link_res = s5_link(dir, child, name, namelen);

    if (link_res < 0){
        dbg(DBG_S5FS, "error creating entry for new directory in parent dir\n");
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&dir->vn_mutex);
        /*s5_free_inode(child);*/
        return link_res;
    }

    KASSERT(child->vn_refcount == 1);
    KASSERT(VNODE_TO_S5INODE(child)->s5_linkcount == 2);

    *result = child;

    kmutex_unlock(&child->vn_mutex);
    kmutex_unlock(&dir->vn_mutex);
    return 0;
}
示例#17
0
文件: main.c 项目: ianhom/klite-demo
void debug(const char* fmt, ...)
{
	va_list va;
	kmutex_lock(debug_mutex);
	va_start(va,fmt);
	vsnprintf(debug_buff,MAX_DEBUG_LEN,fmt,va);
	va_end(va);
	uart_write(1,debug_buff,strlen(debug_buff));
	kmutex_unlock(debug_mutex);
}
示例#18
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * When this function returns, the inode refcount of the unlinked file
 * should be decremented.
 *
 * You probably want to use s5_remove_dirent().
 */
static int
s5fs_unlink(vnode_t *dir, const char *name, size_t namelen)
{
    KASSERT(dir->vn_ops->mkdir != NULL);

    kmutex_lock(&dir->vn_mutex);
    int ret = s5_remove_dirent(dir, name, namelen);
    kmutex_unlock(&dir->vn_mutex);
    return ret;
}
示例#19
0
void smsdvb_unregister(void)
{
	smscore_unregister_hotplug(smsdvb_hotplug);

	kmutex_lock(&g_smsdvb_clientslock);

	while (!list_empty(&g_smsdvb_clients))
	       smsdvb_unregister_client(
			(struct smsdvb_client_t *) g_smsdvb_clients.next);

	kmutex_unlock(&g_smsdvb_clientslock);
}
示例#20
0
static void __exit smsdvb_module_exit(void)
{
	smscore_unregister_hotplug(smsdvb_hotplug);

	kmutex_lock(&g_smsdvb_clientslock);

	while (!list_empty(&g_smsdvb_clients))
		smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next);

	smsdvb_debugfs_unregister();

	kmutex_unlock(&g_smsdvb_clientslock);
}
示例#21
0
/**
 * poll for data availability
 *
 * @param file File structure.
 * @param wait kernel polling table.
 *
 * @return (POLLIN | POLLRDNORM) flags if read data is available.
 *          POLLNVAL flag if wait_queue was cancelled.
 *	    <0 on error.
 */
static unsigned int smschar_poll(struct file *file,
				 struct poll_table_struct *wait)
{
	struct smschar_device_t *dev;
	int events = 0;

	if (file == NULL) {
		sms_err("file is NULL");
		return EINVAL;
	}

	dev = file->private_data;
	if (dev == NULL) {
		sms_err("dev is NULL");
		return -EINVAL;
	}

	if (dev->cancel_waitq) {
		/*sms_debug("returning POLLNVAL");*/
		events |= POLLNVAL;
		return events;
	}

	/*
	 * critical section, protect access to kernel poll
	 * table structure
	 */
	kmutex_lock(&g_smschar_pollwait_lock);

	/*
 	 * make the system call to wait to wait_queue wakeup if there is
	 * no data
	 * cancel_waitq is checked again to prevenet reace condition (wait
	 * to cancalled wait_queue)
	 */
	if (list_empty(&dev->pending_data) && (!dev->cancel_waitq)) {
		poll_wait(file, &dev->waitq, wait);
	}

	/*
	 * pending data, raise relevant flags
	 */
	if (!list_empty(&dev->pending_data)) {
		events |= (POLLIN | POLLRDNORM);
	}
	kmutex_unlock(&g_smschar_pollwait_lock);

	return events;
}
示例#22
0
/*
 * s5fs_link:
 * s5fs_link sets up a hard link. it links oldvnode into dir with the
 * specified name.
 * param *src:
 * param *dir:
 * param *name: name string
 * param namelen: the length of the name string
 * return: 0 on success; negative number on a variety of errors
 */
static int
s5fs_link(vnode_t *src, vnode_t *dir, const char *name, size_t namelen)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(src != NULL);
    KASSERT(dir != NULL);
    KASSERT(name != NULL);
    KASSERT(namelen <= S5_NAME_LEN-1);
    KASSERT(src->vn_fs == dir->vn_fs);
    
    vnode_t* vn = NULL;
    /* Non exist */
    KASSERT(s5fs_lookup(dir, name, namelen, &vn) < 0);
    
    kmutex_lock(&dir->vn_mutex);
    kmutex_lock(&src->vn_mutex);
    
    s5_inode_t* inode = (s5_inode_t*)src->vn_i;
    
    int original_link = inode->s5_linkcount;
    
    KASSERT(inode != NULL);
    
    int ret = s5_link(dir, src, name, namelen);
    
    /* Check increment */
    KASSERT(original_link + 1 == inode->s5_linkcount);
    
    kmutex_unlock(&src->vn_mutex);
    kmutex_unlock(&dir->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
示例#23
0
文件: tests.c 项目: makellos/assign2
/*
 * A Thread function that exhibits a race condition on the race global being
 * removed by a mutex.  It loads increments and stores race, context switching
 * between each line of C after acquiring mutex.  The mutex acquire cannot
 * be cancelled.
 */
void *mutex_uncancellable_test(int arg1, void *arg2) {
    int local;

    kmutex_lock(&mutex); 
    sched_switch();
    local = race;
    sched_switch();
    local++;
    sched_switch();
    race = local;
    sched_switch();
    kmutex_unlock(&mutex);
    do_exit(race);
    return NULL;
}
示例#24
0
/*
 * s5fs_write:
 * Simply call s5_write_file; should be in critical section
 * param *vnode: the pointer to the vnode object
 * param offset: the offset in the file where you want to write
 * param *buf: the source buffer
 * param len: the length of the buffer
 * return: just return the result of s5_write_file
 */
static int
s5fs_write(vnode_t *vnode, off_t offset, const void *buf, size_t len)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(buf != NULL);
    int ret = 0;
    kmutex_lock(&vnode->vn_mutex);
    ret = s5_write_file(vnode, offset, buf, len);
    kmutex_unlock(&vnode->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
示例#25
0
/*
 * Read a maximum of len bytes from the line discipline into buf. If
 * the buffer is empty, sleep until some characters appear. This might
 * be a long wait, so it's best to let the thread be cancellable.
 *
 * Then, read from the head of the buffer up to the tail, stopping at
 * len bytes or a newline character, and leaving the buffer partially
 * full if necessary. Return the number of bytes you read into the
 * buf.

 * In this function, you will be accessing the input buffer, which
 * could be modified by other threads. Make sure to make the
 * appropriate calls to ensure that no one else will modify the input
 * buffer when we are not expecting it.
 *
 * Remember to handle newline characters and CTRL-D, or ASCII 0x04,
 * properly.
 */
int
n_tty_read(tty_ldisc_t *ldisc, void *buf, int len)
{
        /* DRIVERS {{{ */
        int i;
        char *cbuf = (char *)buf;
        n_tty_t *ntty;

        KASSERT(TTY_BUF_SIZE < PAGE_SIZE);
        KASSERT(NULL != ldisc);

        ntty = ldisc_to_ntty(ldisc);

        N_TTY_ASSERT_VALID(ntty);
        KASSERT(NULL != buf);
        KASSERT(len >= 0);

        kmutex_lock(&ntty->ntty_rlock);

        if (n_tty_ckdbuf_empty(ntty)) {
                dprintf("Cooked buffer is empty. Sleeping\n");

                if (sched_cancellable_sleep_on(&ntty->ntty_rwaitq) == -EINTR) {
                        dprintf("Sleep cancelled. Returning -EINTR\n");
                        kmutex_unlock(&ntty->ntty_rlock);
                        return -EINTR;
                }
                dprintf("Woken up from sleep\n");
        }

        for (i = 0; i < len && !n_tty_ckdbuf_empty(ntty); ++i) {
                cbuf[i] = n_tty_ckdbuf_dequeue(ntty);
                if (cbuf[i] == LF) {
                        ++i;
                        break;
                } else if (cbuf[i] == EOT) {
                        break;
                }
        }

        kmutex_unlock(&ntty->ntty_rlock);

        return i;
        /* DRIVERS }}} */
        return 0;
}
示例#26
0
/*
 * s5fs_create:
 * s5fs_create is called by open_namev(). it should vget() a new vnode,
 * and create an entry for this vnode in 'dir' of the specified name.
 * param *dir:
 * param name: the name string
 * param namelen: the length of the name
 * param **result: pointer to the address of the result vnode
 * return: 0 on success; negative number on a variety of errors
 */
static int
s5fs_create(vnode_t *dir, const char *name, size_t namelen, vnode_t **result)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(dir != NULL);
    KASSERT(name != NULL);
    KASSERT(namelen <= NAME_LEN-1);
    
    vnode_t* vn = NULL;
    /* Must be non-exist */
    KASSERT(0 != s5fs_lookup(dir, name, namelen, result));
    /* Lock base */
    kmutex_lock(&dir->vn_mutex);
    int ino;
    if ((ino = s5_alloc_inode(dir->vn_fs, S5_TYPE_DATA, 0)) < 0)
    {
        /* Unsuccessfull*/
        kmutex_unlock(&dir->vn_mutex);
        return ino;
    }
    
    /* May block here */
    vn = vget(dir->vn_fs, (ino_t)ino);
    KASSERT(vn->vn_vno == (ino_t)ino);
    KASSERT(vn != NULL);

    int ret = 0;
    if ((ret = s5_link(dir, vn, name, namelen)) < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&dir->vn_mutex);
        return ret;
    }
    
    KASSERT(VNODE_TO_S5INODE(vn)->s5_linkcount == 2);
    KASSERT(vn->vn_refcount == 1);
    *result = vn;
    kmutex_unlock(&dir->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
    
    return 0;
}
void smsnet_unregister(void)
{
	if (g_smsnet_device) {
		unregister_netdev(g_smsnet_device);
		free_netdev(g_smsnet_device);

		g_smsnet_device = NULL;
	}

	smscore_unregister_hotplug(smsnet_hotplug);

	kmutex_lock(&g_smsnet_clientslock);

	while (!list_empty(&g_smsnet_clients))
		smsnet_unregister_client((struct smsnet_client_t *)
					 g_smsnet_clients.next);

	kmutex_unlock(&g_smsnet_clientslock);

	sms_info("exit");
}
示例#28
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * You probably want to use s5_find_dirent() and vget().
 */
int
s5fs_lookup(vnode_t *base, const char *name, size_t namelen, vnode_t **result)
{
    kmutex_lock(&base->vn_mutex);
    int ino = s5_find_dirent(base, name, namelen);

    if (ino == -ENOENT){
        kmutex_unlock(&base->vn_mutex);
        return -ENOENT;
    }

    KASSERT(ino >= 0 && "forgot an error case\n");

    vnode_t *child = vget(VNODE_TO_S5FS(base)->s5f_fs, ino);

    KASSERT(child != NULL);

    *result = child;

    kmutex_unlock(&base->vn_mutex);
    return 0;
}
示例#29
0
/*
 * s5fs_delete_vnode:
 * s5fs_delete_vnode is called by vput when the
 * specified vnode_t no longer needs to exist
 * param *vnode: the pointer to the vnode object
 */
static void
s5fs_delete_vnode(vnode_t *vnode)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(vnode->vn_fs != NULL);
    
    /* Lock */
    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);
    
    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);
    
    KASSERT(VNODE_TO_S5INODE(vnode) == inode);
    KASSERT(inode->s5_linkcount >= 0);
    
    if (inode->s5_linkcount== 0)
    {
        s5_free_inode(vnode);
    }
    
    pframe_unpin(page);
    
    /* Unlock */
    kmutex_unlock(&vnode->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
}
示例#30
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * Don't worry if you don't know what some of the fields in struct stat
 * mean. The ones you should be sure to set are st_mode, st_ino,
 * st_nlink, st_size, st_blksize, and st_blocks.
 *
 * You probably want to use s5_inode_blocks().
 */
static int
s5fs_stat(vnode_t *vnode, struct stat *ss)
{
    kmutex_lock(&vnode->vn_mutex);
    int allocated_blocks = s5_inode_blocks(vnode);
    s5_inode_t *inode = VNODE_TO_S5INODE(vnode);

    if (allocated_blocks < 0){
        dbg(DBG_S5FS, "error calculating number of allocated blocks\n");
        kmutex_unlock(&vnode->vn_mutex);
        return allocated_blocks;
    }

    ss->st_mode =vnode->vn_mode;
    ss->st_ino = inode->s5_number;
    ss->st_nlink = inode->s5_linkcount;
    ss->st_size = vnode->vn_len;
    ss->st_blksize = BLOCK_SIZE;
    ss->st_blocks = allocated_blocks;

    kmutex_unlock(&vnode->vn_mutex);
    return 0;
}