Exemplo n.º 1
0
static OSKIT_COMDECL filesystem_getroot(oskit_filesystem_t *f,
				       struct oskit_dir **out_dir)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    oskit_dir_t *d;
    struct proc *p;
    oskit_error_t ferror;
    struct vnode *vp;
    int error;

    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;
    
    error = VFS_ROOT(fs->mp, &vp);
    if (error)
    {
	prfree(p);
	return errno_to_oskit_error(error);
    }
    
    error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
    if (error)
    {
	vput(vp);
	prfree(p);
	return errno_to_oskit_error(error);
    }
    
    d = (oskit_dir_t *) hashtab_search(vptab, (hashtab_key_t) vp);
    if (d)
    {
	oskit_dir_addref(d);
    }
    else
    {
	d = (oskit_dir_t *) gfile_create(fs,vp);
	if (!d)
	{
	    vput(vp);
	    prfree(p);
	    return OSKIT_ENOMEM;
	}
    }

    vput(vp);
    prfree(p);
    *out_dir = d;
    return 0;    
}
Exemplo n.º 2
0
static OSKIT_COMDECL filesystem_sync(oskit_filesystem_t *f,
				    oskit_bool_t wait)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    struct mount *mp;
    struct proc *p;
    oskit_error_t ferror;
    int error, asyncflag;

    
    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;

    mp = fs->mp;
    error = 0;
    if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
	!vfs_busy(mp)) {
	asyncflag = mp->mnt_flag & MNT_ASYNC;
	mp->mnt_flag &= ~MNT_ASYNC;
	error = VFS_SYNC(mp, wait ? MNT_WAIT : MNT_NOWAIT, p->p_ucred, p);
	if (asyncflag)
		mp->mnt_flag |= MNT_ASYNC;
	vfs_unbusy(mp);
    }
    prfree(p);
    if (error)
	    return errno_to_oskit_error(error);	

    return 0;
}
Exemplo n.º 3
0
static OSKIT_COMDECL_U filesystem_release(oskit_filesystem_t *f)
{
    struct gfilesystem *fs;
    struct proc *p;
    dev_t dev;
    int rc;
    unsigned newcount;
    
    fs = (struct gfilesystem*)f; 
    if (fs == NULL)
	    panic("%s:%d: null filesystem", __FILE__, __LINE__);
    if (fs->count == 0)
	    panic("%s:%d: bad count", __FILE__, __LINE__);    

    newcount = --fs->count;
    if (newcount == 0)
    {
	rc = getproc(&p);
	assert(rc == 0);
	if (fs->mp)
	{
	    dev = ((struct ufsmount *)fs->mp->mnt_data)->um_dev;
	    rc = dounmount(fs->mp, MNT_FORCE, p);
	    assert(rc == 0);
	    oskit_blkio_release((oskit_blkio_t *)dev);
	}
	prfree(p);
	free(fs,M_TEMP);
    }

    return newcount;
}
Exemplo n.º 4
0
static OSKIT_COMDECL filesystem_unmount(oskit_filesystem_t *f)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    struct mount *mp;
    dev_t dev;
    struct proc *p;
    oskit_error_t ferror;
    int error;

    
    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;

    mp = fs->mp;

    /*
     * Only root, or the user that did the original mount is
     * permitted to forcibly unmount it.
     */
    if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
	(error = suser(p->p_ucred, 0))) 
    {
	prfree(p);
	return errno_to_oskit_error(error);
    }

    /* Get the blkio "pointed" to by the dev_t so we can release it below. */
    dev = ((struct ufsmount *)mp->mnt_data)->um_dev;

    error = dounmount(fs->mp, MNT_FORCE, p);
    fs->mp = 0;
    prfree(p);
    oskit_blkio_release((oskit_blkio_t *)dev);
    if (error)
	    return errno_to_oskit_error(error);	

    return 0;    
}
Exemplo n.º 5
0
static OSKIT_COMDECL filesystem_statfs(oskit_filesystem_t *f,
				      oskit_statfs_t *out_stats)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    struct statfs *sp;
    struct mount *mp;
    struct proc *p;
    oskit_error_t ferror;
    int error;

    
    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;
    
    mp = fs->mp;
    sp = &mp->mnt_stat;
    error = VFS_STATFS(fs->mp, sp, p);
    prfree(p);
    if (error)
	    return errno_to_oskit_error(error);

    sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;    

    out_stats->flag = 0;
    if (sp->f_flags & MNT_RDONLY)
	    out_stats->flag |= OSKIT_FS_RDONLY;
    if (sp->f_flags & MNT_NOEXEC)
	    out_stats->flag |= OSKIT_FS_NOEXEC;
    if (sp->f_flags & MNT_NOSUID)
	    out_stats->flag |= OSKIT_FS_NOSUID;
    if (sp->f_flags & MNT_NODEV)
	    out_stats->flag |= OSKIT_FS_NODEV;
    
    out_stats->bsize = sp->f_bsize;
    out_stats->frsize = sp->f_bsize;
    out_stats->blocks = sp->f_blocks;
    out_stats->bfree = sp->f_bfree;
    out_stats->bavail = sp->f_bavail;
    out_stats->files = sp->f_files;
    out_stats->ffree = sp->f_ffree;
    out_stats->favail = sp->f_ffree;
    out_stats->fsid = sp->f_fsid.val[0]; /* device number */
    out_stats->namemax = NAME_MAX;
    
    return 0;
}
Exemplo n.º 6
0
/*
 * Remove zombie children from the process table.
 */
