Re: init scripts problems ?

"denis.bonnenfant" <[email protected]> Tue, 06 Dec 2005 14:53:31 +0100
Newsgroups gmane.linux.enbd.general
Message-ID <[email protected]>
Peter T. Breuer a écrit :

>"Also sprach denis.bonnenfant:"
>  
>
>>I tested the last patch, and it works really well.
>>    
>>
>
>I still see the problem here (2.6.3) so if you could make a diff -u of
>your code against the original archive enbd_base.c and send it to me,
>that would be very helpful to my understanding.
>  
>
here it is,

I will test it again to be sure.

--- nbd-2.4.32/kernel/linux-2.6.x/drivers/block/enbd/enbd_base.c	2005-11-28 19:42:53.000000000 +0100
+++ ../nbd-2.4.32/kernel/linux-2.6.x/drivers/block/enbd/enbd_base.c	2005-12-05 20:14:59.000000000 +0100
@@ -2640,11 +2640,13 @@
 
 		if (lo->aslot <= 0) {
 			// PTB we were the last client alive, diasable device
+                       do_reset = 1; // PTB do it, show_errs or not!
 			if (atomic_read (&lo->flags) & ENBD_SHOW_ERRS) {
 				// PTB soft_reset will invalidate_buffers
 			        atomic_clear_mask (ENBD_ENABLED, &lo->flags);
-                                do_reset = 1;
-			}
+			} else {
+                                do_enable = 1; // PTB case no show_errs
+                       }
 		} else if (!(atomic_read (&lo->flags) & ENBD_ENABLED)) {
 			// PTB must not call reenable as that clears the queue
                         do_enable = 1;
@@ -2794,7 +2796,18 @@
 
 	if (islot >= lo->nslot) {
 		lo->nslot = islot + 1;
-		ENBD_INFO ("increased socket count to %d\n", lo->nslot);
+		ENBD_INFO ("increased socket count on nd%s to %d\n",
+                        lo->devnam, lo->nslot);
+                if (lo->nslot == 1) {
+                        if (lo->inode && lo->inode->i_bdev) {
+		                ENBD_INFO ("upping openers count on nd%s\n",
+                                        lo->devnam);
+                                lo->inode->i_bdev->bd_openers++;
+                        } else {
+	                        ENBD_ALERT ("missing inode(%p) or bd on nd%s\n",
+                                   lo->inode, lo->devnam);
+                        }
+                }
 	}
 
 	lo->harderror = 0;
@@ -3203,14 +3216,13 @@
 
 
 /*
- * PTB - reset the enabled flag on a device and then clear all queues
- * ( call without the spinlock held )  and then enable again.
+ * PTB - reset the enabled flag on a device.
  */
 static void
 enbd_reenable (struct enbd_device *lo)
 {
 
-	int m, n;
+	//int m, n;
 
 	if (!(atomic_read (&lo->flags) & ENBD_INITIALISED))
 		return;
@@ -3219,16 +3231,15 @@
         if ((atomic_read (&lo->flags) & ENBD_ENABLED))
                 return;
 
-	m = enbd_clr_queue (lo);
+	//m = enbd_clr_queue (lo);
 	// PTB - have to call clr_kernel_queue without the io_spinlock held
-	n = enbd_clr_kernel_queue (lo);
+	//n = enbd_clr_kernel_queue (lo);
 
         enbd_enable(lo);
 }
 
 /*
- *  This function launches a thread which wakes for a signal to reenable
- *  the device, and then sets the timer to deleiver the signal.
+ *  This function sets the timer to reenable the device.
  */
 static int
 enbd_reenable_delay (struct enbd_device *lo, int delay)
@@ -3252,7 +3263,9 @@
 enbd_soft_reset (struct enbd_device *lo)
 {
 	int j;
+       int do_flush_requests_after_invalidate = 1;
         const int max_clrq_retries = 100;
+
 	if (!(atomic_read (&lo->flags) & ENBD_INITIALISED) || lo->nslot <= 0) {
 		return -EINVAL;
 	}
@@ -3278,17 +3291,35 @@
         * PTB put back invalidate buffers for use when called from
 	 * clr_sock from enbd_release on request of Rogier Wolff. FIXME.
         */
-        ENBD_ALERT("INVALIDATE DEVICE nd%s\n", lo->devnam);
+        if (1) {
+                struct inode *inode = lo->inode;
+                struct block_device *bdev = inode ? inode->i_bdev : NULL;
+                struct inode *inodetoo = bdev ? bdev->bd_inode : NULL;
+
+                ENBD_ALERT("INVALIDATE DEVICE nd%s BEGIN\n", lo->devnam);
+                if (!inodetoo || inode != inodetoo) {
+                        ENBD_ALERT(
+                            "invalidate would crash on device %p with inode %p\n",
+                            bdev, inodetoo);
+                        ENBD_ALERT( "aborting invalidate\n");
+                        do_flush_requests_after_invalidate = 0;
+                } else {
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
         __invalidate_device(lo->inode->i_bdev, 0);
 #else
         __invalidate_device(lo->inode->i_bdev);
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) */
+                        ENBD_ALERT("INVALIDATE DEVICE nd%s DONE\n", lo->devnam);
+                }
+        }
+
+        if (do_flush_requests_after_invalidate) {
 
-        if (1) {
                 struct inode *inode = lo->inode;
                 struct block_device *bdev = inode ? inode->i_bdev : NULL;
                 request_queue_t * q; 
+
                 if (!bdev)
                         return 0;
                 q = bdev_get_queue (bdev); 
@@ -3759,6 +3790,17 @@
 	return -1;
 }
 
+static void
+print_slot_pids (struct enbd_device *lo)
+{
+        int i;
+        for (i = 0; i < lo->nslot; i++) {
+                struct enbd_slot * slot =  &lo->slots[i];
+                ENBD_INFO
+                ("device nd%s%d has pid %d\n", lo->devnam, i+1, slot->pid);
+        }
+}
+
 static int
 fixup_slot (struct enbd_device *lo, unsigned int cmd, unsigned long *arg)
 {
@@ -3771,11 +3813,9 @@
 	  case MY_NBD_CLR_REQ:
 	  case MY_NBD_ERR_REQ:
 		// see if we match a known slot pid
-		if (arg && *arg == 0) {
-			islot = find_slot (lo, current->pid);
-			if (islot >= 0)
-				return islot;
-		}
+		islot = find_slot (lo, current->pid); // PTB don't check arg
+		if (islot >= 0)
+			return islot;
 		ENBD_ALERT
 		 ("failed to find slot for pid %d for ioctl %s arg %lx\n",
 		  current->pid,
@@ -3784,6 +3824,7 @@
                   cmd == MY_NBD_ERR_REQ? "MY_NBD_ERR_REQ" :
                   "UNKNOWN",
                   arg ? *arg : 0);
+               print_slot_pids(lo);
 		return islot = -1;
 		break;
 
@@ -3811,6 +3852,7 @@
                   cmd == MY_NBD_SET_SPID? "MY_NBD_SET_SPID" :
                   "UNKNOWN",
                   arg ? *arg : 0);
+               print_slot_pids(lo);
 		return islot = -1;
 		break;
 
@@ -3826,6 +3868,7 @@
                   cmd == MY_NBD_ACK? "MY_NBD_ACK" :
                   "UNKNOWN",
                   arg ? *arg : 0);
+               print_slot_pids(lo);
 	        return islot;
 		break;
 
@@ -3863,7 +3906,8 @@
                                 cmd == MY_NBD_SET_SIG? "MY_NBD_SET_SIG" :
                                 "UNKNOWN",
                                 *arg, intval);
