]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/md/md.c
md: pass mddev to make_request functions rather than request_queue
[mirror_ubuntu-jammy-kernel.git] / drivers / md / md.c
index 69f2a8e6ccdfa56061893c02e690c73a4c1f2265..2e05b0c2515d2a5d57d6585c06aca0eb9c85cf60 100644 (file)
@@ -240,7 +240,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
        atomic_inc(&mddev->active_io);
        rcu_read_unlock();
 
-       rv = mddev->pers->make_request(q, bio);
+       rv = mddev->pers->make_request(mddev, bio);
 
        cpu = part_stat_lock();
        part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
@@ -354,7 +354,7 @@ static void md_submit_barrier(struct work_struct *ws)
                bio_endio(bio, 0);
        else {
                bio->bi_rw &= ~(1<<BIO_RW_BARRIER);
-               if (mddev->pers->make_request(mddev->queue, bio))
+               if (mddev->pers->make_request(mddev, bio))
                        generic_make_request(bio);
                mddev->barrier = POST_REQUEST_BARRIER;
                submit_barriers(mddev);
@@ -3309,6 +3309,7 @@ array_state_show(mddev_t *mddev, char *page)
 }
 
 static int do_md_stop(mddev_t * mddev, int ro, int is_open);
+static int md_set_readonly(mddev_t * mddev, int is_open);
 static int do_md_run(mddev_t * mddev);
 static int restart_array(mddev_t *mddev);
 
@@ -3339,7 +3340,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                break; /* not supported yet */
        case readonly:
                if (mddev->pers)
-                       err = do_md_stop(mddev, 1, 0);
+                       err = md_set_readonly(mddev, 0);
                else {
                        mddev->ro = 1;
                        set_disk_ro(mddev->gendisk, 1);
@@ -3349,7 +3350,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
        case read_auto:
                if (mddev->pers) {
                        if (mddev->ro == 0)
-                               err = do_md_stop(mddev, 1, 0);
+                               err = md_set_readonly(mddev, 0);
                        else if (mddev->ro == 1)
                                err = restart_array(mddev);
                        if (err == 0) {
@@ -4297,11 +4298,10 @@ static void md_safemode_timeout(unsigned long data)
 
 static int start_dirty_degraded;
 
-static int do_md_run(mddev_t * mddev)
+static int md_run(mddev_t *mddev)
 {
        int err;
        mdk_rdev_t *rdev;
-       struct gendisk *disk;
        struct mdk_personality *pers;
 
        if (list_empty(&mddev->disks))
@@ -4366,8 +4366,6 @@ static int do_md_run(mddev_t * mddev)
                sysfs_notify_dirent(rdev->sysfs_state);
        }
 
-       disk = mddev->gendisk;
-
        spin_lock(&pers_lock);
        pers = find_pers(mddev->level, mddev->clevel);
        if (!pers || !try_module_get(pers->owner)) {
@@ -4495,22 +4493,32 @@ static int do_md_run(mddev_t * mddev)
        if (mddev->flags)
                md_update_sb(mddev, 0);
 
-       set_capacity(disk, mddev->array_sectors);
-
        md_wakeup_thread(mddev->thread);
        md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 
-       revalidate_disk(mddev->gendisk);
-       mddev->changed = 1;
        md_new_event(mddev);
        sysfs_notify_dirent(mddev->sysfs_state);
        if (mddev->sysfs_action)
                sysfs_notify_dirent(mddev->sysfs_action);
        sysfs_notify(&mddev->kobj, NULL, "degraded");
-       kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
        return 0;
 }
 
+static int do_md_run(mddev_t *mddev)
+{
+       int err;
+
+       err = md_run(mddev);
+       if (err)
+               goto out;
+
+       set_capacity(mddev->gendisk, mddev->array_sectors);
+       revalidate_disk(mddev->gendisk);
+       kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
+out:
+       return err;
+}
+
 static int restart_array(mddev_t *mddev)
 {
        struct gendisk *disk = mddev->gendisk;
@@ -4561,9 +4569,109 @@ void restore_bitmap_write_access(struct file *file)
        spin_unlock(&inode->i_lock);
 }
 
+static void md_clean(mddev_t *mddev)
+{
+       mddev->array_sectors = 0;
+       mddev->external_size = 0;
+       mddev->dev_sectors = 0;
+       mddev->raid_disks = 0;
+       mddev->recovery_cp = 0;
+       mddev->resync_min = 0;
+       mddev->resync_max = MaxSector;
+       mddev->reshape_position = MaxSector;
+       mddev->external = 0;
+       mddev->persistent = 0;
+       mddev->level = LEVEL_NONE;
+       mddev->clevel[0] = 0;
+       mddev->flags = 0;
+       mddev->ro = 0;
+       mddev->metadata_type[0] = 0;
+       mddev->chunk_sectors = 0;
+       mddev->ctime = mddev->utime = 0;
+       mddev->layout = 0;
+       mddev->max_disks = 0;
+       mddev->events = 0;
+       mddev->delta_disks = 0;
+       mddev->new_level = LEVEL_NONE;
+       mddev->new_layout = 0;
+       mddev->new_chunk_sectors = 0;
+       mddev->curr_resync = 0;
+       mddev->resync_mismatches = 0;
+       mddev->suspend_lo = mddev->suspend_hi = 0;
+       mddev->sync_speed_min = mddev->sync_speed_max = 0;
+       mddev->recovery = 0;
+       mddev->in_sync = 0;
+       mddev->degraded = 0;
+       mddev->barriers_work = 0;
+       mddev->safemode = 0;
+       mddev->bitmap_info.offset = 0;
+       mddev->bitmap_info.default_offset = 0;
+       mddev->bitmap_info.chunksize = 0;
+       mddev->bitmap_info.daemon_sleep = 0;
+       mddev->bitmap_info.max_write_behind = 0;
+}
+
+static void md_stop_writes(mddev_t *mddev)
+{
+       if (mddev->sync_thread) {
+               set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+               md_unregister_thread(mddev->sync_thread);
+               mddev->sync_thread = NULL;
+       }
+
+       del_timer_sync(&mddev->safemode_timer);
+
+       bitmap_flush(mddev);
+       md_super_wait(mddev);
+
+       if (!mddev->in_sync || mddev->flags) {
+               /* mark array as shutdown cleanly */
+               mddev->in_sync = 1;
+               md_update_sb(mddev, 1);
+       }
+}
+
+static void md_stop(mddev_t *mddev)
+{
+       md_stop_writes(mddev);
+
+       mddev->pers->stop(mddev);
+       if (mddev->pers->sync_request && mddev->to_remove == NULL)
+               mddev->to_remove = &md_redundancy_group;
+       module_put(mddev->pers->owner);
+       mddev->pers = NULL;
+       clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+}
+
+static int md_set_readonly(mddev_t *mddev, int is_open)
+{
+       int err = 0;
+       mutex_lock(&mddev->open_mutex);
+       if (atomic_read(&mddev->openers) > is_open) {
+               printk("md: %s still in use.\n",mdname(mddev));
+               err = -EBUSY;
+               goto out;
+       }
+       if (mddev->pers) {
+               md_stop_writes(mddev);
+
+               err  = -ENXIO;
+               if (mddev->ro==1)
+                       goto out;
+               mddev->ro = 1;
+               set_disk_ro(mddev->gendisk, 1);
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               sysfs_notify_dirent(mddev->sysfs_state);
+               err = 0;        
+       }
+out:
+       mutex_unlock(&mddev->open_mutex);
+       return err;
+}
+
 /* mode:
  *   0 - completely stop and dis-assemble array
- *   1 - switch to readonly
  *   2 - stop but do not disassemble array
  */
 static int do_md_stop(mddev_t * mddev, int mode, int is_open)
@@ -4578,64 +4686,32 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
                err = -EBUSY;
        } else if (mddev->pers) {
 
-               if (mddev->sync_thread) {
-                       set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
-                       set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-                       md_unregister_thread(mddev->sync_thread);
-                       mddev->sync_thread = NULL;
-               }
+               if (mddev->ro)
+                       set_disk_ro(disk, 0);
 
-               del_timer_sync(&mddev->safemode_timer);
-
-               switch(mode) {
-               case 1: /* readonly */
-                       err  = -ENXIO;
-                       if (mddev->ro==1)
-                               goto out;
-                       mddev->ro = 1;
-                       break;
-               case 0: /* disassemble */
-               case 2: /* stop */
-                       bitmap_flush(mddev);
-                       md_super_wait(mddev);
-                       if (mddev->ro)
-                               set_disk_ro(disk, 0);
+               md_stop(mddev);
+               mddev->queue->merge_bvec_fn = NULL;
+               mddev->queue->unplug_fn = NULL;
+               mddev->queue->backing_dev_info.congested_fn = NULL;
 
-                       mddev->pers->stop(mddev);
-                       mddev->queue->merge_bvec_fn = NULL;
-                       mddev->queue->unplug_fn = NULL;
-                       mddev->queue->backing_dev_info.congested_fn = NULL;
-                       module_put(mddev->pers->owner);
-                       if (mddev->pers->sync_request && mddev->to_remove == NULL)
-                               mddev->to_remove = &md_redundancy_group;
-                       mddev->pers = NULL;
-                       /* tell userspace to handle 'inactive' */
-                       sysfs_notify_dirent(mddev->sysfs_state);
+               /* tell userspace to handle 'inactive' */
+               sysfs_notify_dirent(mddev->sysfs_state);
 
-                       list_for_each_entry(rdev, &mddev->disks, same_set)
-                               if (rdev->raid_disk >= 0) {
-                                       char nm[20];
-                                       sprintf(nm, "rd%d", rdev->raid_disk);
-                                       sysfs_remove_link(&mddev->kobj, nm);
-                               }
+               list_for_each_entry(rdev, &mddev->disks, same_set)
+                       if (rdev->raid_disk >= 0) {
+                               char nm[20];
+                               sprintf(nm, "rd%d", rdev->raid_disk);
+                               sysfs_remove_link(&mddev->kobj, nm);
+                       }
 
-                       set_capacity(disk, 0);
-                       mddev->changed = 1;
+               set_capacity(disk, 0);
+               revalidate_disk(disk);
 
-                       if (mddev->ro)
-                               mddev->ro = 0;
-               }
-               if (!mddev->in_sync || mddev->flags) {
-                       /* mark array as shutdown cleanly */
-                       mddev->in_sync = 1;
-                       md_update_sb(mddev, 1);
-               }
-               if (mode == 1)
-                       set_disk_ro(disk, 1);
-               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               if (mddev->ro)
+                       mddev->ro = 0;
+               
                err = 0;
        }
-out:
        mutex_unlock(&mddev->open_mutex);
        if (err)
                return err;
@@ -4656,52 +4732,12 @@ out:
 
                export_array(mddev);
 
-               mddev->array_sectors = 0;
-               mddev->external_size = 0;
-               mddev->dev_sectors = 0;
-               mddev->raid_disks = 0;
-               mddev->recovery_cp = 0;
-               mddev->resync_min = 0;
-               mddev->resync_max = MaxSector;
-               mddev->reshape_position = MaxSector;
-               mddev->external = 0;
-               mddev->persistent = 0;
-               mddev->level = LEVEL_NONE;
-               mddev->clevel[0] = 0;
-               mddev->flags = 0;
-               mddev->ro = 0;
-               mddev->metadata_type[0] = 0;
-               mddev->chunk_sectors = 0;
-               mddev->ctime = mddev->utime = 0;
-               mddev->layout = 0;
-               mddev->max_disks = 0;
-               mddev->events = 0;
-               mddev->delta_disks = 0;
-               mddev->new_level = LEVEL_NONE;
-               mddev->new_layout = 0;
-               mddev->new_chunk_sectors = 0;
-               mddev->curr_resync = 0;
-               mddev->resync_mismatches = 0;
-               mddev->suspend_lo = mddev->suspend_hi = 0;
-               mddev->sync_speed_min = mddev->sync_speed_max = 0;
-               mddev->recovery = 0;
-               mddev->in_sync = 0;
-               mddev->changed = 0;
-               mddev->degraded = 0;
-               mddev->barriers_work = 0;
-               mddev->safemode = 0;
-               mddev->bitmap_info.offset = 0;
-               mddev->bitmap_info.default_offset = 0;
-               mddev->bitmap_info.chunksize = 0;
-               mddev->bitmap_info.daemon_sleep = 0;
-               mddev->bitmap_info.max_write_behind = 0;
+               md_clean(mddev);
                kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
                if (mddev->hold_active == UNTIL_STOP)
                        mddev->hold_active = 0;
 
-       } else if (mddev->pers)
-               printk(KERN_INFO "md: %s switched to read-only mode.\n",
-                       mdname(mddev));
+       }
        err = 0;
        blk_integrity_unregister(disk);
        md_new_event(mddev);
@@ -5699,7 +5735,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        goto done_unlock;
 
                case STOP_ARRAY_RO:
-                       err = do_md_stop(mddev, 1, 1);
+                       err = md_set_readonly(mddev, 1);
                        goto done_unlock;
 
                case BLKROSET:
@@ -5850,7 +5886,6 @@ static int md_open(struct block_device *bdev, fmode_t mode)
        atomic_inc(&mddev->openers);
        mutex_unlock(&mddev->open_mutex);
 
-       check_disk_change(bdev);
  out:
        return err;
 }
@@ -5865,21 +5900,6 @@ static int md_release(struct gendisk *disk, fmode_t mode)
 
        return 0;
 }
-
-static int md_media_changed(struct gendisk *disk)
-{
-       mddev_t *mddev = disk->private_data;
-
-       return mddev->changed;
-}
-
-static int md_revalidate(struct gendisk *disk)
-{
-       mddev_t *mddev = disk->private_data;
-
-       mddev->changed = 0;
-       return 0;
-}
 static const struct block_device_operations md_fops =
 {
        .owner          = THIS_MODULE,
@@ -5890,8 +5910,6 @@ static const struct block_device_operations md_fops =
        .compat_ioctl   = md_compat_ioctl,
 #endif
        .getgeo         = md_getgeo,
-       .media_changed  = md_media_changed,
-       .revalidate_disk= md_revalidate,
 };
 
 static int md_thread(void * arg)
@@ -7133,7 +7151,7 @@ static int md_notify_reboot(struct notifier_block *this,
                                 * appears to still be in use.  Hence
                                 * the '100'.
                                 */
-                               do_md_stop(mddev, 1, 100);
+                               md_set_readonly(mddev, 100);
                                mddev_unlock(mddev);
                        }
                /*