linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl()
@ 2024-02-26  3:14 linan666
  2024-02-26  3:14 ` [PATCH v7 1/9] md: merge the check of capabilities into md_ioctl_valid() linan666
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

Changes in v7:
 - adapt to md-6.9 branch.

Changes in v6:
 - in patch 2, return directly.
 - in patch 4, return directly in case GET_DISK_INFO and GET_ARRAY_INFO.
 - in patch 7, rewrite commit message.
 - add patch 8, clean up openers check.

Changes in v5:
 - add patches 1-4 to clean up md_ioct(), pathc 4 can help us clean up
   local variable 'clear_md_closing'.
 - in patches 5 and 7, clean up local variable 'clear_md_closing'.


Li Nan (9):
  md: merge the check of capabilities into md_ioctl_valid()
  md: changed the switch of RAID_VERSION to if
  md: clean up invalid BUG_ON in md_ioctl
  md: return directly before setting did_set_md_closing
  md: Don't clear MD_CLOSING when the raid is about to stop
  md: factor out a helper to sync mddev
  md: sync blockdev before stopping raid or setting readonly
  md: clean up openers check in do_md_stop() and md_set_readonly()
  md: check mddev->pers before calling md_set_readonly()

 drivers/md/md.c | 183 ++++++++++++++++++++++++------------------------
 1 file changed, 91 insertions(+), 92 deletions(-)

-- 
2.39.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v7 1/9] md: merge the check of capabilities into md_ioctl_valid()
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 2/9] md: changed the switch of RAID_VERSION to if linan666
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

There is no functional change. Just to make code cleaner.

Signed-off-by: Li Nan <linan122@huawei.com>
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
---
 drivers/md/md.c | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index e2a5f513dbb7..332eda680aea 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7521,16 +7521,17 @@ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 	return 0;
 }
 
-static inline bool md_ioctl_valid(unsigned int cmd)
+static inline int md_ioctl_valid(unsigned int cmd)
 {
 	switch (cmd) {
-	case ADD_NEW_DISK:
 	case GET_ARRAY_INFO:
-	case GET_BITMAP_FILE:
 	case GET_DISK_INFO:
+	case RAID_VERSION:
+		return 0;
+	case ADD_NEW_DISK:
+	case GET_BITMAP_FILE:
 	case HOT_ADD_DISK:
 	case HOT_REMOVE_DISK:
-	case RAID_VERSION:
 	case RESTART_ARRAY_RW:
 	case RUN_ARRAY:
 	case SET_ARRAY_INFO:
@@ -7539,9 +7540,11 @@ static inline bool md_ioctl_valid(unsigned int cmd)
 	case STOP_ARRAY:
 	case STOP_ARRAY_RO:
 	case CLUSTERED_DISK_NACK:
-		return true;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+		return 0;
 	default:
-		return false;
+		return -ENOTTY;
 	}
 }
 
@@ -7601,18 +7604,9 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 	struct mddev *mddev = NULL;
 	bool did_set_md_closing = false;
 
-	if (!md_ioctl_valid(cmd))
-		return -ENOTTY;
-
-	switch (cmd) {
-	case RAID_VERSION:
-	case GET_ARRAY_INFO:
-	case GET_DISK_INFO:
-		break;
-	default:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-	}
+	err = md_ioctl_valid(cmd);
+	if (err)
+		return err;
 
 	/*
 	 * Commands dealing with the RAID driver but not any
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 2/9] md: changed the switch of RAID_VERSION to if
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
  2024-02-26  3:14 ` [PATCH v7 1/9] md: merge the check of capabilities into md_ioctl_valid() linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 3/9] md: clean up invalid BUG_ON in md_ioctl linan666
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

There is only one case of this 'switch'. Change it to 'if'.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 332eda680aea..b783a64765a7 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7612,12 +7612,8 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 	 * Commands dealing with the RAID driver but not any
 	 * particular array:
 	 */
