Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b44886c5 authored by Song Liu's avatar Song Liu Committed by Shaohua Li
Browse files

md/r5cache: call mddev_lock/unlock() in r5c_journal_mode_set



In r5c_journal_mode_set(), it is necessary to call mddev_lock()
before accessing conf and conf->log. Otherwise, the conf->log
may change (and become NULL).

Shaohua: fix unlock in failure cases

Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent 81fe48e9
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -2540,23 +2540,32 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
 */
int r5c_journal_mode_set(struct mddev *mddev, int mode)
{
	struct r5conf *conf = mddev->private;
	struct r5l_log *log = conf->log;

	if (!log)
		return -ENODEV;
	struct r5conf *conf;
	int err;

	if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
	    mode > R5C_JOURNAL_MODE_WRITE_BACK)
		return -EINVAL;

	err = mddev_lock(mddev);
	if (err)
		return err;
	conf = mddev->private;
	if (!conf || !conf->log) {
		mddev_unlock(mddev);
		return -ENODEV;
	}

	if (raid5_calc_degraded(conf) > 0 &&
	    mode == R5C_JOURNAL_MODE_WRITE_BACK)
	    mode == R5C_JOURNAL_MODE_WRITE_BACK) {
		mddev_unlock(mddev);
		return -EINVAL;
	}

	mddev_suspend(mddev);
	conf->log->r5c_journal_mode = mode;
	mddev_resume(mddev);
	mddev_unlock(mddev);

	pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
		 mdname(mddev), mode, r5c_journal_mode_str[mode]);