Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / drivers / md / md.c
index f7f1908..d1cb45f 100644 (file)
 #include <linux/raid/bitmap.h>
 #include <linux/sysctl.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
-#include <linux/suspend.h>
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/ctype.h>
+#include <linux/freezer.h>
 
 #include <linux/init.h>
 
@@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
  * version 1 superblock
  */
 
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
-       unsigned int disk_csum, csum;
+       __le32 disk_csum;
+       u32 csum;
        unsigned long long newcsum;
        int size = 256 + le32_to_cpu(sb->max_dev)*2;
-       unsigned int *isuper = (unsigned int*)sb;
+       __le32 *isuper = (__le32*)sb;
        int i;
 
        disk_csum = sb->sb_csum;
@@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
                newcsum += le32_to_cpu(*isuper++);
 
        if (size == 2)
-               newcsum += le16_to_cpu(*(unsigned short*) isuper);
+               newcsum += le16_to_cpu(*(__le16*) isuper);
 
        csum = (newcsum & 0xffffffff) + (newcsum >> 32);
        sb->sb_csum = disk_csum;
@@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        if (le32_to_cpu(sb->chunksize))
                rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
 
-       if (le32_to_cpu(sb->size) > rdev->size*2)
+       if (le64_to_cpu(sb->size) > rdev->size*2)
                return -EINVAL;
        return ret;
 }
@@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        else
                sb->resync_offset = cpu_to_le64(0);
 
-       sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+       sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
        sb->raid_disks = cpu_to_le32(mddev->raid_disks);
        sb->size = cpu_to_le64(mddev->size<<1);
@@ -1412,7 +1413,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
        struct block_device *bdev;
        char b[BDEVNAME_SIZE];
 
-       bdev = open_partition_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+       bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
        if (IS_ERR(bdev)) {
                printk(KERN_ERR "md: could not open %s.\n",
                        __bdevname(dev, b));
@@ -1422,7 +1423,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
        if (err) {
                printk(KERN_ERR "md: could not bd_claim %s.\n",
                        bdevname(bdev, b));
-               blkdev_put_partition(bdev);
+               blkdev_put(bdev);
                return err;
        }
        rdev->bdev = bdev;
@@ -1436,7 +1437,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
        if (!bdev)
                MD_BUG();
        bd_release(bdev);
-       blkdev_put_partition(bdev);
+       blkdev_put(bdev);
 }
 
 void md_autodetect_dev(dev_t dev);
@@ -1791,7 +1792,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                else {
                        mddev_t *mddev = rdev->mddev;
                        kick_rdev_from_array(rdev);
-                       md_update_sb(mddev, 1);
+                       if (mddev->pers)
+                               md_update_sb(mddev, 1);
                        md_new_event(mddev);
                        err = 0;
                }
@@ -2002,6 +2004,8 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
        kobject_init(&rdev->kobj);
 
        rdev->desc_nr = -1;
+       rdev->saved_raid_disk = -1;
+       rdev->raid_disk = -1;
        rdev->flags = 0;
        rdev->data_offset = 0;
        rdev->sb_events = 0;
@@ -2231,7 +2235,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks);
 static ssize_t
 raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
 {
-       /* can only set raid_disks if array is not yet active */
        char *e;
        int rv = 0;
        unsigned long n = simple_strtoul(buf, &e, 10);
@@ -2629,7 +2632,7 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
                return -EINVAL;
        buf = e+1;
        minor = simple_strtoul(buf, &e, 10);
-       if (e==buf || *e != '\n')
+       if (e==buf || (*e && *e != '\n') )
                return -EINVAL;
        if (major >= sizeof(super_types)/sizeof(super_types[0]) ||
            super_types[major].name == NULL)
@@ -3198,6 +3201,7 @@ static int do_md_run(mddev_t * mddev)
 
        mddev->changed = 1;
        md_new_event(mddev);
+       kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE);
        return 0;
 }
 
@@ -3311,6 +3315,10 @@ static int do_md_stop(mddev_t * mddev, int mode)
 
                        module_put(mddev->pers->owner);
                        mddev->pers = NULL;
+
+                       set_capacity(disk, 0);
+                       mddev->changed = 1;
+
                        if (mddev->ro)
                                mddev->ro = 0;
                }
