Example #1
0
int
sys_close(int fd)
{
	struct sys_filemapping *mpg;
	struct process *proc;
	proc_filemapping *pmpg;
	int sys_index;

	mpg = resolvefd(fd);
	if (mpg==NULL)
		return -EBADF;

	lock_acquire(filetable_lock);
	mpg->refcnt--;

	proc = getcurprocess();

	/* should never fail seeing how we just resolved it */
	pmpg = (proc_filemapping *) array_getguy(proc->filetable, fd);

	sys_index = *pmpg;

	kfree(pmpg);
	array_setguy(proc->filetable, fd, NULL);

	if(mpg->refcnt>0)
	{
		lock_release(filetable_lock);
		return 0;
	}

	/* no more references to mapping */

	vfs_close(mpg->vn);
	
	kfree(mpg);

	if (sys_index < array_getnum(proc->filetable))
		array_setguy(proc->filetable, sys_index, NULL);

	lock_release(filetable_lock);
	return 0;
}
Example #2
0
int ft_set(struct filetable* ft, struct filedescriptor* fd, int fti) {
    if (fti >= ft_array_size(ft)) {
        return 1;
    }
    array_setguy(ft->filedescriptor, fti, fd);
    if (ft_get(ft, fti) == fd) {
        return 1;
    }
    return 0;
}
Example #3
0
/*
 * ft_remove()
 * This removes the file descriptor from the file table, it will add the file
 * descriptor id to the queue of availiable ids to use.
 */
int ft_remove(struct filetable* ft, int fti) {
    struct filedescriptor * fd = ft_get(ft, fti);
    if (fd != NULL) {
        //  q_addtail(ft->nextfiledescriptor, (void *) fd->fdn);
        int spl = splhigh();
        fd->numOwners--;
        if (fd->numOwners == 0) {
            vfs_close(fd->fdvnode);
            kfree(fd);
        }
        splx(spl);
        array_setguy(ft->filedescriptor, fti, NULL);
    }
    return 1;
}
Example #4
0
/*
 * ft_add()
 * This adds the file descriptor to the file table, it does by checking if there
 * is a free file descriptor in the queue, if not, it will add to the end of the
 * array. This will recover and reuse closed file descriptor ids.
 */
int ft_add(struct filetable* ft, struct filedescriptor* fd) {
    int fdn = 0;
    for (fdn = 0; fdn < ft_array_size(ft) && fdn < OPEN_MAX; fdn++) {
        if (ft_get(ft, fdn) == NULL) {
            array_setguy(ft->filedescriptor, fdn, fd);
            return fdn;
        }
    }
    if (fdn == OPEN_MAX) {
        return -1;
    }
    if (array_add(ft->filedescriptor, fd) != 0) { //if error (ENOMEM)
        return -1;
    }
    fd->numOwners++;
    assert(fdn != 0);
    return fdn;
}
Example #5
0
/*
 * as_fault: fault handling. Handle a fault on an address space, of
 * specified type, at specified address.
 *
 * Synchronization: none. We assume the address space is not shared,
 * so we don't lock it.
 */
int
as_fault(struct addrspace *as, int faulttype, vaddr_t va)
{
	struct vm_object *faultobj = NULL;
	struct lpage *lp;
	vaddr_t bot=0, top;
	int i, index, result;

	/* Find the vm_object concerned */
	for (i=0; i<array_getnum(as->as_objects); i++) {
		struct vm_object *vmo;

		vmo = array_getguy(as->as_objects, i);
		bot = vmo->vmo_base;
		top = bot + PAGE_SIZE*array_getnum(vmo->vmo_lpages);
		if (va >= bot && va < top) {
			faultobj = vmo;
			break;
		}
	}

	if (faultobj==NULL) {
		DEBUG(DB_VM, "vm_fault: EFAULT: va=0x%x\n", va);
		return EFAULT;
	}

	/* Now get the logical page */
	index = (va - bot) / PAGE_SIZE;
	lp = array_getguy(faultobj->vmo_lpages, index);

	if (lp == NULL) {
		/* zerofill page */
		result = lpage_zerofill(&lp);
		if (result) {
			kprintf("vm: zerofill fault at 0x%x failed\n", va);
			return result;
		}
		array_setguy(faultobj->vmo_lpages, index, lp);
	}
	
	return lpage_fault(lp, as, faulttype, va);
}