Beispiel #1
0
int
ext2fs_mountroot(void)
{
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return ENODEV;

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return error;
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return error;
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	ext2fs_sb_setmountinfo(fs, mp);
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return 0;
}
Beispiel #2
0
static int
ntfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct ntfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flag = 0;
	args.uid = 0;
	args.gid = 0;
	args.mode = 0777;

	if ((error = ntfs_mountfs(rootvp, mp, &args, l)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	mountlist_append(mp);
	(void)ntfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Beispiel #3
0
int
cd9660_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;
	int error;
	struct iso_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp))
			!= 0) {
		vrele(rootvp);
		return (error);
	}

	args.flags = ISOFSMNT_ROOT;
	if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	(void)cd9660_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Beispiel #4
0
/*
 * Called by main() when ufs is going to be mounted as root.
 */
lfs_mountroot()
{
	extern struct vnode *rootvp;
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	int error;
	
	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("lfs_mountroot: can't setup bdevvp's");
		return (error);
	}
	if (error = vfs_rootmountalloc("lfs", "root_device", &mp))
		return (error);
	if (error = lfs_mountfs(rootvp, mp, p)) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp, p);
		free(mp, M_MOUNT);
		return (error);
	}
	simple_lock(&mountlist_slock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	simple_unlock(&mountlist_slock);
	(void)lfs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp, p);
	return (0);
}
Beispiel #5
0
int
v7fs_mountroot(void)
{
    struct mount *mp;
    int error;

    DPRINTF("");
    /* On mountroot, devvp (rootdev) is opened by vfs_mountroot */
    if ((error = is_v7fs_partition (rootvp)))
        return error;

    if ((error = vfs_rootmountalloc(MOUNT_V7FS, "root_device", &mp))) {
        DPRINTF("mountalloc error=%d\n", error);
        vrele(rootvp);
        return error;
    }

    if ((error = v7fs_mountfs(rootvp, mp, _BYTE_ORDER))) {
        DPRINTF("mountfs error=%d\n", error);
        vfs_unbusy(mp, false, NULL);
        vfs_destroy(mp);
        return error;
    }

    mountlist_append(mp);

    vfs_unbusy(mp, false, NULL);

    return 0;
}
Beispiel #6
0
int
cd9660_mountroot(void)
{
	struct mount *mp;
	extern struct vnode *rootvp;
	struct proc *p = curproc;	/* XXX */
	int error;
	struct iso_args args;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("cd9660_mountroot: can't setup bdevvp's");
		return (error);
	}

	if ((error = vfs_rootmountalloc("cd9660", "root_device", &mp)) != 0)
		return (error);
	args.flags = ISOFSMNT_ROOT;
	if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT, 0);
		return (error);
	}

	TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	(void)cd9660_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(0);

	return (0);
}
Beispiel #7
0
int
compat_20_netbsd32_getfsstat(struct lwp *l, const struct compat_20_netbsd32_getfsstat_args *uap, register_t *retval)
{
	/* {
		syscallarg(netbsd32_statfsp_t) buf;
		syscallarg(netbsd32_long) bufsize;
		syscallarg(int) flags;
	} */
	struct mount *mp, *nmp;
	struct statvfs *sp;
	struct netbsd32_statfs sb32;
	void *sfsp;
	long count, maxcount, error;

	maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs);
	sfsp = SCARG_P32(uap, buf);
	mutex_enter(&mountlist_lock);
	count = 0;
	for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
		if (vfs_busy(mp, &nmp)) {
			continue;
		}
		if (sfsp && count < maxcount) {
			sp = &mp->mnt_stat;
			/*
			 * If MNT_NOWAIT or MNT_LAZY is specified, do not
			 * refresh the fsstat cache. MNT_WAIT or MNT_LAZY
			 * overrides MNT_NOWAIT.
			 */
			if (SCARG(uap, flags) != MNT_NOWAIT &&
			    SCARG(uap, flags) != MNT_LAZY &&
			    (SCARG(uap, flags) == MNT_WAIT ||
			     SCARG(uap, flags) == 0) &&
			    (error = VFS_STATVFS(mp, sp)) != 0) {
				mutex_enter(&mountlist_lock);
				vfs_unbusy(mp, false, &nmp);
				continue;
			}
			sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
			compat_20_netbsd32_from_statvfs(sp, &sb32);
			error = copyout(&sb32, sfsp, sizeof(sb32));
			if (error) {
				vfs_unbusy(mp, false, NULL);
				return (error);
			}
			sfsp = (char *)sfsp + sizeof(sb32);
		}
		count++;
		mutex_enter(&mountlist_lock);
		vfs_unbusy(mp, false, &nmp);
	}
	mutex_exit(&mountlist_lock);
	if (sfsp && count > maxcount)
		*retval = maxcount;
	else
		*retval = count;
	return (0);
}
Beispiel #8
0
/*
 * Called by main() when ufs is going to be mounted as root.
 */
