Jan Beulich
2012-Mar-06 08:56 UTC
[PATCH] linux-2.6.18/blkfront: module exit handling adjustments
blkdev majors and minor tracking data must be released upon exit, or else the module can''t attach to devices using the same majors upon being loaded again. Also replace the literal uses of 202 for the Xen VBD major with the upstream manifest constant. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/drivers/xen/blkfront/blkfront.c +++ b/drivers/xen/blkfront/blkfront.c @@ -962,7 +962,8 @@ module_init(xlblk_init); static void __exit xlblk_exit(void) { - return xenbus_unregister_driver(&blkfront_driver); + xenbus_unregister_driver(&blkfront_driver); + xlbd_release_major_info(); } module_exit(xlblk_exit); --- a/drivers/xen/blkfront/block.h +++ b/drivers/xen/blkfront/block.h @@ -156,4 +156,6 @@ static inline void xlvbd_sysfs_delif(str } #endif +void xlbd_release_major_info(void); + #endif /* __XEN_DRIVERS_BLOCK_H__ */ --- a/drivers/xen/blkfront/vbd.c +++ b/drivers/xen/blkfront/vbd.c @@ -40,6 +40,10 @@ #include <xen/platform-compat.h> #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +#define XENVBD_MAJOR 202 +#endif + #define BLKIF_MAJOR(dev) ((dev)>>8) #define BLKIF_MINOR(dev) ((dev) & 0xff) @@ -163,7 +167,7 @@ xlbd_alloc_major_info(int major, int min ptr->type = &xlbd_vbd_type_ext; /* - * if someone already registered block major 202, + * if someone already registered block major XENVBD_MAJOR, * don''t try to register it again */ if (major_info[XLBD_MAJOR_VBD_ALT(index)] != NULL) { @@ -238,6 +242,32 @@ xlbd_put_major_info(struct xlbd_major_in /* XXX: release major if 0 */ } +void __exit +xlbd_release_major_info(void) +{ + unsigned int i; + int vbd_done = 0; + + for (i = 0; i < ARRAY_SIZE(major_info); ++i) { + struct xlbd_major_info *mi = major_info[i]; + + if (!mi) + continue; + if (mi->usage) + printk(KERN_WARNING + "vbd: major %u still in use (%u times)\n", + mi->major, mi->usage); + if (mi->major != XENVBD_MAJOR || !vbd_done) { + unregister_blkdev(mi->major, mi->type->devname); + kfree(mi->minors->bitmap); + kfree(mi->minors); + } + if (mi->major == XENVBD_MAJOR) + vbd_done = 1; + kfree(mi); + } +} + static int xlbd_reserve_minors(struct xlbd_major_info *mi, unsigned int minor, unsigned int nr_minors) @@ -443,7 +473,7 @@ xlvbd_add(blkif_sector_t capacity, int v minor = BLKIF_MINOR(vdevice); } else { - major = 202; + major = XENVBD_MAJOR; minor = BLKIF_MINOR_EXT(vdevice); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel