Example #1
0
/*
 * Look for a mountable device named DEVNAME.
 * Should already hold knowndevs_lock.
 */
static
int
findmount(const char *devname, struct knowndev **result)
{
	struct knowndev *dev;
	unsigned i, num;
	bool found = false;

	KASSERT(vfs_biglock_do_i_hold());

	num = knowndevarray_num(knowndevs);
	for (i=0; !found && i<num; i++) {
		dev = knowndevarray_get(knowndevs, i);
		if (dev->kd_rawname==NULL) {
			/* not mountable/unmountable */
			continue;
		}

		if (!strcmp(devname, dev->kd_name)) {
			*result = dev;
			found = true;
		}
	}

	return found ? 0 : ENODEV;
}
Example #2
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;
}
Example #3
0
/*
 * Given a filesystem, hand back the name of the device it's mounted on.
 */
const char *
vfs_getdevname(struct fs *fs)
{
	struct knowndev *kd;
	unsigned i, num;

	KASSERT(fs != NULL);

	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 == fs) {
			/*
			 * This is not a race condition: as long as the
			 * guy calling us holds a reference to the fs,
			 * the fs cannot go away, and the device can't
			 * go away until the fs goes away.
			 */
			return kd->kd_name;
		}
	}

	return NULL;
}
Example #4
0
int
sfs_rwblock(struct sfs_fs *sfs, struct uio *uio)
{
	int result;
	int tries=0;

	KASSERT(vfs_biglock_do_i_hold());

	DEBUG(DB_SFS, "sfs: %s %llu\n", 
	      uio->uio_rw == UIO_READ ? "read" : "write",
	      uio->uio_offset / SFS_BLOCKSIZE);

 retry:
	result = sfs->sfs_device->d_io(sfs->sfs_device, uio);
	if (result == EINVAL) {
		/*
		 * This means the sector we requested was out of range,
		 * or the seek address we gave wasn't sector-aligned,
		 * or a couple of other things that are our fault.
		 */
		panic("sfs: d_io returned EINVAL\n");
	}
	if (result == EIO) {
		if (tries == 0) {
			tries++;
			kprintf("sfs: block %llu I/O error, retrying\n",
				uio->uio_offset / SFS_BLOCKSIZE);
			goto retry;
		}
		else if (tries < 10) {
			tries++;
			goto retry;
		}
		else {
			kprintf("sfs: block %llu I/O error, giving up after "
				"%d retries\n",
				uio->uio_offset / SFS_BLOCKSIZE, tries);
		}
	}
	return result;
}
Example #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;
}