[LWN Logo]

Date:	Wed, 10 May 2000 20:47:28 +0200
From:	Christoph Hellwig <chhellwig@gmx.net>
To:	linux-kernel@vger.rutgers.edu
Subject: [PATCH] devfs support for LVM (2.3.99pre7-8)

Hi,
this patch support devfs for the LVM. With this patch your root partition
doesn't have to be mounted rw for vgchange (with the appended patch).
If you use an unpatched version of vgchange it will print 
'devfs: devfs_register(): device already registered: "<lvol>"'
for every logical volume and
'devfs: devfs_register(): device already registered: "group"'
for every volume group, because vgchange tries to create them manually.


	Christoph

-- 
Always remember that you are unique.  Just like everyone else.


diff -rNu --exclude-from=/usr/src/exclude linux.orig/drivers/block/lvm.c linux/drivers/block/lvm.c
--- linux.orig/drivers/block/lvm.c	Fri May  5 15:36:14 2000
+++ linux/drivers/block/lvm.c	Wed May 10 20:36:51 2000
@@ -123,6 +123,7 @@
  *               - avoided inline strings functions lvm_strlen etc.
  *    14/02/2000 - support for 2.3.43
  *               - integrated Andrea Arcagnelli's snapshot code
+ *    01/05/2000 - added devfs support (Christoph Hellwig)
  *
  */
 
@@ -300,6 +301,11 @@
 static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t lvm_snapshot_lock = SPIN_LOCK_UNLOCKED;
 