-	switch (cmd) {
-	case RAID_VERSION:
-		err = get_version(argp);
-		goto out;
-	default:;
-	}
+	if (cmd == RAID_VERSION)
+		return get_version(argp);
 
 	/*
 	 * Commands creating/starting a new array:
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 3/9] md: clean up invalid BUG_ON in md_ioctl
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
  2024-02-26  3:14 ` [PATCH v7 1/9] md: merge the check of capabilities into md_ioctl_valid() linan666
  2024-02-26  3:14 ` [PATCH v7 2/9] md: changed the switch of RAID_VERSION to if linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 4/9] md: return directly before setting did_set_md_closing linan666
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

'disk->private_data' is set to mddev in md_alloc() and never set to NULL,
and users need to open mddev before submitting ioctl. So mddev must not
have been freed during ioctl, and there is no need to check mddev here.
Clean up it.

Signed-off-by: Li Nan <linan122@huawei.com>
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
---
 drivers/md/md.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index b783a64765a7..6432bdbddb1c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7621,11 +7621,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 
 	mddev = bdev->bd_disk->private_data;
 
-	if (!mddev) {
-		BUG();
-		goto out;
-	}
-
 	/* Some actions do not requires the mutex */
 	switch (cmd) {
 	case GET_ARRAY_INFO:
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 4/9] md: return directly before setting did_set_md_closing
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (2 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 3/9] md: clean up invalid BUG_ON in md_ioctl linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 5/9] md: Don't clear MD_CLOSING when the raid is about to stop linan666
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

There is nothing to do at 'out' before setting 'did_set_md_closing'
in md_ioctl(). Return directly, and it will help us to remove
'did_set_md_closing' later.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6432bdbddb1c..08b0f80274c0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7625,26 +7625,19 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 	switch (cmd) {
 	case GET_ARRAY_INFO:
 		if (!mddev->raid_disks && !mddev->external)
-			err = -ENODEV;
-		else
-			err = get_array_info(mddev, argp);
-		goto out;
+			return -ENODEV;
+		return get_array_info(mddev, argp);
 
 	case GET_DISK_INFO:
 		if (!mddev->raid_disks && !mddev->external)
-			err = -ENODEV;
-		else
-			err = get_disk_info(mddev, argp);
-		goto out;
+			return -ENODEV;
+		return get_disk_info(mddev, argp);
 
 	case SET_DISK_FAULTY:
-		err = set_disk_faulty(mddev, new_decode_dev(arg));
-		goto out;
+		return set_disk_faulty(mddev, new_decode_dev(arg));
 
 	case GET_BITMAP_FILE:
-		err = get_bitmap_file(mddev, argp);
-		goto out;
-
+		return get_bitmap_file(mddev, argp);
 	}
 
 	if (cmd == HOT_REMOVE_DISK)
@@ -7660,13 +7653,11 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 		mutex_lock(&mddev->open_mutex);
 		if (mddev->pers && atomic_read(&mddev->openers) > 1) {
 			mutex_unlock(&mddev->open_mutex);
-			err = -EBUSY;
-			goto out;
+			return -EBUSY;
 		}
 		if (test_and_set_bit(MD_CLOSING, &mddev->flags)) {
 			mutex_unlock(&mddev->open_mutex);
-			err = -EBUSY;
-			goto out;
+			return -EBUSY;
 		}
 		did_set_md_closing = true;
 		mutex_unlock(&mddev->open_mutex);
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 5/9] md: Don't clear MD_CLOSING when the raid is about to stop
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (3 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 4/9] md: return directly before setting did_set_md_closing linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 6/9] md: factor out a helper to sync mddev linan666
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

The raid should not be opened anymore when it is about to be stopped.
However, other processes can open it again if the flag MD_CLOSING is
cleared before exiting. From now on, this flag will not be cleared when
the raid will be stopped.

Fixes: 065e519e71b2 ("md: MD_CLOSING needs to be cleared after called md_set_readonly or do_md_stop")
Signed-off-by: Li Nan <linan122@huawei.com>
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
---
 drivers/md/md.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 08b0f80274c0..43ca8a4c02ce 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6264,7 +6264,15 @@ static void md_clean(struct mddev *mddev)
 	mddev->persistent = 0;
 	mddev->level = LEVEL_NONE;
 	mddev->clevel[0] = 0;
-	mddev->flags = 0;
+	/*
+	 * Don't clear MD_CLOSING, or mddev can be opened again.
+	 * 'hold_active != 0' means mddev is still in the creation
+	 * process and will be used later.
+	 */
+	if (mddev->hold_active)
+		mddev->flags = 0;
+	else
+		mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
 	mddev->sb_flags = 0;
 	mddev->ro = MD_RDWR;
 	mddev->metadata_type[0] = 0;
@@ -7602,7 +7610,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 	int err = 0;
 	void __user *argp = (void __user *)arg;
 	struct mddev *mddev = NULL;
-	bool did_set_md_closing = false;
 
 	err = md_ioctl_valid(cmd);
 	if (err)
@@ -7659,7 +7666,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 			mutex_unlock(&mddev->open_mutex);
 			return -EBUSY;
 		}
-		did_set_md_closing = true;
 		mutex_unlock(&mddev->open_mutex);
 		sync_blockdev(bdev);
 	}
