Esempio n. 1
0
static
int
badnames(const char *n1, const char *n2, const char *n3)
{
	const char *volname;
	unsigned i, num;
	struct knowndev *kd;

	KASSERT(vfs_biglock_do_i_hold());

	num = knowndevarray_num(knowndevs);
	for (i=0; i<num; i++) {
		kd = knowndevarray_get(knowndevs, i);

		if (kd->kd_fs) {
			volname = FSOP_GETVOLNAME(kd->kd_fs);
			if (samestring3(volname, n1, n2, n3)) {
				return 1;
			}
		}

		if (samestring3(kd->kd_rawname, n1, n2, n3) ||
		    samestring3(kd->kd_name, n1, n2, n3)) {
			return 1;
		}
	}

	return 0;
}
Esempio n. 2
0
/*
 * Mount a filesystem. Once we've found the device, call MOUNTFUNC to
 * set up the filesystem and hand back a struct fs.
 *
 * The DATA argument is passed through unchanged to MOUNTFUNC.
 */
int
vfs_mount(const char *devname, void *data,
	  int (*mountfunc)(void *data, struct device *, struct fs **ret))
{
	const char *volname;
	struct knowndev *kd;
	struct fs *fs;
	int result;

	vfs_biglock_acquire();

	result = findmount(devname, &kd);
	if (result) {
		vfs_biglock_release();
		return result;
	}

	if (kd->kd_fs != NULL) {
		vfs_biglock_release();
		return EBUSY;
	}
	KASSERT(kd->kd_rawname != NULL);
	KASSERT(kd->kd_device != NULL);

	result = mountfunc(data, kd->kd_device, &fs);
	if (result) {
		vfs_biglock_release();
		return result;
	}

	KASSERT(fs != NULL);

	kd->kd_fs = fs;

	volname = FSOP_GETVOLNAME(fs);
	kprintf("vfs: Mounted %s: on %s\n",
		volname ? volname : kd->kd_name, kd->kd_name);

	vfs_biglock_release();
	return 0;
}
Esempio n. 3
0
/*
 * Get current directory, as a pathname.
 * Use VOP_NAMEFILE to get the pathname and FSOP_GETVOLNAME to get the
 * volume name.
 */
int
vfs_getcwd(struct uio *uio)
{
	struct vnode *cwd;
	int result;
	const char *name;
	char colon=':';

	KASSERT(uio->uio_rw==UIO_READ);

	result = vfs_getcurdir(&cwd);
	if (result) {
		return result;
	}

	/* The current dir must be a directory, and thus it is not a device. */
	KASSERT(cwd->vn_fs != NULL);

	name = FSOP_GETVOLNAME(cwd->vn_fs);
	if (name==NULL) {
		name = vfs_getdevname(cwd->vn_fs);
	}
	KASSERT(name != NULL);

	result = uiomove((char *)name, strlen(name), uio);
	if (result) {
		goto out;
	}
	result = uiomove(&colon, 1, uio);
	if (result) {
		goto out;
	}

	result = VOP_NAMEFILE(cwd, uio);

 out:

	VOP_DECREF(cwd);
	return result;
}
Esempio n. 4
0
/*
 * Add a new device to the VFS layer's device table.
 *
 * If "mountable" is set, the device will be treated as one that expects
 * to have a filesystem mounted on it, and a raw device will be created
 * for direct access.
 */
static
int
vfs_doadd(const char *dname, int mountable, struct device *dev, struct fs *fs)
{
	char *name=NULL, *rawname=NULL;
	struct knowndev *kd=NULL;
	struct vnode *vnode=NULL;
	const char *volname=NULL;
	unsigned index;
	int result;

	vfs_biglock_acquire();

	name = kstrdup(dname);
	if (name==NULL) {
		goto nomem;
	}
	if (mountable) {
		rawname = mkrawname(name);
		if (rawname==NULL) {
			goto nomem;
		}
	}

	vnode = dev_create_vnode(dev);
	if (vnode==NULL) {
		goto nomem;
	}

	kd = kmalloc(sizeof(struct knowndev));
	if (kd==NULL) {
		goto nomem;
	}

	kd->kd_name = name;
	kd->kd_rawname = rawname;
	kd->kd_device = dev;
	kd->kd_vnode = vnode;
	kd->kd_fs = fs;

	if (fs!=NULL) {
		volname = FSOP_GETVOLNAME(fs);
	}

	if (badnames(name, rawname, volname)) {
		vfs_biglock_release();
		return EEXIST;
	}

	result = knowndevarray_add(knowndevs, kd, &index);

	if (result == 0 && dev != NULL) {
		/* use index+1 as the device number, so 0 is reserved */
		dev->d_devnumber = index+1;
	}

	vfs_biglock_release();
	return result;

 nomem:

	if (name) {
		kfree(name);
	}
	if (rawname) {
		kfree(rawname);
	}
	if (vnode) {
		kfree(vnode);
	}
	if (kd) {
		kfree(kd);
	}

	vfs_biglock_release();
	return ENOMEM;
}
Esempio n. 5
0
/*
 * Given a device name (lhd0, emu0, somevolname, null, etc.), hand
 * back an appropriate vnode.
 */
int
vfs_getroot(const char *devname, struct vnode **ret)
{
	struct knowndev *kd;
	unsigned i, num;

	KASSERT(vfs_biglock_do_i_hold());

	num = knowndevarray_num(knowndevs);
	for (i=0; i<num; i++) {
		kd = knowndevarray_get(knowndevs, i);

		/*
		 * If this device has a mounted filesystem, and
		 * DEVNAME names either the filesystem or the device,
		 * return the root of the filesystem.
		 *
		 * If it has no mounted filesystem, it's mountable,
		 * and DEVNAME names the device, return ENXIO.
		 */

		if (kd->kd_fs!=NULL) {
			const char *volname;
			volname = FSOP_GETVOLNAME(kd->kd_fs);

			if (!strcmp(kd->kd_name, devname) ||
			    (volname!=NULL && !strcmp(volname, devname))) {
				return FSOP_GETROOT(kd->kd_fs, ret);
			}
		}
		else {
			if (kd->kd_rawname!=NULL &&
			    !strcmp(kd->kd_name, devname)) {
				return ENXIO;
			}
		}

		/*
		 * If DEVNAME names the device, and we get here, it
		 * must have no fs and not be mountable. In this case,
		 * we return the device itself.
		 */
		if (!strcmp(kd->kd_name, devname)) {
			KASSERT(kd->kd_fs==NULL);
			KASSERT(kd->kd_rawname==NULL);
			KASSERT(kd->kd_device != NULL);
			VOP_INCREF(kd->kd_vnode);
			*ret = kd->kd_vnode;
			return 0;
		}

		/*
		 * If the device has a rawname and DEVNAME names that,
		 * return the device itself.
		 */
		if (kd->kd_rawname!=NULL && !strcmp(kd->kd_rawname, devname)) {
			KASSERT(kd->kd_device != NULL);
			VOP_INCREF(kd->kd_vnode);
			*ret = kd->kd_vnode;
			return 0;
		}

		/*
		 * If none of the above tests matched, we didn't name
		 * any of the names of this device, so go on to the
		 * next one.
		 */
	}

	/*
	 * If we got here, the device specified by devname doesn't exist.
	 */

	return ENODEV;
}