ffs_mountroot()
{
	extern struct vnode *rootvp;
	struct fs *fs;
	struct mount *mp;
	struct proc *p = current_proc();	/* XXX */
	struct ufsmount *ump;
	u_int size;
	int error;
	
	/*
	 * Get vnode for rootdev.
	 */
	if (error = bdevvp(rootdev, &rootvp)) {
		printf("ffs_mountroot: can't setup bdevvp");
		return (error);
	}
	if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) {
		vrele(rootvp); /* release the reference from bdevvp() */
		return (error);
	}

	/* Must set the MNT_ROOTFS flag before doing the actual mount */
	mp->mnt_flag |= MNT_ROOTFS;

	/* Set asynchronous flag by default */
	mp->mnt_flag |= MNT_ASYNC;

	if (error = ffs_mountfs(rootvp, mp, p)) {
		mp->mnt_vfc->vfc_refcount--;

		if (mp->mnt_kern_flag & MNTK_IO_XINFO)
		        FREE(mp->mnt_xinfo_ptr, M_TEMP);
		vfs_unbusy(mp, p);

		vrele(rootvp); /* release the reference from bdevvp() */
		FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
		return (error);
	}
	simple_lock(&mountlist_slock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	simple_unlock(&mountlist_slock);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp, p);
	inittodr(fs->fs_time);
	return (0);
}
Beispiel #9
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;
}
/*
 * Do operations associated with quotas
 */
int
ulfs_quotactl(struct mount *mp, struct quotactl_args *args)
{

#if !defined(LFS_QUOTA) && !defined(LFS_QUOTA2)
	(void) mp;
	(void) args;
	return (EOPNOTSUPP);
#else
	struct lwp *l = curlwp;
	int error;

	/* Mark the mount busy, as we're passing it to kauth(9). */
	error = vfs_busy(mp, NULL);
	if (error) {
		return (error);
	}
	mutex_enter(&mp->mnt_updating);

	error = lfsquota_handle_cmd(mp, l, args);

	mutex_exit(&mp->mnt_updating);
	vfs_unbusy(mp, false, NULL);
	return (error);
#endif
}
Beispiel #11
0
static int
vfs_getrealpath(const char * path, char * realpath, size_t bufsize, vfs_context_t ctx)
{
	vnode_t vp;
	struct mount *mp = NULL;
	char  *str;
	char ch;
	uint32_t  id;
	ino64_t ino;
	int error;
	int length;

	/* Get file system id and move str to next component. */
	id = strtoul(path, &str, 10);
	if (id == 0 || str[0] != '/') {
		return (EINVAL);
	}
	while (*str == '/') {
		str++;
	}
	ch = *str;

	mp = mount_lookupby_volfsid(id, 1);
	if (mp == NULL) {
		return (EINVAL);  /* unexpected failure */
	}
	/* Check for an alias to a file system root. */
	if (ch == '@' && str[1] == '\0') {
		ino = 2;
		str++;
	} else {
		/* Get file id and move str to next component. */
	    ino = strtouq(str, &str, 10);
	}

	/* Get the target vnode. */
	if (ino == 2) {
		error = VFS_ROOT(mp, &vp, ctx);
	} else {
		error = VFS_VGET(mp, ino, &vp, ctx);
	}
	vfs_unbusy(mp);
	if (error) {
		goto out;
	}
	realpath[0] = '\0';

	/* Get the absolute path to this vnode. */
	error = build_path(vp, realpath, bufsize, &length, 0, ctx);
	vnode_put(vp);

	if (error == 0 && *str != '\0') {
		int attempt = strlcat(realpath, str, MAXPATHLEN);
		if (attempt > MAXPATHLEN){
			error = ENAMETOOLONG;
		}
	}
out:
	return (error);
}
Beispiel #12
0
/*
 * Do a lazy sync of the filesystem.
 */