@@ -7801,7 +7807,7 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 				     mddev_unlock(mddev);
 
 out:
-	if(did_set_md_closing)
+	if (cmd == STOP_ARRAY_RO || (err && cmd == STOP_ARRAY))
 		clear_bit(MD_CLOSING, &mddev->flags);
 	return err;
 }
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 6/9] md: factor out a helper to sync mddev
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (4 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 5/9] md: Don't clear MD_CLOSING when the raid is about to stop linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 7/9] md: sync blockdev before stopping raid or setting readonly linan666
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

There are no functional changes, prepare to sync mddev in
array_state_store().

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 43ca8a4c02ce..cba1027b279e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -529,6 +529,24 @@ void mddev_resume(struct mddev *mddev)
 }
 EXPORT_SYMBOL_GPL(mddev_resume);
 
+/* sync bdev before setting device to readonly or stopping raid*/
+static int mddev_set_closing_and_sync_blockdev(struct mddev *mddev, int opener_num)
+{
+	mutex_lock(&mddev->open_mutex);
+	if (mddev->pers && atomic_read(&mddev->openers) > opener_num) {
+		mutex_unlock(&mddev->open_mutex);
+		return -EBUSY;
+	}
+	if (test_and_set_bit(MD_CLOSING, &mddev->flags)) {
+		mutex_unlock(&mddev->open_mutex);
+		return -EBUSY;
+	}
+	mutex_unlock(&mddev->open_mutex);
+
+	sync_blockdev(mddev->gendisk->part0);
+	return 0;
+}
+
 /*
  * Generic flush handling for md
  */
@@ -7657,17 +7675,9 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 		/* Need to flush page cache, and ensure no-one else opens
 		 * and writes
 		 */
-		mutex_lock(&mddev->open_mutex);
-		if (mddev->pers && atomic_read(&mddev->openers) > 1) {
-			mutex_unlock(&mddev->open_mutex);
-			return -EBUSY;
-		}
-		if (test_and_set_bit(MD_CLOSING, &mddev->flags)) {
-			mutex_unlock(&mddev->open_mutex);
-			return -EBUSY;
-		}
-		mutex_unlock(&mddev->open_mutex);
-		sync_blockdev(bdev);
+		err = mddev_set_closing_and_sync_blockdev(mddev, 1);
+		if (err)
+			return err;
 	}
 
 	if (!md_is_rdwr(mddev))
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 7/9] md: sync blockdev before stopping raid or setting readonly
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (5 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 6/9] md: factor out a helper to sync mddev linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 8/9] md: clean up openers check in do_md_stop() and md_set_readonly() linan666
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

Commit a05b7ea03d72 ("md: avoid crash when stopping md array races
with closing other open fds.") added sync_block before stopping raid and
setting readonly. Later in commit 260fa034ef7a ("md: avoid deadlock when
dirty buffers during md_stop.") it is moved to ioctl. array_state_store()
was ignored. Add sync blockdev to array_state_store() now.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index cba1027b279e..fe0c7c80fb5e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4500,6 +4500,17 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
 	case broken:		/* cannot be set */
 	case bad_word:
 		return -EINVAL;
+	case clear:
+	case readonly:
+	case inactive:
+	case read_auto:
+		if (!mddev->pers || !md_is_rdwr(mddev))
+			break;
+		/* write sysfs will not open mddev and opener should be 0 */
+		err = mddev_set_closing_and_sync_blockdev(mddev, 0);
+		if (err)
+			return err;
+		break;
 	default:
 		break;
 	}
@@ -4599,6 +4610,11 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
 		sysfs_notify_dirent_safe(mddev->sysfs_state);
 	}
 	mddev_unlock(mddev);
+
+	if (st == readonly || st == read_auto || st == inactive ||
+	    (err && st == clear))
+		clear_bit(MD_CLOSING, &mddev->flags);
+
 	return err ?: len;
 }
 static struct md_sysfs_entry md_array_state =
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 8/9] md: clean up openers check in do_md_stop() and md_set_readonly()
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (6 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 7/9] md: sync blockdev before stopping raid or setting readonly linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26  3:14 ` [PATCH v7 9/9] md: check mddev->pers before calling md_set_readonly() linan666
  2024-02-26 21:32 ` [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() Song Liu
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

Before stopping or setting readonly, mddev_set_closing_and_sync_blockdev()
is always called to check the openers. So no longer need to check it again
in do_md_stop() and md_set_readonly(). Clean it up.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 37 ++++++++++++++-----------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index fe0c7c80fb5e..82c12ecf17a6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4482,8 +4482,8 @@ array_state_show(struct mddev *mddev, char *page)
 	return sprintf(page, "%s\n", array_states[st]);
 }
 