-			return islot = -1;
+		   print_slot_pids(lo);
+		   return islot = -1;
 		}
 		islot = intval - 1;
 
@@ -4981,13 +5025,20 @@
         }
         atomic_clear_mask(ENBD_ENABLED, &lo->flags);
         atomic_clear_mask(ENBD_VALIDATED, &lo->flags);
+        ENBD_INFO("set INVALID on nd%s\n", lo->devnam);
         // PTB clear SIGNED suggested by Dag Sverre Seljebotn */
         atomic_clear_mask(ENBD_SIGNED, &lo->flags);
         lo->nslot = 0;
+        if (lo->inode && lo->inode->i_bdev) {
+	        ENBD_INFO ("downing openers count on nd%s\n", lo->devnam);
+                                lo->inode->i_bdev->bd_openers--;
+        } else {
+	        ENBD_ALERT ("missing inode (%p) or bdev on nd%s\n",
+                        lo->inode, lo->devnam);
+        }
         write_unlock(&lo->meta_lock);
-        ENBD_ALERT("set INVALID on nd%s\n", lo->devnam);
         //__invalidate_device(lo->inode->i_bdev, 0);
-        ENBD_ALERT ("reset device nd%s\n", lo->devnam);
+        ENBD_INFO ("reset device nd%s\n", lo->devnam);
 }
 
 static int