int
sync_fsync(void *v)
{
	struct vop_fsync_args *ap = v;
	struct vnode *syncvp = ap->a_vp;
	struct mount *mp = syncvp->v_mount;
	int asyncflag;

	/*
	 * We only need to do something if this is a lazy evaluation.
	 */
	if (ap->a_waitfor != MNT_LAZY)
		return (0);

	/*
	 * Move ourselves to the back of the sync list.
	 */
	vn_syncer_add_to_worklist(syncvp, syncdelay);

	/*
	 * Walk the list of vnodes pushing all that are dirty and
	 * not already on the sync list.
	 */
	if (vfs_busy(mp, VB_READ|VB_NOWAIT) == 0) {
		asyncflag = mp->mnt_flag & MNT_ASYNC;
		mp->mnt_flag &= ~MNT_ASYNC;
		VFS_SYNC(mp, MNT_LAZY, ap->a_cred, ap->a_p);
		if (asyncflag)
			mp->mnt_flag |= MNT_ASYNC;
		vfs_unbusy(mp);
	}

	return (0);
}
Beispiel #13
0
static int
msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
    struct vnode **rvp)
{
	struct mount *mp;
	struct msdosfsmount *pmp;
	struct denode *rdp;
	int ltype, error;

	mp = vp->v_mount;
	pmp = VFSTOMSDOSFS(mp);
	ltype = VOP_ISLOCKED(vp);
	KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
	    ("msdosfs_deget_dotdot: vp not locked"));

	error = vfs_busy(mp, MBF_NOWAIT);
	if (error != 0) {
		vfs_ref(mp);
		VOP_UNLOCK(vp, 0);
		error = vfs_busy(mp, 0);
		vn_lock(vp, ltype | LK_RETRY);
		vfs_rel(mp);
		if (error != 0)
			return (ENOENT);
		if (vp->v_iflag & VI_DOOMED) {
			vfs_unbusy(mp);
			return (ENOENT);
		}
	}
	VOP_UNLOCK(vp, 0);
	error = deget(pmp, cluster, blkoff,  &rdp);
	vfs_unbusy(mp);
	if (error == 0)
		*rvp = DETOV(rdp);
	if (*rvp != vp)
		vn_lock(vp, ltype | LK_RETRY);
	if (vp->v_iflag & VI_DOOMED) {
		if (error == 0) {
			if (*rvp == vp)
				vunref(*rvp);
			else
				vput(*rvp);
		}
		error = ENOENT;
	}
	return (error);
}
Beispiel #14
0
int
ffs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	struct ufsmount *ump;
	int error;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	swapdev_vp = NULL;
	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("ffs_mountroot: can't setup bdevvp's\n");
		if (swapdev_vp)
			vrele(swapdev_vp);
		return (error);
	}

	if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) {
		vrele(swapdev_vp);
		vrele(rootvp);
		return (error);
	}

	if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		vrele(swapdev_vp);
		vrele(rootvp);
		return (error);
	}

	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(fs->fs_time);

	return (0);
}
Beispiel #15
0
int
mfs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct lwp *l = curlwp;		/* XXX */
	struct ufsmount *ump;
	struct mfsnode *mfsp;
	int error = 0;

	if ((error = vfs_rootmountalloc(MOUNT_MFS, "mfs_root", &mp))) {
		vrele(rootvp);
		return (error);
	}

	mfsp = kmem_alloc(sizeof(*mfsp), KM_SLEEP);
	rootvp->v_data = mfsp;
	rootvp->v_op = mfs_vnodeop_p;
	rootvp->v_tag = VT_MFS;
	mfsp->mfs_baseoff = mfs_rootbase;
	mfsp->mfs_size = mfs_rootsize;
	mfsp->mfs_vnode = rootvp;
	mfsp->mfs_proc = NULL;		/* indicate kernel space */
	mfsp->mfs_shutdown = 0;
	cv_init(&mfsp->mfs_cv, "mfs");
	mfsp->mfs_refcnt = 1;
	bufq_alloc(&mfsp->mfs_buflist, "fcfs", 0);
	if ((error = ffs_mountfs(rootvp, mp, l)) != 0) {
		vfs_unbusy(mp, false, NULL);
		bufq_free(mfsp->mfs_buflist);
		vfs_destroy(mp);
		kmem_free(mfsp, sizeof(*mfsp));
		return (error);
	}
	mutex_enter(&mountlist_lock);
	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	mutex_exit(&mountlist_lock);
	mp->mnt_vnodecovered = NULLVP;
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Beispiel #16
0
__private_extern__
int
fuse_internal_remove(vnode_t               dvp,
                     vnode_t               vp,
                     struct componentname *cnp,
                     enum fuse_opcode      op,
                     vfs_context_t         context)
{
    struct fuse_dispatcher fdi;

    struct vnode_attr *vap = VTOVA(vp);
    int need_invalidate = 0;
    uint64_t target_nlink = 0;
    mount_t mp = vnode_mount(vp);

    int err = 0;

    fdisp_init(&fdi, cnp->cn_namelen + 1);
    fdisp_make_vp(&fdi, op, dvp, context);

    memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
    ((char *)fdi.indata)[cnp->cn_namelen] = '\0';

    if ((vap->va_nlink > 1) && vnode_isreg(vp)) {
        need_invalidate = 1;
        target_nlink = vap->va_nlink;
    }

    if (!(err = fdisp_wait_answ(&fdi))) {
        fuse_ticket_drop(fdi.tick);
    }

    fuse_invalidate_attr(dvp);
    fuse_invalidate_attr(vp);

    /*
     * XXX: M_MACFUSE_INVALIDATE_CACHED_VATTRS_UPON_UNLINK
     *
     * Consider the case where vap->va_nlink > 1 for the entity being
     * removed. In our world, other in-memory vnodes that share a link
     * count each with this one may not know right way that this one just
     * got deleted. We should let them know, say, through a vnode_iterate()
     * here and a callback that does fuse_invalidate_attr(vp) on each
     * relevant vnode.
     */
    if (need_invalidate && !err) {
        if (!vfs_busy(mp, LK_NOWAIT)) {
            vnode_iterate(mp, 0, fuse_internal_remove_callback,
                          (void *)&target_nlink);
            vfs_unbusy(mp);
        } else {
            IOLog("MacFUSE: skipping link count fixup upon remove\n");
        }
    }

    return err;
}
Beispiel #17
0
int
mfs_mountroot(void)
{
	struct fs *fs;
	struct mount *mp;
	struct proc *p = curproc;
	struct ufsmount *ump;
	struct mfsnode *mfsp;
	int error;

	if ((error = bdevvp(swapdev, &swapdev_vp)) ||
	    (error = bdevvp(rootdev, &rootvp))) {
		printf("mfs_mountroot: can't setup bdevvp's");
		return (error);
	}
	if ((error = vfs_rootmountalloc("mfs", "mfs_root", &mp)) != 0)
		return (error);
	mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK);
	rootvp->v_data = mfsp;
	rootvp->v_op = mfs_vnodeop_p;
	rootvp->v_tag = VT_MFS;
	mfsp->mfs_baseoff = mfs_rootbase;
	mfsp->mfs_size = mfs_rootsize;
	mfsp->mfs_vnode = rootvp;
	mfsp->mfs_pid = p->p_pid;
	mfsp->mfs_buflist = (struct buf *)0;
	if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		free(mfsp, M_MFSNODE);
		return (error);
	}

	CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_fs;
	(void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
	(void)ffs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr((time_t)0);

	return (0);
}
Beispiel #18
0
int
procfs_domounts(struct lwp *curl, struct proc *p,
    struct pfsnode *pfs, struct uio *uio)
{
	char *bf, *mtab = NULL;
	const char *fsname;
	size_t len, mtabsz = 0;
	struct mount *mp, *nmp;
	struct statvfs *sfs;
	int error = 0;

	bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
	mutex_enter(&mountlist_lock);
	for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
	     mp = nmp) {
		if (vfs_busy(mp, &nmp)) {
			continue;
		}

		sfs = &mp->mnt_stat;

		/* Linux uses different names for some filesystems */
		fsname = sfs->f_fstypename;
		if (strcmp(fsname, "procfs") == 0)
			fsname = "proc";
		else if (strcmp(fsname, "ext2fs") == 0)
			fsname = "ext2";

		len = snprintf(bf, LBFSZ, "%s %s %s %s%s%s%s%s%s 0 0\n",
			sfs->f_mntfromname,
			sfs->f_mntonname,
			fsname,
			(mp->mnt_flag & MNT_RDONLY) ? "ro" : "rw",
			(mp->mnt_flag & MNT_NOSUID) ? ",nosuid" : "",
			(mp->mnt_flag & MNT_NOEXEC) ? ",noexec" : "",
			(mp->mnt_flag & MNT_NODEV) ? ",nodev" : "",
			(mp->mnt_flag & MNT_SYNCHRONOUS) ? ",sync" : "",
			(mp->mnt_flag & MNT_NOATIME) ? ",noatime" : ""
			);

		mtab = realloc(mtab, mtabsz + len, M_TEMP, M_WAITOK);
		memcpy(mtab + mtabsz, bf, len);
		mtabsz += len;

		vfs_unbusy(mp, false, &nmp);
	}
	mutex_exit(&mountlist_lock);
	free(bf, M_TEMP);

	if (mtabsz > 0) {
		error = uiomove_frombuf(mtab, mtabsz, uio);
		free(mtab, M_TEMP);
	}

	return error;
}
Beispiel #19
0
int
ext2fs_mountroot(void)
{
	struct m_ext2fs *fs;
        struct mount *mp;
	struct proc *p = curproc;	/* XXX */
	struct ufsmount *ump;
	int error;

	/*
	 * Get vnodes for swapdev and rootdev.
	 */
	if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
		panic("ext2fs_mountroot: can't setup bdevvp's");

	if ((error = vfs_rootmountalloc("ext2fs", "root_device", &mp)) != 0) {
		vrele(rootvp);
		return (error);
	}

	if ((error = ext2fs_mountfs(rootvp, mp, p)) != 0) {
		mp->mnt_vfc->vfc_refcount--;
		vfs_unbusy(mp);
		free(mp, M_MOUNT);
		vrele(rootvp);
		return (error);
	}

	TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
	strlcpy(fs->e2fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->e2fs_fsmnt));
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
		strlcpy(fs->e2fs.e2fs_fsmnt, mp->mnt_stat.f_mntonname,
		    sizeof(fs->e2fs.e2fs_fsmnt));
	}
	(void)ext2fs_statfs(mp, &mp->mnt_stat, p);
	vfs_unbusy(mp);
	inittodr(fs->e2fs.e2fs_wtime);
	return (0);
}
Beispiel #20
0
int
msdosfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct msdosfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_MSDOS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flags = MSDOSFSMNT_VERSIONED;
	args.uid = 0;
	args.gid = 0;
	args.mask = 0777;
	args.version = MSDOSFSMNT_VERSION;
	args.dirmask = 0777;

	if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	if ((error = update_mp(mp, &args)) != 0) {
		(void)msdosfs_unmount(mp, 0);
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		vrele(rootvp);
		return (error);
	}

	mountlist_append(mp);
	(void)msdosfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
