diff -NurpP --minimal linux-2.6.14.2-vs2.1.0-rc7.7/drivers/block/Kconfig linux-2.6.14.2-vs2.1.0-rc7.8/drivers/block/Kconfig --- linux-2.6.14.2-vs2.1.0-rc7.7/drivers/block/Kconfig 2005-10-29 03:19:03 +0200 +++ linux-2.6.14.2-vs2.1.0-rc7.8/drivers/block/Kconfig 2005-11-20 01:14:19 +0100 @@ -317,6 +317,7 @@ config BLK_DEV_CRYPTOLOOP config BLK_DEV_VROOT tristate "Virtual Root device support" + depends on QUOTACTL ---help--- Saying Y here will allow you to use quota/fs ioctls on a shared partition within a virtual server without compromising security. diff -NurpP --minimal linux-2.6.14.2-vs2.1.0-rc7.7/drivers/block/vroot.c linux-2.6.14.2-vs2.1.0-rc7.8/drivers/block/vroot.c --- linux-2.6.14.2-vs2.1.0-rc7.7/drivers/block/vroot.c 2005-10-29 03:19:03 +0200 +++ linux-2.6.14.2-vs2.1.0-rc7.8/drivers/block/vroot.c 2005-11-20 00:57:19 +0100 @@ -150,7 +150,7 @@ static struct block_device_operations vr .ioctl = vr_ioctl, }; -struct block_device *vroot_get_real_bdev(struct block_device *bdev) +struct block_device *__vroot_get_real_bdev(struct block_device *bdev) { struct inode *inode = bdev->bd_inode; struct vroot_device *vr; @@ -188,7 +188,7 @@ MODULE_DESCRIPTION ("Virtual Root Device int __init vroot_init(void) { - int i; + int err, i; if (max_vroot < 1 || max_vroot > 256) { max_vroot = MAX_VROOT_DEFAULT; @@ -200,6 +200,7 @@ int __init vroot_init(void) if (register_blkdev(VROOT_MAJOR, "vroot")) return -EIO; + err = -ENOMEM; vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL); if (!vroot_dev) goto out_mem1; @@ -232,11 +233,17 @@ int __init vroot_init(void) disk->private_data = vr; } + err = register_vroot_grb(&__vroot_get_real_bdev); + if (err) + goto out_reg; + for (i = 0; i < max_vroot; i++) add_disk(disks[i]); printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot); return 0; +out_reg: + devfs_remove("vroot"); out_mem3: while (i--) put_disk(disks[i]); @@ -246,13 +253,16 @@ out_mem2: out_mem1: unregister_blkdev(VROOT_MAJOR, "vroot"); printk(KERN_ERR "vroot: ran out of memory\n"); - return -ENOMEM; + return err; } void vroot_exit(void) { int i; + if (unregister_vroot_grb(&__vroot_get_real_bdev)) + printk(KERN_WARNING "vroot: cannot unregister grb\n"); + for (i = 0; i < max_vroot; i++) { del_gendisk(disks[i]); put_disk(disks[i]); diff -NurpP --minimal linux-2.6.14.2-vs2.1.0-rc7.7/fs/quota.c linux-2.6.14.2-vs2.1.0-rc7.8/fs/quota.c --- linux-2.6.14.2-vs2.1.0-rc7.7/fs/quota.c 2005-10-29 03:20:34 +0200 +++ linux-2.6.14.2-vs2.1.0-rc7.8/fs/quota.c 2005-11-20 05:29:00 +0100 @@ -335,8 +335,41 @@ static int do_quotactl(struct dqhash *ha return 0; } -#ifdef CONFIG_BLK_DEV_VROOT -extern struct block_device *vroot_get_real_bdev(struct block_device *); +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE) + +#include +#include + +static vroot_grb_func *vroot_get_real_bdev = NULL; + +static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED; + +int register_vroot_grb(vroot_grb_func *func) { + int ret = -EBUSY; + + spin_lock(&vroot_grb_lock); + if (!vroot_get_real_bdev) { + vroot_get_real_bdev = func; + ret = 0; + } + spin_unlock(&vroot_grb_lock); + return ret; +} +EXPORT_SYMBOL(register_vroot_grb); + +int unregister_vroot_grb(vroot_grb_func *func) { + int ret = -EINVAL; + + spin_lock(&vroot_grb_lock); + if (vroot_get_real_bdev) { + vroot_get_real_bdev = NULL; + ret = 0; + } + spin_unlock(&vroot_grb_lock); + return ret; +} +EXPORT_SYMBOL(unregister_vroot_grb); + #endif /* diff -NurpP --minimal linux-2.6.14.2-vs2.1.0-rc7.7/include/linux/vroot.h linux-2.6.14.2-vs2.1.0-rc7.8/include/linux/vroot.h --- linux-2.6.14.2-vs2.1.0-rc7.7/include/linux/vroot.h 2005-10-29 03:19:03 +0200 +++ linux-2.6.14.2-vs2.1.0-rc7.8/include/linux/vroot.h 2005-11-20 01:15:50 +0100 @@ -31,6 +31,12 @@ struct vroot_device { int vr_state; }; + +typedef struct block_device *(vroot_grb_func)(struct block_device *); + +extern int register_vroot_grb(vroot_grb_func *); +extern int unregister_vroot_grb(vroot_grb_func *); + #endif /* __KERNEL__ */ #define MAX_VROOT_DEFAULT 8