]> err.no Git - linux-2.6/blobdiff - drivers/md/md.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / md / md.c
index 147efcb1e8ca55df300c82020c17b1acdeb6b46c..d7316b829a62687a4c29372a893d2684121fb3a3 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/suspend.h>
 #include <linux/poll.h>
+#include <linux/mutex.h>
 
 #include <linux/init.h>
 
@@ -162,6 +163,7 @@ void md_new_event(mddev_t *mddev)
 {
        atomic_inc(&md_event_count);
        wake_up(&md_event_waiters);
+       sysfs_notify(&mddev->kobj, NULL, "sync_action");
 }
 EXPORT_SYMBOL_GPL(md_new_event);
 
@@ -214,13 +216,11 @@ static void mddev_put(mddev_t *mddev)
                return;
        if (!mddev->raid_disks && list_empty(&mddev->disks)) {
                list_del(&mddev->all_mddevs);
-               /* that blocks */
+               spin_unlock(&all_mddevs_lock);
                blk_cleanup_queue(mddev->queue);
-               /* that also blocks */
                kobject_unregister(&mddev->kobj);
-               /* result blows... */
-       }
-       spin_unlock(&all_mddevs_lock);
+       } else
+               spin_unlock(&all_mddevs_lock);
 }
 
 static mddev_t * mddev_find(dev_t unit)
@@ -254,7 +254,7 @@ static mddev_t * mddev_find(dev_t unit)
        else
                new->md_minor = MINOR(unit) >> MdpMinorShift;
 
-       init_MUTEX(&new->reconfig_sem);
+       mutex_init(&new->reconfig_mutex);
        INIT_LIST_HEAD(&new->disks);
        INIT_LIST_HEAD(&new->all_mddevs);
        init_timer(&new->safemode_timer);
@@ -276,22 +276,17 @@ static mddev_t * mddev_find(dev_t unit)
 
 static inline int mddev_lock(mddev_t * mddev)
 {
-       return down_interruptible(&mddev->reconfig_sem);
-}
-
-static inline void mddev_lock_uninterruptible(mddev_t * mddev)
-{
-       down(&mddev->reconfig_sem);
+       return mutex_lock_interruptible(&mddev->reconfig_mutex);
 }
 
 static inline int mddev_trylock(mddev_t * mddev)
 {
-       return down_trylock(&mddev->reconfig_sem);
+       return mutex_trylock(&mddev->reconfig_mutex);
 }
 
 static inline void mddev_unlock(mddev_t * mddev)
 {
-       up(&mddev->reconfig_sem);
+       mutex_unlock(&mddev->reconfig_mutex);
 
        md_wakeup_thread(mddev->thread);
 }
@@ -2458,9 +2453,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
        if (!entry->show)
                return -EIO;
-       mddev_lock(mddev);
-       rv = entry->show(mddev, page);
-       mddev_unlock(mddev);
+       rv = mddev_lock(mddev);
+       if (!rv) {
+               rv = entry->show(mddev, page);
+               mddev_unlock(mddev);
+       }
        return rv;
 }
 
@@ -2474,9 +2471,11 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
 
        if (!entry->store)
                return -EIO;
-       mddev_lock(mddev);
-       rv = entry->store(mddev, page, length);
-       mddev_unlock(mddev);
+       rv = mddev_lock(mddev);
+       if (!rv) {
+               rv = entry->store(mddev, page, length);
+               mddev_unlock(mddev);
+       }
        return rv;
 }
 
@@ -2500,7 +2499,7 @@ int mdp_major = 0;
 
 static struct kobject *md_probe(dev_t dev, int *part, void *data)
 {
-       static DECLARE_MUTEX(disks_sem);
+       static DEFINE_MUTEX(disks_mutex);
        mddev_t *mddev = mddev_find(dev);
        struct gendisk *disk;
        int partitioned = (MAJOR(dev) != MD_MAJOR);
@@ -2510,15 +2509,15 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        if (!mddev)
                return NULL;
 
-       down(&disks_sem);
+       mutex_lock(&disks_mutex);
        if (mddev->gendisk) {
-               up(&disks_sem);
+               mutex_unlock(&disks_mutex);
                mddev_put(mddev);
                return NULL;
        }
        disk = alloc_disk(1 << shift);
        if (!disk) {
-               up(&disks_sem);
+               mutex_unlock(&disks_mutex);
                mddev_put(mddev);
                return NULL;
        }
@@ -2536,7 +2535,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        disk->queue = mddev->queue;
        add_disk(disk);
        mddev->gendisk = disk;
-       up(&disks_sem);
+       mutex_unlock(&disks_mutex);
        mddev->kobj.parent = &disk->kobj;
        mddev->kobj.k_name = NULL;
        snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
@@ -4341,8 +4340,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
 
-       if (mddev_lock(mddev)!=0) 
+       if (mddev_lock(mddev) < 0)
                return -EINTR;
+
        if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
                seq_printf(seq, "%s : %sactive", mdname(mddev),
                                                mddev->pers ? "" : "in");
@@ -4892,7 +4892,7 @@ void md_check_recovery(mddev_t *mddev)
                ))
                return;
 
-       if (mddev_trylock(mddev)==0) {
+       if (mddev_trylock(mddev)) {
                int spares =0;
 
                spin_lock_irq(&mddev->write_lock);
@@ -5028,7 +5028,7 @@ static int md_notify_reboot(struct notifier_block *this,
                printk(KERN_INFO "md: stopping all md devices.\n");
 
                ITERATE_MDDEV(mddev,tmp)
-                       if (mddev_trylock(mddev)==0)
+                       if (mddev_trylock(mddev))
                                do_md_stop (mddev, 1);
                /*
                 * certain more exotic SCSI devices are known to be