+static devfs_handle_t lvm_devfs_handle;
+static devfs_handle_t vg_devfs_handle[MAX_VG];
+static devfs_handle_t ch_devfs_handle[MAX_VG];
+static devfs_handle_t lv_devfs_handle[MAX_LV];
+
 static struct file_operations lvm_chr_fops =
 {
 	open:		lvm_chr_open,
@@ -366,21 +372,22 @@
 {
 	struct gendisk *gendisk_ptr = NULL;
 
-	if (register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
+	if (devfs_register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
 		printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
 		return -EIO;
 	}
-#ifdef BLOCK_DEVICE_OPERATIONS
-	if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0)
-#else
-	if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_fops) < 0)
-#endif
-	{
+	if (devfs_register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0) {
 		printk("%s -- register_blkdev failed\n", lvm_name);
-		if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
+		if (devfs_unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
 			printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
 		return -EIO;
 	}
+	
+	lvm_devfs_handle = devfs_register(
+		0 , "lvm", 0, 0, LVM_CHAR_MAJOR, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+		0, 0, &lvm_chr_fops, NULL);
+
 #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
 	create_proc_info_entry(LVM_NAME, S_IFREG | S_IRUGO,
 			       &proc_root, lvm_proc_get_info_ptr);
@@ -437,10 +444,12 @@
 {
 	struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
 
-	if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
+	devfs_unregister (lvm_devfs_handle);
+
+	if (devfs_unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
 		printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
 	}
-	if (unregister_blkdev(MAJOR_NR, lvm_name) < 0) {
+	if (devfs_unregister_blkdev(MAJOR_NR, lvm_name) < 0) {
 		printk(KERN_ERR "%s -- unregister_blkdev failed\n", lvm_name);
 	}
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
@@ -1657,6 +1666,14 @@
 		kfree(vg_ptr);
 		return -EFAULT;
 	}
+
+	vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, 0, NULL);
+	ch_devfs_handle[vg_ptr->vg_number] = devfs_register(
+		vg_devfs_handle[vg_ptr->vg_number] , "group", 0,
+		DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+		0, 0, &lvm_chr_fops, NULL);
+
 	/* we are not that active so far... */
 	vg_ptr->vg_status &= ~VG_ACTIVE;
 	vg[VG_CHR(minor)] = vg_ptr;
@@ -1884,6 +1901,9 @@
 	/* let's go inactive */
 	vg_ptr->vg_status &= ~VG_ACTIVE;
 
+	devfs_unregister (ch_devfs_handle[vg_ptr->vg_number]);
+	devfs_unregister (vg_devfs_handle[vg_ptr->vg_number]);
+
 	/* free LVs */
 	/* first free snapshot logical volumes */
 	for (i = 0; i < vg_ptr->lv_max; i++) {
@@ -1939,6 +1959,7 @@
 {
 	int l, le, l_new, p, size;
 	ulong lv_status_save;
+	char *lv_tmp, *lv_buf;
 	lv_block_exception_t *lvbe = lv->lv_block_exception;
 	vg_t *vg_ptr = vg[VG_CHR(minor)];
 	lv_t *lv_ptr = NULL;
@@ -2094,6 +2115,17 @@
 	vg_ptr->lv_cur++;
 	lv_ptr->lv_status = lv_status_save;
 
+	strtok(lv->lv_name, "/");	/* /dev */
+
+	while((lv_tmp = strtok(NULL, "/")) != NULL)
+		lv_buf = lv_tmp;
+
+	lv_devfs_handle[lv->lv_number] = devfs_register(
+		vg_devfs_handle[vg_ptr->vg_number], lv_buf, 0,
+		DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, lv->lv_number,
+		S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
+		0, 0, &lvm_blk_dops, NULL);
+
 	/* optionally add our new snapshot LV */
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		/* sync the original logical volume */
@@ -2185,6 +2217,8 @@
 			lv_ptr->lv_snapshot_org->lv_access &= ~LV_SNAPSHOT_ORG;
 		lvm_snapshot_release(lv_ptr);
 	}
+
+	devfs_unregister(lv_devfs_handle[lv_ptr->lv_number]);
 
 #ifdef DEBUG_KFREE
 	printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-------------------------------- snip --------------------------------

diff -rNu lvm-tools-aa-20000119.orig/tools/lib/lv_create_node.c lvm-tools-aa-20000119/tools/lib/lv_create_node.c
--- lvm-tools-aa-20000119.orig/tools/lib/lv_create_node.c	Fri Jan  7 00:45:32 2000
+++ lvm-tools-aa-20000119/tools/lib/lv_create_node.c	Sat Apr  8 12:45:00 2000
@@ -38,7 +38,7 @@
 
 int lv_create_node ( lv_t *lv) {
    int ret = 0;
-
+#if 0
 #ifdef DEBUG
    debug ( "lv_create_node -- CALLED\n");
 #endif
@@ -63,6 +63,7 @@
 lv_create_node_end:
 #ifdef DEBUG
    debug ( "lv_create_node -- LEAVING with %d\n", ret);
+#endif
 #endif
    return ret;
 }
diff -rNu lvm-tools-aa-20000119.orig/tools/lib/lvm_check_special.c lvm-tools-aa-20000119/tools/lib/lvm_check_special.c
--- lvm-tools-aa-20000119.orig/tools/lib/lvm_check_special.c	Fri Jan  7 00:45:35 2000
+++ lvm-tools-aa-20000119/tools/lib/lvm_check_special.c	Sat Apr  8 22:26:14 2000
@@ -27,6 +27,7 @@
 #include <liblvm.h>
 
 void lvm_check_special ( void) {
+#if 0
    int create = FALSE;
    struct stat stat_buf;
 
@@ -41,4 +42,5 @@
               S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
               LVM_CHAR_MAJOR << MINORBITS);
    }
+#endif
 }
diff -rNu lvm-tools-aa-20000119.orig/tools/lib/vg_create_dir_and_group.c lvm-tools-aa-20000119/tools/lib/vg_create_dir_and_group.c
--- lvm-tools-aa-20000119.orig/tools/lib/vg_create_dir_and_group.c	Fri Jan  7 00:45:45 2000
+++ lvm-tools-aa-20000119/tools/lib/vg_create_dir_and_group.c	Sat Apr  8 22:28:01 2000
@@ -41,7 +41,7 @@
 int vg_create_dir_and_group ( vg_t *vg) {
    int ret = 0;
    char name[NAME_LEN];
-
+#if 0
 #ifdef DEBUG
    debug ( "vg_create_dir_and_group -- CALLED\n");
 #endif
@@ -69,6 +69,7 @@
 
 #ifdef DEBUG
    debug ( "vg_create_dir_and_group -- LEAVING\n");
+#endif
 #endif
    return ret;
 }
diff -rNu lvm-tools-aa-20000119.orig/tools/lib/vg_remove_dir_and_group_and_nodes.c lvm-tools-aa-20000119/tools/lib/vg_remove_dir_and_group_and_nodes.c
--- lvm-tools-aa-20000119.orig/tools/lib/vg_remove_dir_and_group_and_nodes.c	Fri Jan  7 00:45:47 2000
+++ lvm-tools-aa-20000119/tools/lib/vg_remove_dir_and_group_and_nodes.c	Sun Apr  9 17:03:53 2000
@@ -27,6 +27,7 @@
 #include <liblvm.h>
 
 int vg_remove_dir_and_group_and_nodes ( char *vg_name) {
+#if 0
    char system_buffer[NAME_LEN+20];
 
 #ifdef DEBUG
@@ -43,5 +44,8 @@
 #endif
 
    return system ( system_buffer);
+#else
+   return 0;
+#endif
 }
    

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/