direct-io.hg

changeset 11655:d90be316e5f5

[BLKTAP] have udev create the device for blktap
This patch makes blktap Do The Right Thing(TM). It allows udev to
create the /dev/xen/blktap[0-9] devices.

It creates a sysfs class called "xen". This part may later be placed
someplace else, but currently blktap is the only user so it is placed in
the blktap code.

When blktap is initialized, a blktap0 sysfs class device is made. The
other devices blktapX (X > 0) are made when the BLKTAP_IOCTL_NEWINTF
ioctl is called. This way we don't flood the sysfs and /dev/xen with
unnecessary devices.

I added a rule in the xen-backend.rules to allow for udev to create the
blktap devices.


With this, we can really remove the code to search and create the
/dev/xen/blktap[0-9]*, but I'll leave it in for now. With the use of
udev, we really should remove that code as well as the code for creating
the evtchn device. udev works for both of these now. But that removal
will have to be in another patch.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
author Andrew Warfield <andy@xensource.com>
date Thu Sep 28 13:44:00 2006 -0700 (2006-09-28)
parents 500043f8ccff
children dc017943eea2
files linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c tools/examples/xen-backend.rules
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Thu Sep 28 12:47:45 2006 -0700
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Thu Sep 28 13:44:00 2006 -0700
     1.3 @@ -44,7 +44,6 @@
     1.4  #include <linux/kernel.h>
     1.5  #include <linux/fs.h>
     1.6  #include <linux/mm.h>
     1.7 -#include <linux/miscdevice.h>
     1.8  #include <linux/errno.h>
     1.9  #include <linux/major.h>
    1.10  #include <linux/gfp.h>
    1.11 @@ -55,6 +54,30 @@
    1.12  #define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
    1.13  #define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
    1.14  
    1.15 +
    1.16 +struct class *xen_class;
    1.17 +EXPORT_SYMBOL_GPL(xen_class);
    1.18 +
    1.19 +/*
    1.20 + * Setup the xen class.  This should probably go in another file, but
    1.21 + * since blktap is the only user of it so far, it gets to keep it.
    1.22 + */
    1.23 +int setup_xen_class(void)
    1.24 +{
    1.25 +	int ret;
    1.26 +
    1.27 +	if (xen_class)
    1.28 +		return 0;
    1.29 +
    1.30 +	xen_class = class_create(THIS_MODULE, "xen");
    1.31 +	if ((ret = IS_ERR(xen_class))) {
    1.32 +		xen_class = NULL;
    1.33 +		return ret;
    1.34 +	}
    1.35 +
    1.36 +	return 0;
    1.37 +}
    1.38 +
    1.39  /*
    1.40   * The maximum number of requests that can be outstanding at any time
    1.41   * is determined by 
    1.42 @@ -100,6 +123,7 @@ typedef struct tap_blkif {
    1.43  	unsigned long *idx_map;       /*Record the user ring id to kern 
    1.44  					[req id, idx] tuple                  */
    1.45  	blkif_t *blkif;               /*Associate blkif with tapdev          */
    1.46 +	int sysfs_set;                /*Set if it has a class device.        */
    1.47  } tap_blkif_t;
    1.48  
    1.49  /*Data struct handed back to userspace for tapdisk device to VBD mapping*/
    1.50 @@ -304,8 +328,6 @@ static int blktap_ioctl(struct inode *in
    1.51                          unsigned int cmd, unsigned long arg);
    1.52  static unsigned int blktap_poll(struct file *file, poll_table *wait);
    1.53  
    1.54 -struct miscdevice *set_misc(int minor, char *name, int dev);
    1.55 -
    1.56  static struct file_operations blktap_fops = {
    1.57  	.owner   = THIS_MODULE,
    1.58  	.poll    = blktap_poll,
    1.59 @@ -337,6 +359,16 @@ static int get_next_free_dev(void)
    1.60  	
    1.61  done:
    1.62  	spin_unlock_irqrestore(&pending_free_lock, flags);
    1.63 +
    1.64 +	/*
    1.65 +	 * We are protected by having the dev_pending set.
    1.66 +	 */
    1.67 +	if (!tapfds[i]->sysfs_set && xen_class) {
    1.68 +		class_device_create(xen_class, NULL,
    1.69 +				    MKDEV(blktap_major, ret), NULL,
    1.70 +				    "blktap%d", ret);
    1.71 +		tapfds[i]->sysfs_set = 1;
    1.72 +	}
    1.73  	return ret;
    1.74  }
    1.75  
    1.76 @@ -428,7 +460,7 @@ static int blktap_release(struct inode *
    1.77  	if (!info) {
    1.78  		WPRINTK("Trying to free device that doesn't exist "
    1.79  		       "[/dev/xen/blktap%d]\n",iminor(inode) - BLKTAP_MINOR);
    1.80 -		return -1;
    1.81 +		return -EBADF;
    1.82  	}
    1.83  	info->dev_inuse = 0;
    1.84  	DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
    1.85 @@ -602,6 +634,7 @@ static int blktap_ioctl(struct inode *in
    1.86  	case BLKTAP_IOCTL_FREEINTF:
    1.87  	{
    1.88  		unsigned long dev = arg;
    1.89 +		unsigned long flags;
    1.90  
    1.91  		/* Looking at another device */
    1.92  		info = NULL;
    1.93 @@ -609,8 +642,11 @@ static int blktap_ioctl(struct inode *in
    1.94  		if ( (dev > 0) && (dev < MAX_TAP_DEV) )
    1.95  			info = tapfds[dev];
    1.96  
    1.97 +		spin_lock_irqsave(&pending_free_lock, flags);
    1.98  		if ( (info != NULL) && (info->dev_pending) )
    1.99  			info->dev_pending = 0;
   1.100 +		spin_unlock_irqrestore(&pending_free_lock, flags);
   1.101 +
   1.102  		return 0;
   1.103  	}
   1.104  	case BLKTAP_IOCTL_MINOR:
   1.105 @@ -1371,7 +1407,8 @@ static int __init blkif_init(void)
   1.106  
   1.107  	for(i = 0; i < MAX_TAP_DEV; i++ ) {
   1.108  		info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
   1.109 -		if(tapfds[i] == NULL) return -ENOMEM;
   1.110 +		if(tapfds[i] == NULL)
   1.111 +			return -ENOMEM;
   1.112  		info->minor = i;
   1.113  		info->pid = 0;
   1.114  		info->blkif = NULL;
   1.115 @@ -1379,12 +1416,31 @@ static int __init blkif_init(void)
   1.116  		ret = devfs_mk_cdev(MKDEV(blktap_major, i),
   1.117  			S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
   1.118  
   1.119 -		if(ret != 0) return -ENOMEM;
   1.120 +		if(ret != 0)
   1.121 +			return -ENOMEM;
   1.122  		info->dev_pending = info->dev_inuse = 0;
   1.123  
   1.124  		DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
   1.125  	}
   1.126  	
   1.127 +	/* Make sure the xen class exists */
   1.128 +	if (!setup_xen_class()) {
   1.129 +		/*
   1.130 +		 * This will allow udev to create the blktap ctrl device.
   1.131 +		 * We only want to create blktap0 first.  We don't want
   1.132 +		 * to flood the sysfs system with needless blktap devices.
   1.133 +		 * We only create the device when a request of a new device is
   1.134 +		 * made.
   1.135 +		 */
   1.136 +		class_device_create(xen_class, NULL,
   1.137 +				    MKDEV(blktap_major, 0), NULL,
   1.138 +				    "blktap0");
   1.139 +		tapfds[0]->sysfs_set = 1;
   1.140 +	} else {
   1.141 +		/* this is bad, but not fatal */
   1.142 +		WPRINTK("blktap: sysfs xen_class not created\n");
   1.143 +	}
   1.144 +
   1.145  	DPRINTK("Blktap device successfully created\n");
   1.146  
   1.147  	return 0;
     2.1 --- a/tools/examples/xen-backend.rules	Thu Sep 28 12:47:45 2006 -0700
     2.2 +++ b/tools/examples/xen-backend.rules	Thu Sep 28 13:44:00 2006 -0700
     2.3 @@ -5,3 +5,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vif*"
     2.4  SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline"
     2.5  SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
     2.6  KERNEL=="evtchn", NAME="xen/%k"
     2.7 +KERNEL=="blktap[0-9]*", NAME="xen/%k"