aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/nbd.c
diff options
context:
space:
mode:
authorLaurent Vivier <Laurent.Vivier@bull.net>2008-04-29 04:02:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:23 -0400
commitd71a6d7332e5881a65249f4fb97b0db3c61dd5ec (patch)
treeff38d51dc1de5651e87ad33ec3a02648297237da /drivers/block/nbd.c
parent48cf6061b30205b29b306bf9bc22dd6f0b091461 (diff)
NBD: add partition support
Permit the use of partitions with network block devices (NBD). A new parameter is introduced to define how many partition we want to be able to manage per network block device. This parameter is "max_part". For instance, to manage 63 partitions / loop device, we will do: [on the server side] # nbd-server 1234 /dev/sdb [on the client side] # modprobe nbd max_part=63 # ls -l /dev/nbd* brw-rw---- 1 root disk 43, 0 2008-03-25 11:14 /dev/nbd0 brw-rw---- 1 root disk 43, 64 2008-03-25 11:11 /dev/nbd1 brw-rw---- 1 root disk 43, 640 2008-03-25 11:11 /dev/nbd10 brw-rw---- 1 root disk 43, 704 2008-03-25 11:11 /dev/nbd11 brw-rw---- 1 root disk 43, 768 2008-03-25 11:11 /dev/nbd12 brw-rw---- 1 root disk 43, 832 2008-03-25 11:11 /dev/nbd13 brw-rw---- 1 root disk 43, 896 2008-03-25 11:11 /dev/nbd14 brw-rw---- 1 root disk 43, 960 2008-03-25 11:11 /dev/nbd15 brw-rw---- 1 root disk 43, 128 2008-03-25 11:11 /dev/nbd2 brw-rw---- 1 root disk 43, 192 2008-03-25 11:11 /dev/nbd3 brw-rw---- 1 root disk 43, 256 2008-03-25 11:11 /dev/nbd4 brw-rw---- 1 root disk 43, 320 2008-03-25 11:11 /dev/nbd5 brw-rw---- 1 root disk 43, 384 2008-03-25 11:11 /dev/nbd6 brw-rw---- 1 root disk 43, 448 2008-03-25 11:11 /dev/nbd7 brw-rw---- 1 root disk 43, 512 2008-03-25 11:11 /dev/nbd8 brw-rw---- 1 root disk 43, 576 2008-03-25 11:11 /dev/nbd9 # nbd-client localhost 1234 /dev/nbd0 Negotiation: ..size = 80418240KB bs=1024, sz=80418240 -------NOTE, RFC: partition table is not automatically read. The driver sets bdev->bd_invalidated to 1 to force the read of the partition table of the device, but this is done only on an open of the device. So we have to do a "touch /dev/nbdX" or something like that. It can't be done from the nbd-client or nbd driver because at this level we can't ask to read the partition table and to serve the request at the same time (-> deadlock) If someone has a better idea, I'm open to any suggestion. -------NOTE, RFC # fdisk -l /dev/nbd0 Disk /dev/nbd0: 82.3 GB, 82348277760 bytes 255 heads, 63 sectors/track, 10011 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/nbd0p1 * 1 9965 80043831 83 Linux /dev/nbd0p2 9966 10011 369495 5 Extended /dev/nbd0p5 9966 10011 369463+ 82 Linux swap / Solaris # ls -l /dev/nbd0* brw-rw---- 1 root disk 43, 0 2008-03-25 11:16 /dev/nbd0 brw-rw---- 1 root disk 43, 1 2008-03-25 11:16 /dev/nbd0p1 brw-rw---- 1 root disk 43, 2 2008-03-25 11:16 /dev/nbd0p2 brw-rw---- 1 root disk 43, 5 2008-03-25 11:16 /dev/nbd0p5 # mount /dev/nbd0p1 /mnt # ls /mnt bin dev initrd lost+found opt sbin sys var boot etc initrd.img media proc selinux tmp vmlinuz cdrom home lib mnt root srv usr # umount /mnt # nbd-client -d /dev/nbd0 # ls -l /dev/nbd0* brw-rw---- 1 root disk 43, 0 2008-03-25 11:16 /dev/nbd0 -------NOTE On "nbd-client -d", we can do an iocl(BLKRRPART) to update partition table: as the size of the device is 0, we don't have to serve the partition manager request (-> no deadlock). -------NOTE Signed-off-by: Paul Clements <paul.clements@steeleye.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/nbd.c')
-rw-r--r--drivers/block/nbd.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 8e33de6bea33..a3da198ca429 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -56,6 +56,7 @@ static unsigned int debugflags;
56 56
57static unsigned int nbds_max = 16; 57static unsigned int nbds_max = 16;
58static struct nbd_device *nbd_dev; 58static struct nbd_device *nbd_dev;
59static int max_part;
59 60
60/* 61/*
61 * Use just one lock (or at most 1 per NIC). Two arguments for this: 62 * Use just one lock (or at most 1 per NIC). Two arguments for this:
@@ -610,10 +611,13 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
610 error = -EINVAL; 611 error = -EINVAL;
611 file = fget(arg); 612 file = fget(arg);
612 if (file) { 613 if (file) {
614 struct block_device *bdev = inode->i_bdev;
613 inode = file->f_path.dentry->d_inode; 615 inode = file->f_path.dentry->d_inode;
614 if (S_ISSOCK(inode->i_mode)) { 616 if (S_ISSOCK(inode->i_mode)) {
615 lo->file = file; 617 lo->file = file;
616 lo->sock = SOCKET_I(inode); 618 lo->sock = SOCKET_I(inode);
619 if (max_part > 0)
620 bdev->bd_invalidated = 1;
617 error = 0; 621 error = 0;
618 } else { 622 } else {
619 fput(file); 623 fput(file);
@@ -663,6 +667,8 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
663 lo->bytesize = 0; 667 lo->bytesize = 0;
664 inode->i_bdev->bd_inode->i_size = 0; 668 inode->i_bdev->bd_inode->i_size = 0;
665 set_capacity(lo->disk, 0); 669 set_capacity(lo->disk, 0);
670 if (max_part > 0)
671 ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0);
666 return lo->harderror; 672 return lo->harderror;
667 case NBD_CLEAR_QUE: 673 case NBD_CLEAR_QUE:
668 /* 674 /*
@@ -696,6 +702,7 @@ static int __init nbd_init(void)
696{ 702{
697 int err = -ENOMEM; 703 int err = -ENOMEM;
698 int i; 704 int i;
705 int part_shift;
699 706
700 BUILD_BUG_ON(sizeof(struct nbd_request) != 28); 707 BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
701 708
@@ -703,8 +710,17 @@ static int __init nbd_init(void)
703 if (!nbd_dev) 710 if (!nbd_dev)
704 return -ENOMEM; 711 return -ENOMEM;
705 712
713 if (max_part < 0) {
714 printk(KERN_CRIT "nbd: max_part must be >= 0\n");
715 return -EINVAL;
716 }
717
718 part_shift = 0;
719 if (max_part > 0)
720 part_shift = fls(max_part);
721
706 for (i = 0; i < nbds_max; i++) { 722 for (i = 0; i < nbds_max; i++) {
707 struct gendisk *disk = alloc_disk(1); 723 struct gendisk *disk = alloc_disk(1 << part_shift);
708 elevator_t *old_e; 724 elevator_t *old_e;
709 if (!disk) 725 if (!disk)
710 goto out; 726 goto out;
@@ -748,10 +764,9 @@ static int __init nbd_init(void)
748 nbd_dev[i].blksize = 1024; 764 nbd_dev[i].blksize = 1024;
749 nbd_dev[i].bytesize = 0; 765 nbd_dev[i].bytesize = 0;
750 disk->major = NBD_MAJOR; 766 disk->major = NBD_MAJOR;
751 disk->first_minor = i; 767 disk->first_minor = i << part_shift;
752 disk->fops = &nbd_fops; 768 disk->fops = &nbd_fops;
753 disk->private_data = &nbd_dev[i]; 769 disk->private_data = &nbd_dev[i];
754 disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
755 sprintf(disk->disk_name, "nbd%d", i); 770 sprintf(disk->disk_name, "nbd%d", i);
756 set_capacity(disk, 0); 771 set_capacity(disk, 0);
757 add_disk(disk); 772 add_disk(disk);
@@ -789,7 +804,9 @@ MODULE_DESCRIPTION("Network Block Device");
789MODULE_LICENSE("GPL"); 804MODULE_LICENSE("GPL");
790 805
791module_param(nbds_max, int, 0444); 806module_param(nbds_max, int, 0444);
792MODULE_PARM_DESC(nbds_max, "How many network block devices to initialize."); 807MODULE_PARM_DESC(nbds_max, "number of network block devices to initialize (default: 16)");
808module_param(max_part, int, 0444);
809MODULE_PARM_DESC(max_part, "number of partitions per device (default: 0)");
793#ifndef NDEBUG 810#ifndef NDEBUG
794module_param(debugflags, int, 0644); 811module_param(debugflags, int, 0644);
795MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); 812MODULE_PARM_DESC(debugflags, "flags for controlling debug output");