-static int do_md_stop(struct mddev *mddev, int ro, struct block_device *bdev);
-static int md_set_readonly(struct mddev *mddev, struct block_device *bdev);
+static int do_md_stop(struct mddev *mddev, int ro);
+static int md_set_readonly(struct mddev *mddev);
 static int restart_array(struct mddev *mddev);
 
 static ssize_t
@@ -4544,14 +4544,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
 	case inactive:
 		/* stop an active array, return 0 otherwise */
 		if (mddev->pers)
-			err = do_md_stop(mddev, 2, NULL);
+			err = do_md_stop(mddev, 2);
 		break;
 	case clear:
-		err = do_md_stop(mddev, 0, NULL);
+		err = do_md_stop(mddev, 0);
 		break;
 	case readonly:
 		if (mddev->pers)
-			err = md_set_readonly(mddev, NULL);
+			err = md_set_readonly(mddev);
 		else {
 			mddev->ro = MD_RDONLY;
 			set_disk_ro(mddev->gendisk, 1);
@@ -4561,7 +4561,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
 	case read_auto:
 		if (mddev->pers) {
 			if (md_is_rdwr(mddev))
-				err = md_set_readonly(mddev, NULL);
+				err = md_set_readonly(mddev);
 			else if (mddev->ro == MD_RDONLY)
 				err = restart_array(mddev);
 			if (err == 0) {
@@ -6419,7 +6419,7 @@ void md_stop(struct mddev *mddev)
 
 EXPORT_SYMBOL_GPL(md_stop);
 
-static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
+static int md_set_readonly(struct mddev *mddev)
 {
 	int err = 0;
 	int did_freeze = 0;
@@ -6437,9 +6437,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
 		   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
 	mddev_lock_nointr(mddev);
 
-	mutex_lock(&mddev->open_mutex);
-	if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
-	    test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
+	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
 		pr_warn("md: %s still in use.\n",mdname(mddev));
 		err = -EBUSY;
 		goto out;
@@ -6464,7 +6462,6 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
 		sysfs_notify_dirent_safe(mddev->sysfs_state);
 	}
 
-	mutex_unlock(&mddev->open_mutex);
 	return err;
 }
 
@@ -6472,8 +6469,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
  *   0 - completely stop and dis-assemble array
  *   2 - stop but do not disassemble array
  */
-static int do_md_stop(struct mddev *mddev, int mode,
-		      struct block_device *bdev)
+static int do_md_stop(struct mddev *mddev, int mode)
 {
 	struct gendisk *disk = mddev->gendisk;
 	struct md_rdev *rdev;
@@ -6486,12 +6482,9 @@ static int do_md_stop(struct mddev *mddev, int mode,
 
 	stop_sync_thread(mddev, true, false);
 
-	mutex_lock(&mddev->open_mutex);
-	if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
-	    mddev->sysfs_active ||
+	if (mddev->sysfs_active ||
 	    test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
 		pr_warn("md: %s still in use.\n",mdname(mddev));
-		mutex_unlock(&mddev->open_mutex);
 		if (did_freeze) {
 			clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 			set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -6513,13 +6506,11 @@ static int do_md_stop(struct mddev *mddev, int mode,
 				sysfs_unlink_rdev(mddev, rdev);
 
 		set_capacity_and_notify(disk, 0);
-		mutex_unlock(&mddev->open_mutex);
 		mddev->changed = 1;
 
 		if (!md_is_rdwr(mddev))
 			mddev->ro = MD_RDWR;
-	} else
-		mutex_unlock(&mddev->open_mutex);
+	}
 	/*
 	 * Free resources if final stop
 	 */
@@ -6565,7 +6556,7 @@ static void autorun_array(struct mddev *mddev)
 	err = do_md_run(mddev);
 	if (err) {
 		pr_warn("md: do_md_run() returned %d\n", err);
-		do_md_stop(mddev, 0, NULL);
+		do_md_stop(mddev, 0);
 	}
 }
 
@@ -7734,11 +7725,11 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 		goto unlock;
 
 	case STOP_ARRAY:
-		err = do_md_stop(mddev, 0, bdev);
+		err = do_md_stop(mddev, 0);
 		goto unlock;
 
 	case STOP_ARRAY_RO:
-		err = md_set_readonly(mddev, bdev);
+		err = md_set_readonly(mddev);
 		goto unlock;
 
 	case HOT_REMOVE_DISK:
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v7 9/9] md: check mddev->pers before calling md_set_readonly()
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (7 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 8/9] md: clean up openers check in do_md_stop() and md_set_readonly() linan666
@ 2024-02-26  3:14 ` linan666
  2024-02-26 21:32 ` [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() Song Liu
  9 siblings, 0 replies; 11+ messages in thread
From: linan666 @ 2024-02-26  3:14 UTC (permalink / raw)
  To: song, shli, neilb
  Cc: mariusz.tkaczyk, linux-raid, linux-kernel, linan666, yukuai3,
	yi.zhang, houtao1, yangerkun

From: Li Nan <linan122@huawei.com>

If 'mddev->pers' is NULL, there is nothing to do in md_set_readonly().
Except for md_ioctl(), the other two callers of md_set_readonly() have
already checked 'mddev->pers'. To simplify the code, move the check of
'mddev->pers' to the caller.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 82c12ecf17a6..f227a7613003 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6419,6 +6419,7 @@ void md_stop(struct mddev *mddev)
 
 EXPORT_SYMBOL_GPL(md_stop);
 
+/* ensure 'mddev->pers' exist before calling md_set_readonly() */
 static int md_set_readonly(struct mddev *mddev)
 {
 	int err = 0;
@@ -6443,20 +6444,18 @@ static int md_set_readonly(struct mddev *mddev)
 		goto out;
 	}
 
-	if (mddev->pers) {
-		__md_stop_writes(mddev);
-
-		if (mddev->ro == MD_RDONLY) {
-			err  = -ENXIO;
-			goto out;
-		}
+	__md_stop_writes(mddev);
 
-		mddev->ro = MD_RDONLY;
-		set_disk_ro(mddev->gendisk, 1);
+	if (mddev->ro == MD_RDONLY) {
+		err  = -ENXIO;
+		goto out;
 	}
 
+	mddev->ro = MD_RDONLY;
+	set_disk_ro(mddev->gendisk, 1);
+
 out:
-	if ((mddev->pers && !err) || did_freeze) {
+	if (!err || did_freeze) {
 		clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 		sysfs_notify_dirent_safe(mddev->sysfs_state);
@@ -7729,7 +7728,8 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
 		goto unlock;
 
 	case STOP_ARRAY_RO:
-		err = md_set_readonly(mddev);
+		if (mddev->pers)
+			err = md_set_readonly(mddev);
 		goto unlock;
 
 	case HOT_REMOVE_DISK:
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl()
  2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
                   ` (8 preceding siblings ...)
  2024-02-26  3:14 ` [PATCH v7 9/9] md: check mddev->pers before calling md_set_readonly() linan666
@ 2024-02-26 21:32 ` Song Liu
  9 siblings, 0 replies; 11+ messages in thread
From: Song Liu @ 2024-02-26 21:32 UTC (permalink / raw)
  To: linan666
  Cc: shli, neilb, mariusz.tkaczyk, linux-raid, linux-kernel, yukuai3,
	yi.zhang, houtao1, yangerkun

On Sun, Feb 25, 2024 at 7:20 PM <linan666@huaweicloud.com> wrote:
>
> From: Li Nan <linan122@huawei.com>
>
> Changes in v7:
>  - adapt to md-6.9 branch.

LGTM. Applied to md-6.9 branch. Thanks!

Song

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-02-26 21:32 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-26  3:14 [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() linan666
2024-02-26  3:14 ` [PATCH v7 1/9] md: merge the check of capabilities into md_ioctl_valid() linan666
2024-02-26  3:14 ` [PATCH v7 2/9] md: changed the switch of RAID_VERSION to if linan666
2024-02-26  3:14 ` [PATCH v7 3/9] md: clean up invalid BUG_ON in md_ioctl linan666
2024-02-26  3:14 ` [PATCH v7 4/9] md: return directly before setting did_set_md_closing linan666
2024-02-26  3:14 ` [PATCH v7 5/9] md: Don't clear MD_CLOSING when the raid is about to stop linan666
2024-02-26  3:14 ` [PATCH v7 6/9] md: factor out a helper to sync mddev linan666
2024-02-26  3:14 ` [PATCH v7 7/9] md: sync blockdev before stopping raid or setting readonly linan666
2024-02-26  3:14 ` [PATCH v7 8/9] md: clean up openers check in do_md_stop() and md_set_readonly() linan666
2024-02-26  3:14 ` [PATCH v7 9/9] md: check mddev->pers before calling md_set_readonly() linan666
2024-02-26 21:32 ` [PATCH v7 0/9] bugfix of MD_CLOSING and clean up md_ioctl() Song Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).