Пример #1
0
int __init
blktap_ring_init(void)
{
	dev_t dev = 0;
	int err;

	cdev_init(&blktap_ring_cdev, &blktap_ring_file_operations);
	blktap_ring_cdev.owner = THIS_MODULE;

	err = alloc_chrdev_region(&dev, 0, MAX_BLKTAP_DEVICE, "blktap2");
	if (err < 0) {
		BTERR("error registering ring devices: %d\n", err);
		return err;
	}

	err = cdev_add(&blktap_ring_cdev, dev, MAX_BLKTAP_DEVICE);
	if (err) {
		BTERR("error adding ring device: %d\n", err);
		unregister_chrdev_region(dev, MAX_BLKTAP_DEVICE);
		return err;
	}

	blktap_ring_major = MAJOR(dev);
	BTINFO("blktap ring major: %d\n", blktap_ring_major);

	return 0;
}
Пример #2
0
static void
blktap_control_free(void)
{
	int i;

	for (i = 0; i < MAX_BLKTAP_DEVICE; i++)
		blktap_control_destroy_device(blktaps[i]);

	if (blktap_control_registered)
		if (misc_deregister(&blktap_misc) < 0)
			BTERR("misc_deregister failed for control device");
}
Пример #3
0
static int __init
blktap_control_init(void)
{
	int err;

	err = misc_register(&blktap_misc);
	if (err) {
		BTERR("misc_register failed for control device");
		return err;
	}

	blktap_control_registered = 1;
	return 0;
}
Пример #4
0
static struct blktap *
blktap_control_allocate_tap(void)
{
	int err, minor;
	struct blktap *tap;

	/*
	 * This is called only from the ioctl, which
	 * means we should always have interrupts enabled.
	 */
	BUG_ON(irqs_disabled());

	spin_lock_irq(&blktap_control_lock);

	for (minor = 0; minor < MAX_BLKTAP_DEVICE; minor++) {
		tap = blktaps[minor];
		if (!tap)
			goto found;

		if (!tap->dev_inuse) {
			blktap_control_initialize_tap(tap);
			goto found;
		}
	}

	tap = NULL;

found:
	spin_unlock_irq(&blktap_control_lock);

	if (!tap) {
		tap = blktap_control_create_tap();
		if (!tap)
			return NULL;
	}

	err = blktap_ring_create(tap);
	if (err) {
		BTERR("ring creation failed: %d\n", err);
		clear_bit(BLKTAP_CONTROL, &tap->dev_inuse);
		return NULL;
	}

	BTINFO("allocated tap %p\n", tap);
	return tap;
}
Пример #5
0
static int
blktap_control_ioctl(struct inode *inode, struct file *filp,
		     unsigned int cmd, unsigned long arg)
{
	unsigned long dev;
	struct blktap *tap;

	switch (cmd) {
	case BLKTAP2_IOCTL_ALLOC_TAP: {
		struct blktap_handle h;

		tap = blktap_control_allocate_tap();
		if (!tap) {
			BTERR("error allocating device\n");
			return -ENOMEM;
		}

		h.ring   = ring_major;
		h.device = device_major;
		h.minor  = tap->minor;

		if (copy_to_user((struct blktap_handle __user *)arg,
				 &h, sizeof(h))) {
			blktap_control_destroy_device(tap);
			return -EFAULT;
		}

		return 0;
	}

	case BLKTAP2_IOCTL_FREE_TAP:
		dev = arg;

		if (dev >= MAX_BLKTAP_DEVICE || !blktaps[dev])
			return -EINVAL;

		blktap_control_destroy_device(blktaps[dev]);
		return 0;
	}

	return -ENOIOCTLCMD;
}