Beispiel #21
0
int
ext2fs_mountroot(void)
{	
//	printf("ext2fs_mountroot\n");
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
	(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt,
	    sizeof(fs->e2fs_fsmnt) - 1, 0);
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
		(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
		    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
	}
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return (0);
}
Beispiel #22
0
int
#define struct
ext2fs_mountroot(struct mount *mp)
{
	struct vnode *rootvp;
#undef struct
        struct m_ext2fs *fs;
//        struct mount *mp;
        int error;
        
        DEBUG ((EFI_D_INFO, "mountroot 1\n"));
        if (device_class(root_device) != DV_DISK)
    		return (ENONDEV);
        
        DEBUG ((EFI_D_INFO, "mountroot 2\n"));
        if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
    		vrele(rootvp);
                return (error);
        }
        
        DEBUG ((EFI_D_INFO, "mountroot 3\n"));
        if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
    		vfs_unbusy(mp,false,NULL);
    		vfs_destroy(mp);
                return (error);
        }

      DEBUG ((EFI_D_INFO, "mountroot 4\n"));
        fs = mp->fs;
        memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
        (void) copystr(mp->f_mntonname, fs->e2fs_fsmnt,
            sizeof(fs->e2fs_fsmnt) - 1, 0);
        if (fs->e2fs.e2fs_rev > E2FS_REV0) {
                memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
                (void) copystr(mp->f_mntonname, fs->e2fs.e2fs_fsmnt,
                    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
        }
        vfs_unbusy(mp, false, NULL);
        return (0);
Beispiel #23
0
int
traverse(vnode_t **cvpp, int lktype)
{
	vnode_t *cvp;
	vnode_t *tvp;
	vfs_t *vfsp;
	int error;

	cvp = *cvpp;
	tvp = NULL;

	/*
	 * If this vnode is mounted on, then we transparently indirect
	 * to the vnode which is the root of the mounted file system.
	 * Before we do this we must check that an unmount is not in
	 * progress on this vnode.
	 */

	for (;;) {
		/*
		 * Reached the end of the mount chain?
		 */
		vfsp = vn_mountedvfs(cvp);
		if (vfsp == NULL)
			break;
		error = vfs_busy(vfsp, 0);
		/*
		 * tvp is NULL for *cvpp vnode, which we can't unlock.
		 */
		if (tvp != NULL)
			vput(cvp);
		else
			vrele(cvp);
		if (error)
			return (error);

		/*
		 * The read lock must be held across the call to VFS_ROOT() to
		 * prevent a concurrent unmount from destroying the vfs.
		 */
		error = VFS_ROOT(vfsp, lktype, &tvp);
		vfs_unbusy(vfsp);
		if (error != 0)
			return (error);
		cvp = tvp;
	}

	*cvpp = cvp;
	return (0);
}
Beispiel #24
0
/*
 * Do operations associated with quotas
 */
int
ufs_quotactl(struct mount *mp, prop_dictionary_t dict)
{
	struct lwp *l = curlwp;

#if !defined(QUOTA) && !defined(QUOTA2)
	(void) mp;
	(void) dict;
	(void) l;
	return (EOPNOTSUPP);
#else
	int  error;
	prop_dictionary_t cmddict;
	prop_array_t commands;
	prop_object_iterator_t iter;

	/* Mark the mount busy, as we're passing it to kauth(9). */
	error = vfs_busy(mp, NULL);
	if (error)
		return (error);

	error = quota_get_cmds(dict, &commands);
	if (error)
		goto out_vfs;
	iter = prop_array_iterator(commands);
	if (iter == NULL) {
		error = ENOMEM;
		goto out_vfs;
	}
		
		
	mutex_enter(&mp->mnt_updating);
	while ((cmddict = prop_object_iterator_next(iter)) != NULL) {
		if (prop_object_type(cmddict) != PROP_TYPE_DICTIONARY)
			continue;
		error = quota_handle_cmd(mp, l, cmddict);
		if (error)
			break;
	}
	prop_object_iterator_release(iter);
	mutex_exit(&mp->mnt_updating);
out_vfs:
	vfs_unbusy(mp, false, NULL);
	return (error);
#endif
}
Beispiel #25
0
int
procfs_domounts(struct lwp *curl, struct proc *p,
    struct pfsnode *pfs, struct uio *uio)
{
	char *bf, *mtab = NULL;
	size_t mtabsz = 0;
	struct mount *mp, *nmp;
	int error = 0, root = 0;
	struct cwdinfo *cwdi = curl->l_proc->p_cwdi;

	bf = malloc(LBFSZ, M_TEMP, M_WAITOK);

	mutex_enter(&mountlist_lock);
	for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
		struct statvfs sfs;

		if (vfs_busy(mp, &nmp))
			continue;

		if ((error = dostatvfs(mp, &sfs, curl, MNT_WAIT, 0)) == 0)
			root |= procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ,
			    &sfs, curl, 0);

		vfs_unbusy(mp, false, &nmp);
	}
	mutex_exit(&mountlist_lock);

	/*
	 * If we are inside a chroot that is not itself a mount point,
	 * fake a root entry.
	 */
	if (!root && cwdi->cwdi_rdir)
		(void)procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ,
		    &cwdi->cwdi_rdir->v_mount->mnt_stat, curl, 1);

	free(bf, M_TEMP);

	if (mtabsz > 0) {
		error = uiomove_frombuf(mtab, mtabsz, uio);
		free(mtab, M_TEMP);
	}

	return error;
}
Beispiel #26
0
int
vfs_getbyid(fsid_t *fsid, ino64_t ino, vnode_t *vpp, vfs_context_t ctx)
{
	mount_t mp;
	int error;
	
	mp = mount_lookupby_volfsid(fsid->val[0], 1);
	if (mp == NULL) {
		return EINVAL;
	}

	/* Get the target vnode. */
	if (ino == 2) {
		error = VFS_ROOT(mp, vpp, ctx);
	} else {
		error = VFS_VGET(mp, ino, vpp, ctx);
	}

	vfs_unbusy(mp);
	return error;
}
Beispiel #27
0
/*
 * Do a lazy sync of the filesystem.
 *
 * sync_fsync { struct vnode *a_vp, int a_waitfor }
 */
static int
sync_fsync(struct vop_fsync_args *ap)
{
	struct vnode *syncvp = ap->a_vp;
	struct mount *mp = syncvp->v_mount;
	int asyncflag;

	/*
	 * We only need to do something if this is a lazy evaluation.
	 */
	if ((ap->a_waitfor & MNT_LAZY) == 0)
		return (0);

	/*
	 * Move ourselves to the back of the sync list.
	 */
	vn_syncer_add(syncvp, syncdelay);

	/*
	 * Walk the list of vnodes pushing all that are dirty and
	 * not already on the sync list, and freeing vnodes which have
	 * no refs and whos VM objects are empty.  vfs_msync() handles
	 * the VM issues and must be called whether the mount is readonly
	 * or not.
	 */
	if (vfs_busy(mp, LK_NOWAIT) != 0)
		return (0);
	if (mp->mnt_flag & MNT_RDONLY) {
		vfs_msync(mp, MNT_NOWAIT);
	} else {
		asyncflag = mp->mnt_flag & MNT_ASYNC;
		mp->mnt_flag &= ~MNT_ASYNC;	/* ZZZ hack */
		vfs_msync(mp, MNT_NOWAIT);
		VFS_SYNC(mp, MNT_NOWAIT | MNT_LAZY);
		if (asyncflag)
			mp->mnt_flag |= MNT_ASYNC;
	}
	vfs_unbusy(mp);
	return (0);
}
Beispiel #28
0
/*
 * Resolve a mount point's glue ncp.  This ncp connects creates the illusion
 * of continuity in the namecache tree by connecting the ncp related to the
 * vnode under the mount to the ncp related to the mount's root vnode.
 *
 * If no error occured a locked, ref'd ncp is stored in *ncpp.
 */