@@ -3330,7 +3338,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
        if (mode == 0) {
                mdk_rdev_t *rdev;
                struct list_head *tmp;
-               struct gendisk *disk;
+
                printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
 
                bitmap_destroy(mddev);
@@ -3355,10 +3363,6 @@ static int do_md_stop(mddev_t * mddev, int mode)
                mddev->raid_disks = 0;
                mddev->recovery_cp = 0;
 
-               disk = mddev->gendisk;
-               if (disk)
-                       set_capacity(disk, 0);
-               mddev->changed = 1;
        } else if (mddev->pers)
                printk(KERN_INFO "md: %s switched to read-only mode.\n",
                        mdname(mddev));
@@ -3368,6 +3372,7 @@ out:
        return err;
 }
 
+#ifndef MODULE
 static void autorun_array(mddev_t *mddev)
 {
        mdk_rdev_t *rdev;
@@ -3482,6 +3487,7 @@ static void autorun_devices(int part)
        }
        printk(KERN_INFO "md: ... autorun DONE.\n");
 }
+#endif /* !MODULE */
 
 static int get_version(void __user * arg)
 {
@@ -3719,6 +3725,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                if (err)
                        export_rdev(rdev);
 
+               md_update_sb(mddev, 1);
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                md_wakeup_thread(mddev->thread);
                return err;
@@ -3974,6 +3981,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
                mddev->major_version = info->major_version;
                mddev->minor_version = info->minor_version;
                mddev->patch_version = info->patch_version;
+               mddev->persistent = !info->not_persistent;
                return 0;
        }
        mddev->major_version = MD_MAJOR_VERSION;
@@ -4043,11 +4051,8 @@ static int update_size(mddev_t *mddev, unsigned long size)
                return -EBUSY;
        ITERATE_RDEV(mddev,rdev,tmp) {
                sector_t avail;
-               if (rdev->sb_offset > rdev->data_offset)
-                       avail = (rdev->sb_offset*2) - rdev->data_offset;
-               else
-                       avail = get_capacity(rdev->bdev->bd_disk)
-                               - rdev->data_offset;
+               avail = rdev->size * 2;
+
                if (fit && (size == 0 || size > avail/2))
                        size = avail/2;
                if (avail < ((sector_t)size << 1))
@@ -4301,9 +4306,10 @@ static int md_ioctl(struct inode *inode, struct file *file,
         * Commands querying/configuring an existing array:
         */
        /* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY,
-        * RUN_ARRAY, and SET_BITMAP_FILE are allowed */
+        * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */
        if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
-                       && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) {
+                       && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE
+                       && cmd != GET_BITMAP_FILE) {
                err = -ENODEV;
                goto abort_unlock;
        }
@@ -4423,7 +4429,7 @@ static int md_open(struct inode *inode, struct file *file)
        mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
        int err;
 
-       if ((err = mddev_lock(mddev)))
+       if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1)))
                goto out;
 
        err = 0;
@@ -4486,6 +4492,7 @@ static int md_thread(void * arg)
         * many dirty RAID5 blocks.
         */
 
+       current->flags |= PF_NOFREEZE;
        allow_signal(SIGKILL);
        while (!kthread_should_stop()) {
 
@@ -4502,7 +4509,6 @@ static int md_thread(void * arg)
                         test_bit(THREAD_WAKEUP, &thread->flags)
                         || kthread_should_stop(),
                         thread->timeout);
-               try_to_freeze();
 
                clear_bit(THREAD_WAKEUP, &thread->flags);
 
@@ -4846,8 +4852,8 @@ static int md_seq_show(struct seq_file *seq, void *v)
                                chunk_kb ? "KB" : "B");
                        if (bitmap->file) {
                                seq_printf(seq, ", file: ");
-                               seq_path(seq, bitmap->file->f_vfsmnt,
-                                        bitmap->file->f_dentry," \t\n");
+                               seq_path(seq, bitmap->file->f_path.mnt,
+                                        bitmap->file->f_path.dentry," \t\n");
                        }
 
                        seq_printf(seq, "\n");
@@ -5273,7 +5279,6 @@ void md_do_sync(mddev_t *mddev)
        mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);
 
        if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
-           test_bit(MD_RECOVERY_SYNC, &mddev->recovery) &&
            !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
            mddev->curr_resync > 2) {
                if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
@@ -5297,6 +5302,7 @@ void md_do_sync(mddev_t *mddev)
                                        rdev->recovery_offset = mddev->curr_resync;
                }
        }
+       set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
  skip:
        mddev->curr_resync = 0;
@@ -5593,7 +5599,7 @@ static void autostart_arrays(int part)
        autorun_devices(part);
 }
 
-#endif
+#endif /* !MODULE */
 
 static __exit void md_exit(void)
 {