void
freeproc(proc_t *p)
{
	proc_t *q;
	task_t *tk;

	ASSERT(p->p_stat == SZOMB);
	ASSERT(p->p_tlist == NULL);
	ASSERT(MUTEX_HELD(&pidlock));

	sigdelq(p, NULL, 0);
	if (p->p_killsqp) {
		siginfofree(p->p_killsqp);
		p->p_killsqp = NULL;
	}

	prfree(p);	/* inform /proc */

	/*
	 * Don't free the init processes.
	 * Other dying processes will access it.
	 */
	if (p == proc_init)
		return;


	/*
	 * We wait until now to free the cred structure because a
	 * zombie process's credentials may be examined by /proc.
	 * No cred locking needed because there are no threads at this point.
	 */
	upcount_dec(crgetruid(p->p_cred), crgetzoneid(p->p_cred));
	crfree(p->p_cred);
	if (p->p_corefile != NULL) {
		corectl_path_rele(p->p_corefile);
		p->p_corefile = NULL;
	}
	if (p->p_content != NULL) {
		corectl_content_rele(p->p_content);
		p->p_content = NULL;
	}

	if (p->p_nextofkin && !((p->p_nextofkin->p_flag & SNOWAIT) ||
	    (PTOU(p->p_nextofkin)->u_signal[SIGCLD - 1] == SIG_IGN))) {
		/*
		 * This should still do the right thing since p_utime/stime
		 * get set to the correct value on process exit, so it
		 * should get properly updated
		 */
		p->p_nextofkin->p_cutime += p->p_utime;
		p->p_nextofkin->p_cstime += p->p_stime;

		p->p_nextofkin->p_cacct[LMS_USER] += p->p_acct[LMS_USER];
		p->p_nextofkin->p_cacct[LMS_SYSTEM] += p->p_acct[LMS_SYSTEM];
		p->p_nextofkin->p_cacct[LMS_TRAP] += p->p_acct[LMS_TRAP];
		p->p_nextofkin->p_cacct[LMS_TFAULT] += p->p_acct[LMS_TFAULT];
		p->p_nextofkin->p_cacct[LMS_DFAULT] += p->p_acct[LMS_DFAULT];
		p->p_nextofkin->p_cacct[LMS_KFAULT] += p->p_acct[LMS_KFAULT];
		p->p_nextofkin->p_cacct[LMS_USER_LOCK]
		    += p->p_acct[LMS_USER_LOCK];
		p->p_nextofkin->p_cacct[LMS_SLEEP] += p->p_acct[LMS_SLEEP];
		p->p_nextofkin->p_cacct[LMS_WAIT_CPU]
		    += p->p_acct[LMS_WAIT_CPU];
		p->p_nextofkin->p_cacct[LMS_STOPPED] += p->p_acct[LMS_STOPPED];

		p->p_nextofkin->p_cru.minflt	+= p->p_ru.minflt;
		p->p_nextofkin->p_cru.majflt	+= p->p_ru.majflt;
		p->p_nextofkin->p_cru.nswap	+= p->p_ru.nswap;
		p->p_nextofkin->p_cru.inblock	+= p->p_ru.inblock;
		p->p_nextofkin->p_cru.oublock	+= p->p_ru.oublock;
		p->p_nextofkin->p_cru.msgsnd	+= p->p_ru.msgsnd;
		p->p_nextofkin->p_cru.msgrcv	+= p->p_ru.msgrcv;
		p->p_nextofkin->p_cru.nsignals	+= p->p_ru.nsignals;
		p->p_nextofkin->p_cru.nvcsw	+= p->p_ru.nvcsw;
		p->p_nextofkin->p_cru.nivcsw	+= p->p_ru.nivcsw;
		p->p_nextofkin->p_cru.sysc	+= p->p_ru.sysc;
		p->p_nextofkin->p_cru.ioch	+= p->p_ru.ioch;

	}

	q = p->p_nextofkin;
	if (q && q->p_orphan == p)
		q->p_orphan = p->p_nextorph;
	else if (q) {
		for (q = q->p_orphan; q; q = q->p_nextorph)
			if (q->p_nextorph == p)
				break;
		ASSERT(q && q->p_nextorph == p);
		q->p_nextorph = p->p_nextorph;
	}

	/*
	 * The process table slot is being freed, so it is now safe to give up
	 * task and project membership.
	 */
	mutex_enter(&p->p_lock);
	tk = p->p_task;
	task_detach(p);
	mutex_exit(&p->p_lock);

	proc_detach(p);
	pid_exit(p, tk);	/* frees pid and proc structure */

	task_rele(tk);
}
Exemplo n.º 7
0
static OSKIT_COMDECL filesystem_remount(oskit_filesystem_t *f,
				       oskit_u32_t flags)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    struct mount *mp;
    struct proc *p;
    oskit_error_t ferror;
    int error, oflag;

    
    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;

    mp = fs->mp;

    /*
     * Only root, or the user that did the original mount is
     * permitted to update it.
     */
    if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
	(error = suser(p->p_ucred, 0))) 
    {
	prfree(p);
	return errno_to_oskit_error(error);
    }

    if (flags & OSKIT_FS_NOEXEC)
	    mp->mnt_flag |= MNT_NOEXEC;
    if (flags & OSKIT_FS_NOSUID)
	    mp->mnt_flag |= MNT_NOSUID;
    if (flags & OSKIT_FS_NODEV)
	    mp->mnt_flag |= MNT_NODEV;

    oflag = mp->mnt_flag;

    if ((flags & OSKIT_FS_RDONLY) &&
	((mp->mnt_flag & MNT_RDONLY) == 0))
	    /* rdwr -> rdonly */
	    mp->mnt_flag |= (MNT_UPDATE | MNT_FORCE | MNT_RDONLY);
    
    if (((flags & OSKIT_FS_RDONLY) == 0) &&
	(mp->mnt_flag & MNT_RDONLY))
	    /* rdonly -> rdwr */
	    mp->mnt_flag |= (MNT_UPDATE | MNT_RELOAD | MNT_WANTRDWR);

    error = 0;
    if (mp->mnt_flag & MNT_UPDATE)
    {
	struct nameidata nd;		/* dummy to contain cred */
	struct ucred cred;		/* dummy, contents not actually used */

	nd.ni_cnd.cn_cred = &cred;
	error = VFS_MOUNT(mp, 0, 0, &nd, p);
	if (mp->mnt_flag & MNT_WANTRDWR)
		mp->mnt_flag &= ~MNT_RDONLY;
	mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR);
	if (error)
		mp->mnt_flag = oflag;
    }

    prfree(p);
    if (error)
	    return errno_to_oskit_error(error);	

    return 0;    
}