int
nlookup_mp(struct mount *mp, struct nchandle *nch)
{
    struct vnode *vp;
    int error;

    error = 0;
    cache_get(&mp->mnt_ncmountpt, nch);
    if (nch->ncp->nc_flag & NCF_UNRESOLVED) {
	while (vfs_busy(mp, 0))
	    ;
	error = VFS_ROOT(mp, &vp);
	vfs_unbusy(mp);
	if (error) {
	    cache_put(nch);
	} else {
	    cache_setvp(nch, vp);
	    vput(vp);
	}
    }
    return(error);
}
Beispiel #29
0
/*
 * Internal version of mount system call for diskless setup.
 * Separate function because we used to call it twice.
 * (once for root and once for swap)
 */
static int
nfs_mount_diskless(struct nfs_dlmount *ndmntp, const char *mntname, struct mount **mpp, struct vnode **vpp, struct lwp *l)
	/* mntname:	 mount point name */
{
	struct mount *mp;
	struct mbuf *m;
	int error;

	vfs_rootmountalloc(MOUNT_NFS, mntname, &mp);

	mp->mnt_op = &nfs_vfsops;

	/*
	 * Historical practice expects NFS root file systems to
	 * be initially mounted r/w.
	 */
	mp->mnt_flag &= ~MNT_RDONLY;

	/* Get mbuf for server sockaddr. */
	m = m_get(M_WAIT, MT_SONAME);
	if (m == NULL)
		panic("nfs_mountroot: mget soname for %s", mntname);
	MCLAIM(m, &nfs_mowner);
	memcpy(mtod(m, void *), (void *)ndmntp->ndm_args.addr,
	      (m->m_len = ndmntp->ndm_args.addr->sa_len));

	error = mountnfs(&ndmntp->ndm_args, mp, m, mntname,
			 ndmntp->ndm_args.hostname, vpp, l);
	if (error) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		printf("nfs_mountroot: mount %s failed: %d\n",
		       mntname, error);
	} else
		*mpp = mp;

	return (error);
}
Beispiel #30
0
/*
 * sys_lfs_segclean:
 *
 * Mark the segment clean.
 *
 *  0 on success
 * -1/errno is return on error.
 */
int
sys_lfs_segclean(struct lwp *l, const struct sys_lfs_segclean_args *uap, register_t *retval)
{
	/* {
		syscallarg(fsid_t *) fsidp;
		syscallarg(u_long) segment;
	} */
	struct lfs *fs;
	struct mount *mntp;
	fsid_t fsid;
	int error;
	unsigned long segnum;

	error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LFS,
	    KAUTH_REQ_SYSTEM_LFS_SEGCLEAN, NULL, NULL, NULL);
	if (error)
		return (error);

	if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
		return (error);
	if ((mntp = vfs_getvfs(&fsid)) == NULL)
		return (ENOENT);

	fs = VFSTOULFS(mntp)->um_lfs;
	segnum = SCARG(uap, segment);

	if ((error = vfs_busy(mntp, NULL)) != 0)
		return (error);

	KERNEL_LOCK(1, NULL);
	lfs_seglock(fs, SEGM_PROT);
	error = lfs_do_segclean(fs, segnum);
	lfs_segunlock(fs);
	KERNEL_UNLOCK_ONE(NULL);
	vfs_unbusy(mntp, false, NULL);
	return error;
}