PATCH - md 21 of 22 - Improve handling of MD super blocks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





1/ don't free the rdev->sb on an error -- it might be
   accessed again later.  Just wait for the device to be
   exported.
2/ Change md_update_sb to __md_update_sb and have it 
   clear the sb_dirty flag.
   New md_update_sb locks the device and calls __md_update_sb
   if sb_dirty.  This avoids any possbile races around 
   updating the superblock


 ----------- Diffstat output ------------
 ./drivers/md/md.c         |   31 ++++++++++++++++++-------------
 ./drivers/md/multipath.c  |    1 -
 ./drivers/md/raid1.c      |    1 -
 ./drivers/md/raid5.c      |    4 +---
 ./include/linux/raid/md.h |    2 +-
 5 files changed, 20 insertions(+), 19 deletions(-)

--- ./drivers/md/md.c	2002/06/18 06:05:22	1.20
+++ ./drivers/md/md.c	2002/06/18 06:08:03	1.21
@@ -921,12 +921,13 @@
 	return 0;
 }
 
-int md_update_sb(mddev_t * mddev)
+void __md_update_sb(mddev_t * mddev)
 {
 	int err, count = 100;
 	struct list_head *tmp;
 	mdk_rdev_t *rdev;
 
+	mddev->sb_dirty = 0;
 repeat:
 	mddev->sb->utime = CURRENT_TIME;
 	if (!(++mddev->sb->events_lo))
@@ -948,7 +949,7 @@
 	 * nonpersistent superblocks
 	 */
 	if (mddev->sb->not_persistent)
-		return 0;
+		return;
 
 	printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
 					mdidx(mddev));
@@ -976,9 +977,18 @@
 		}
 		printk(KERN_ERR "md: excessive errors occurred during superblock update, exiting\n");
 	}
-	return 0;
 }
 
+void md_update_sb(mddev_t *mddev)
+{
+	if (mddev_lock(mddev))
+		return;
+	if (mddev->sb_dirty)
+		__md_update_sb(mddev);
+	mddev_unlock(mddev);
+}
+
+
 /*
  * Import a device. If 'on_disk', then sanity check the superblock
  *
@@ -1648,7 +1658,7 @@
 	}
 
 	mddev->sb->state &= ~(1 << MD_SB_CLEAN);
-	md_update_sb(mddev);
+	__md_update_sb(mddev);
 
 	/*
 	 * md_size has units of 1K blocks, which are
@@ -1770,7 +1780,7 @@
 				printk(KERN_INFO "md: marking sb clean...\n");
 				mddev->sb->state |= 1 << MD_SB_CLEAN;
 			}
-			md_update_sb(mddev);
+			__md_update_sb(mddev);
 		}
 		if (ro)
 			set_device_ro(dev, 1);
@@ -2281,8 +2291,7 @@
 
 	remove_descriptor(disk, mddev->sb);
 	kick_rdev_from_array(rdev);
-	mddev->sb_dirty = 1;
-	md_update_sb(mddev);
+	__md_update_sb(mddev);
 
 	return 0;
 busy:
@@ -2393,9 +2402,7 @@
 	mddev->sb->spare_disks++;
 	mddev->sb->working_disks++;
 
-	mddev->sb_dirty = 1;
-
-	md_update_sb(mddev);
+	__md_update_sb(mddev);
 
 	/*
 	 * Kick recovery, maybe this spare has to be added to the
@@ -2918,7 +2925,6 @@
 		return 0;
 	if (!mddev->pers->error_handler
 			|| mddev->pers->error_handler(mddev,rdev) <= 0) {
-		free_disk_sb(rrdev);
 		rrdev->faulty = 1;
 	} else
 		return 1;
@@ -3423,8 +3429,7 @@
 			sb->active_disks++;
 			sb->spare_disks--;
 		}
-		mddev->sb_dirty = 1;
-		md_update_sb(mddev);
+		__md_update_sb(mddev);
 		mddev->recovery_running = 0;
 	unlock:
 		mddev_unlock(mddev);
--- ./drivers/md/raid5.c	2002/06/18 05:29:05	1.7
+++ ./drivers/md/raid5.c	2002/06/18 06:08:03	1.8
@@ -1335,10 +1335,8 @@
 
 	handled = 0;
 
-	if (mddev->sb_dirty) {
-		mddev->sb_dirty = 0;
+	if (mddev->sb_dirty)
 		md_update_sb(mddev);
-	}
 	spin_lock_irq(&conf->device_lock);
 	while (1) {
 		struct list_head *first;
--- ./drivers/md/raid1.c	2002/06/18 05:29:05	1.3
+++ ./drivers/md/raid1.c	2002/06/18 06:08:03	1.4
@@ -1084,7 +1084,6 @@
 		conf = mddev_to_conf(mddev);
 		if (mddev->sb_dirty) {
 			printk(KERN_INFO "raid1: dirty sb detected, updating.\n");
-			mddev->sb_dirty = 0;
 			md_update_sb(mddev);
 		}
 		bio = r1_bio->master_bio;
--- ./drivers/md/multipath.c	2002/06/18 04:18:35	1.2
+++ ./drivers/md/multipath.c	2002/06/18 06:08:03	1.3
@@ -699,7 +699,6 @@
 		mddev = mp_bh->mddev;
 		if (mddev->sb_dirty) {
 			printk(KERN_INFO "dirty sb detected, updating.\n");
-			mddev->sb_dirty = 0;
 			md_update_sb(mddev);
 		}
 		bio = mp_bh->bio;
--- ./include/linux/raid/md.h	2002/06/18 04:37:53	1.3
+++ ./include/linux/raid/md.h	2002/06/18 06:08:03	1.4
@@ -75,7 +75,7 @@
 extern void md_unregister_thread (mdk_thread_t *thread);
 extern void md_wakeup_thread(mdk_thread_t *thread);
 extern void md_interrupt_thread (mdk_thread_t *thread);
-extern int md_update_sb (mddev_t *mddev);
+extern void md_update_sb (mddev_t *mddev);
 extern int md_do_sync(mddev_t *mddev, mdp_disk_t *spare);
 extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
 extern void md_sync_acct(kdev_t dev, unsigned long nr_sectors);
-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux