Commit 0fd62b86 authored by Neil Brown's avatar Neil Brown
Browse files

Make sure all changes to md/array_state are notified.



Changes in md/array_state could be of interest to a monitoring
program.  So make sure all changes trigger a notification.

Exceptions:
   changing active_idle to active is not reported because it
      is frequent and not interesting.
   changing active to active_idle is only reported on arrays
      with externally managed metadata, as it is not interesting
      otherwise.

Signed-off-by: default avatarNeil Brown <neilb@suse.de>
parent c7d0c941
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -236,6 +236,11 @@ All md devices contain:
     writing the word for the desired state, however some states
     cannot be explicitly set, and some transitions are not allowed.

     Select/poll works on this file.  All changes except between
     	active_idle and active (which can be frequent and are not
	very interesting) are notified.  active->active_idle is
	reported if the metadata is externally managed.

     clear
         No devices, no size, no level
         Writing is equivalent to STOP_ARRAY ioctl
+24 −5
Original line number Diff line number Diff line
@@ -2716,9 +2716,11 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
	}
	if (err)
		return err;
	else
	else {
		sysfs_notify(&mddev->kobj, NULL, "array_state");
		return len;
	}
}
static struct md_sysfs_entry md_array_state =
__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);

@@ -3408,7 +3410,11 @@ static void md_safemode_timeout(unsigned long data)
{
	mddev_t *mddev = (mddev_t *) data;

	if (!atomic_read(&mddev->writes_pending)) {
		mddev->safemode = 1;
		if (mddev->external)
			sysfs_notify(&mddev->kobj, NULL, "array_state");
	}
	md_wakeup_thread(mddev->thread);
}

@@ -3675,6 +3681,7 @@ static int do_md_run(mddev_t * mddev)

	mddev->changed = 1;
	md_new_event(mddev);
	sysfs_notify(&mddev->kobj, NULL, "array_state");
	kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
	return 0;
}
@@ -3709,6 +3716,8 @@ static int restart_array(mddev_t *mddev)
		md_wakeup_thread(mddev->thread);
		md_wakeup_thread(mddev->sync_thread);
		err = 0;
		sysfs_notify(&mddev->kobj, NULL, "array_state");

	} else
		err = -EINVAL;

@@ -3879,6 +3888,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
			mdname(mddev));
	err = 0;
	md_new_event(mddev);
	sysfs_notify(&mddev->kobj, NULL, "array_state");
out:
	return err;
}
@@ -4876,6 +4886,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
	    mddev->ro && mddev->pers) {
		if (mddev->ro == 2) {
			mddev->ro = 0;
			sysfs_notify(&mddev->kobj, NULL, "array_state");
			set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
			md_wakeup_thread(mddev->thread);

@@ -5516,6 +5527,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok)
 */
void md_write_start(mddev_t *mddev, struct bio *bi)
{
	int did_change = 0;
	if (bio_data_dir(bi) != WRITE)
		return;

@@ -5526,6 +5538,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
		md_wakeup_thread(mddev->thread);
		md_wakeup_thread(mddev->sync_thread);
		did_change = 1;
	}
	atomic_inc(&mddev->writes_pending);
	if (mddev->safemode == 1)
@@ -5536,10 +5549,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
			mddev->in_sync = 0;
			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
			md_wakeup_thread(mddev->thread);
			did_change = 1;
		}
		spin_unlock_irq(&mddev->write_lock);
		sysfs_notify(&mddev->kobj, NULL, "array_state");
	}
	if (did_change)
		sysfs_notify(&mddev->kobj, NULL, "array_state");
	wait_event(mddev->sb_wait,
		   !test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
		   !test_bit(MD_CHANGE_PENDING, &mddev->flags));
@@ -5991,18 +6006,22 @@ void md_check_recovery(mddev_t *mddev)
		int spares = 0;

		if (!mddev->external) {
			int did_change = 0;
			spin_lock_irq(&mddev->write_lock);
			if (mddev->safemode &&
			    !atomic_read(&mddev->writes_pending) &&
			    !mddev->in_sync &&
			    mddev->recovery_cp == MaxSector) {
				mddev->in_sync = 1;
				did_change = 1;
				if (mddev->persistent)
					set_bit(MD_CHANGE_CLEAN, &mddev->flags);
			}
			if (mddev->safemode == 1)
				mddev->safemode = 0;
			spin_unlock_irq(&mddev->write_lock);
			if (did_change)
				sysfs_notify(&mddev->kobj, NULL, "array_state");
		}

		if (mddev->flags)