2024-01-25 06:38:38

by Li Nan

[permalink] [raw]
Subject: [PATCH v3 0/4] md: Don't clear MD_CLOSING when the raid is about to stop

From: Li Nan <[email protected]>

Changes in v3:
- rename vaires 'did_set_md_closing' in patch 1.
- rename function mddev_set_closing_and_sync_blockdev() in patch 2.
- reorganize conditions in patch 3.
- add a new patch to clean up md_set_readonly().

Changes in v2:
- don't clear MD_CLOSING in md_clean().
- set MD_CLOSING and sync blockdev in array_state_store().

Li Nan (4):
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: check mddev->pers before calling md_set_readonly()

drivers/md/md.c | 96 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 67 insertions(+), 29 deletions(-)

--
2.39.2



2024-01-25 06:39:16

by Li Nan

[permalink] [raw]
Subject: [PATCH v3 1/4] md: Don't clear MD_CLOSING when the raid is about to stop

From: Li Nan <[email protected]>

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 <[email protected]>
Acked-by: Mariusz Tkaczyk <[email protected]>
---
drivers/md/md.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9bdd57324c37..06550fe34aa1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6254,7 +6254,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;
@@ -7600,7 +7608,7 @@ 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;
+ bool clear_md_closing = false;

if (!md_ioctl_valid(cmd))
return -ENOTTY;
@@ -7684,7 +7692,7 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
err = -EBUSY;
goto out;
}
- did_set_md_closing = true;
+ clear_md_closing = true;
mutex_unlock(&mddev->open_mutex);
sync_blockdev(bdev);
}
@@ -7728,6 +7736,12 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,

case STOP_ARRAY:
err = do_md_stop(mddev, 0, bdev);
+ if (!err)
+ /*
+ * mddev has been stopped, keep the flag
+ * MD_CLOSING to prevent reuse.
+ */
+ clear_md_closing = false;
goto unlock;

case STOP_ARRAY_RO:
@@ -7826,7 +7840,7 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
mddev_unlock(mddev);

out:
- if(did_set_md_closing)
+ if (clear_md_closing)
clear_bit(MD_CLOSING, &mddev->flags);
return err;
}
--
2.39.2


2024-01-25 06:46:57

by Li Nan

[permalink] [raw]
Subject: [PATCH v3 2/4] md: factor out a helper to sync mddev

From: Li Nan <[email protected]>

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

Signed-off-by: Li Nan <[email protected]>
Acked-by: Mariusz Tkaczyk <[email protected]>
---
drivers/md/md.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 06550fe34aa1..40ab5c7ce394 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)
+{
+ 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(mddev->gendisk->part0);
+ return 0;
+}
+
/*
* Generic flush handling for md
*/
@@ -7681,20 +7699,10 @@ 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);
- err = -EBUSY;
- goto out;
- }
- if (test_and_set_bit(MD_CLOSING, &mddev->flags)) {
- mutex_unlock(&mddev->open_mutex);
- err = -EBUSY;
+ err = mddev_set_closing_and_sync_blockdev(mddev);
+ if (err)
goto out;
- }
clear_md_closing = true;
- mutex_unlock(&mddev->open_mutex);
- sync_blockdev(bdev);
}

if (!md_is_rdwr(mddev))
--
2.39.2


2024-01-25 06:49:53

by Li Nan

[permalink] [raw]
Subject: [PATCH v3 4/4] md: check mddev->pers before calling md_set_readonly()

From: Li Nan <[email protected]>

If 'mddev->pers' is NULL, there is nothing to do in md_set_readonly().
To simplify the code, move the check of 'mddev->pers' to the caller of
md_set_readonly().

Signed-off-by: Li Nan <[email protected]>
---
drivers/md/md.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3f1c9a264c8a..ca034861891e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6411,6 +6411,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, struct block_device *bdev)
{
int err = 0;
@@ -6431,28 +6432,25 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
mddev_lock_nointr(mddev);

mutex_lock(&mddev->open_mutex);
- if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
- mddev->sync_thread ||
+ if (atomic_read(&mddev->openers) > !!bdev || mddev->sync_thread ||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
pr_warn("md: %s still in use.\n",mdname(mddev));
err = -EBUSY;
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);
md_wakeup_thread(mddev->thread);
@@ -7771,7 +7769,8 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
goto unlock;

case STOP_ARRAY_RO:
- err = md_set_readonly(mddev, bdev);
+ if (mddev->pers)
+ err = md_set_readonly(mddev, bdev);
goto unlock;

case HOT_REMOVE_DISK:
--
2.39.2


2024-01-25 06:51:32

by Li Nan

[permalink] [raw]
Subject: [PATCH v3 3/4] md: sync blockdev before stopping raid or setting readonly

From: Li Nan <[email protected]>

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 <[email protected]>
---
drivers/md/md.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 40ab5c7ce394..3f1c9a264c8a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4478,6 +4478,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
{
int err = 0;
enum array_state st = match_word(buf, array_states);
+ bool clear_md_closing = false;

/* No lock dependent actions */
switch (st) {
@@ -4487,6 +4488,16 @@ 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;
+ err = mddev_set_closing_and_sync_blockdev(mddev);
+ if (err)
+ return err;
+ clear_md_closing = true;
default:
break;
}
@@ -4512,6 +4523,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
spin_unlock(&mddev->lock);
return err ?: len;
}
+
err = mddev_lock(mddev);
if (err)
return err;
@@ -4524,6 +4536,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
break;
case clear:
err = do_md_stop(mddev, 0, NULL);
+ if (!err)
+ clear_md_closing = false;
break;
case readonly:
if (mddev->pers)
@@ -4586,6 +4600,10 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
sysfs_notify_dirent_safe(mddev->sysfs_state);
}
mddev_unlock(mddev);
+
+ if (clear_md_closing)
+ clear_bit(MD_CLOSING, &mddev->flags);
+
return err ?: len;
}
static struct md_sysfs_entry md_array_state =
--
2.39.2


2024-01-25 14:00:14

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 3/4] md: sync blockdev before stopping raid or setting readonly

Hi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.8-rc1 next-20240125]
[cannot apply to song-md/md-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/linan666-huaweicloud-com/md-Don-t-clear-MD_CLOSING-when-the-raid-is-about-to-stop/20240125-144040
base: linus/master
patch link: https://lore.kernel.org/r/20240125062841.1721193-4-linan666%40huaweicloud.com
patch subject: [PATCH v3 3/4] md: sync blockdev before stopping raid or setting readonly
config: hexagon-allyesconfig (https://download.01.org/0day-ci/archive/20240125/[email protected]/config)
compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project a31a60074717fc40887cfe132b77eec93bedd307)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240125/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

In file included from drivers/md/md.c:43:
In file included from include/linux/blkdev.h:9:
In file included from include/linux/blk_types.h:10:
In file included from include/linux/bvec.h:10:
In file included from include/linux/highmem.h:12:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:328:
include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
547 | val = __raw_readb(PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
560 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
| ^
In file included from drivers/md/md.c:43:
In file included from include/linux/blkdev.h:9:
In file included from include/linux/blk_types.h:10:
In file included from include/linux/bvec.h:10:
In file included from include/linux/highmem.h:12:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:328:
include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
573 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
| ^
In file included from drivers/md/md.c:43:
In file included from include/linux/blkdev.h:9:
In file included from include/linux/blk_types.h:10:
In file included from include/linux/bvec.h:10:
In file included from include/linux/highmem.h:12:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:328:
include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
584 | __raw_writeb(value, PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
594 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
604 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
>> drivers/md/md.c:4521:2: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
4521 | default:
| ^
drivers/md/md.c:4521:2: note: insert 'break;' to avoid fall-through
4521 | default:
| ^
| break;
7 warnings generated.


vim +4521 drivers/md/md.c

9e653b6342c940 NeilBrown 2006-06-26 4495
9e653b6342c940 NeilBrown 2006-06-26 4496 static ssize_t
fd01b88c75a718 NeilBrown 2011-10-11 4497 array_state_store(struct mddev *mddev, const char *buf, size_t len)
9e653b6342c940 NeilBrown 2006-06-26 4498 {
6497709b5d1bcc NeilBrown 2017-03-15 4499 int err = 0;
9e653b6342c940 NeilBrown 2006-06-26 4500 enum array_state st = match_word(buf, array_states);
242b3580d1a1d0 Li Nan 2024-01-25 4501 bool clear_md_closing = false;
6791875e2e5393 NeilBrown 2014-12-15 4502
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4503 /* No lock dependent actions */
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4504 switch (st) {
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4505 case suspended: /* not supported yet */
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4506 case write_pending: /* cannot be set */
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4507 case active_idle: /* cannot be set */
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4508 case broken: /* cannot be set */
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4509 case bad_word:
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4510 return -EINVAL;
242b3580d1a1d0 Li Nan 2024-01-25 4511 case clear:
242b3580d1a1d0 Li Nan 2024-01-25 4512 case readonly:
242b3580d1a1d0 Li Nan 2024-01-25 4513 case inactive:
242b3580d1a1d0 Li Nan 2024-01-25 4514 case read_auto:
242b3580d1a1d0 Li Nan 2024-01-25 4515 if (!mddev->pers || !md_is_rdwr(mddev))
242b3580d1a1d0 Li Nan 2024-01-25 4516 break;
242b3580d1a1d0 Li Nan 2024-01-25 4517 err = mddev_set_closing_and_sync_blockdev(mddev);
242b3580d1a1d0 Li Nan 2024-01-25 4518 if (err)
242b3580d1a1d0 Li Nan 2024-01-25 4519 return err;
242b3580d1a1d0 Li Nan 2024-01-25 4520 clear_md_closing = true;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 @4521 default:
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4522 break;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4523 }
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4524
f97a5528b21eb1 Ye Bin 2022-09-20 4525 if (mddev->pers && (st == active || st == clean) &&
f97a5528b21eb1 Ye Bin 2022-09-20 4526 mddev->ro != MD_RDONLY) {
6791875e2e5393 NeilBrown 2014-12-15 4527 /* don't take reconfig_mutex when toggling between
6791875e2e5393 NeilBrown 2014-12-15 4528 * clean and active
6791875e2e5393 NeilBrown 2014-12-15 4529 */
6791875e2e5393 NeilBrown 2014-12-15 4530 spin_lock(&mddev->lock);
6791875e2e5393 NeilBrown 2014-12-15 4531 if (st == active) {
6791875e2e5393 NeilBrown 2014-12-15 4532 restart_array(mddev);
2953079c692da0 Shaohua Li 2016-12-08 4533 clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
91a6c4aded58cb Tomasz Majchrzak 2016-10-25 4534 md_wakeup_thread(mddev->thread);
6791875e2e5393 NeilBrown 2014-12-15 4535 wake_up(&mddev->sb_wait);
6791875e2e5393 NeilBrown 2014-12-15 4536 } else /* st == clean */ {
6791875e2e5393 NeilBrown 2014-12-15 4537 restart_array(mddev);
6497709b5d1bcc NeilBrown 2017-03-15 4538 if (!set_in_sync(mddev))
6791875e2e5393 NeilBrown 2014-12-15 4539 err = -EBUSY;
6791875e2e5393 NeilBrown 2014-12-15 4540 }
573275b58ee9e1 Tomasz Majchrzak 2016-06-30 4541 if (!err)
573275b58ee9e1 Tomasz Majchrzak 2016-06-30 4542 sysfs_notify_dirent_safe(mddev->sysfs_state);
6791875e2e5393 NeilBrown 2014-12-15 4543 spin_unlock(&mddev->lock);
c008f1d356277a NeilBrown 2015-06-12 4544 return err ?: len;
6791875e2e5393 NeilBrown 2014-12-15 4545 }
242b3580d1a1d0 Li Nan 2024-01-25 4546
6791875e2e5393 NeilBrown 2014-12-15 4547 err = mddev_lock(mddev);
6791875e2e5393 NeilBrown 2014-12-15 4548 if (err)
6791875e2e5393 NeilBrown 2014-12-15 4549 return err;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4550
9e653b6342c940 NeilBrown 2006-06-26 4551 switch (st) {
9e653b6342c940 NeilBrown 2006-06-26 4552 case inactive:
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4553 /* stop an active array, return 0 otherwise */
90cf195d9bcb4b NeilBrown 2012-07-31 4554 if (mddev->pers)
a05b7ea03d72f3 NeilBrown 2012-07-19 4555 err = do_md_stop(mddev, 2, NULL);
9e653b6342c940 NeilBrown 2006-06-26 4556 break;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4557 case clear:
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4558 err = do_md_stop(mddev, 0, NULL);
242b3580d1a1d0 Li Nan 2024-01-25 4559 if (!err)
242b3580d1a1d0 Li Nan 2024-01-25 4560 clear_md_closing = false;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4561 break;
9e653b6342c940 NeilBrown 2006-06-26 4562 case readonly:
9e653b6342c940 NeilBrown 2006-06-26 4563 if (mddev->pers)
a05b7ea03d72f3 NeilBrown 2012-07-19 4564 err = md_set_readonly(mddev, NULL);
9e653b6342c940 NeilBrown 2006-06-26 4565 else {
f97a5528b21eb1 Ye Bin 2022-09-20 4566 mddev->ro = MD_RDONLY;
648b629ed40623 NeilBrown 2008-04-30 4567 set_disk_ro(mddev->gendisk, 1);
9e653b6342c940 NeilBrown 2006-06-26 4568 err = do_md_run(mddev);
9e653b6342c940 NeilBrown 2006-06-26 4569 }
9e653b6342c940 NeilBrown 2006-06-26 4570 break;
9e653b6342c940 NeilBrown 2006-06-26 4571 case read_auto:
9e653b6342c940 NeilBrown 2006-06-26 4572 if (mddev->pers) {
f97a5528b21eb1 Ye Bin 2022-09-20 4573 if (md_is_rdwr(mddev))
a05b7ea03d72f3 NeilBrown 2012-07-19 4574 err = md_set_readonly(mddev, NULL);
f97a5528b21eb1 Ye Bin 2022-09-20 4575 else if (mddev->ro == MD_RDONLY)
648b629ed40623 NeilBrown 2008-04-30 4576 err = restart_array(mddev);
648b629ed40623 NeilBrown 2008-04-30 4577 if (err == 0) {
f97a5528b21eb1 Ye Bin 2022-09-20 4578 mddev->ro = MD_AUTO_READ;
648b629ed40623 NeilBrown 2008-04-30 4579 set_disk_ro(mddev->gendisk, 0);
648b629ed40623 NeilBrown 2008-04-30 4580 }
9e653b6342c940 NeilBrown 2006-06-26 4581 } else {
f97a5528b21eb1 Ye Bin 2022-09-20 4582 mddev->ro = MD_AUTO_READ;
9e653b6342c940 NeilBrown 2006-06-26 4583 err = do_md_run(mddev);
9e653b6342c940 NeilBrown 2006-06-26 4584 }
9e653b6342c940 NeilBrown 2006-06-26 4585 break;
9e653b6342c940 NeilBrown 2006-06-26 4586 case clean:
9e653b6342c940 NeilBrown 2006-06-26 4587 if (mddev->pers) {
339421def582ab Song Liu 2015-10-08 4588 err = restart_array(mddev);
339421def582ab Song Liu 2015-10-08 4589 if (err)
339421def582ab Song Liu 2015-10-08 4590 break;
85572d7c75fd5b NeilBrown 2014-12-15 4591 spin_lock(&mddev->lock);
6497709b5d1bcc NeilBrown 2017-03-15 4592 if (!set_in_sync(mddev))
e691063a61f7f7 NeilBrown 2008-02-06 4593 err = -EBUSY;
85572d7c75fd5b NeilBrown 2014-12-15 4594 spin_unlock(&mddev->lock);
5bf295975416f8 NeilBrown 2009-05-07 4595 } else
5bf295975416f8 NeilBrown 2009-05-07 4596 err = -EINVAL;
9e653b6342c940 NeilBrown 2006-06-26 4597 break;
9e653b6342c940 NeilBrown 2006-06-26 4598 case active:
9e653b6342c940 NeilBrown 2006-06-26 4599 if (mddev->pers) {
339421def582ab Song Liu 2015-10-08 4600 err = restart_array(mddev);
339421def582ab Song Liu 2015-10-08 4601 if (err)
339421def582ab Song Liu 2015-10-08 4602 break;
2953079c692da0 Shaohua Li 2016-12-08 4603 clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
9e653b6342c940 NeilBrown 2006-06-26 4604 wake_up(&mddev->sb_wait);
9e653b6342c940 NeilBrown 2006-06-26 4605 err = 0;
9e653b6342c940 NeilBrown 2006-06-26 4606 } else {
f97a5528b21eb1 Ye Bin 2022-09-20 4607 mddev->ro = MD_RDWR;
648b629ed40623 NeilBrown 2008-04-30 4608 set_disk_ro(mddev->gendisk, 0);
9e653b6342c940 NeilBrown 2006-06-26 4609 err = do_md_run(mddev);
9e653b6342c940 NeilBrown 2006-06-26 4610 }
9e653b6342c940 NeilBrown 2006-06-26 4611 break;
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4612 default:
09f894affcf2da Mariusz Tkaczyk 2023-09-28 4613 err = -EINVAL;
9e653b6342c940 NeilBrown 2006-06-26 4614 break;
9e653b6342c940 NeilBrown 2006-06-26 4615 }
6791875e2e5393 NeilBrown 2014-12-15 4616
6791875e2e5393 NeilBrown 2014-12-15 4617 if (!err) {
1d23f178d56ae1 NeilBrown 2011-12-08 4618 if (mddev->hold_active == UNTIL_IOCTL)
1d23f178d56ae1 NeilBrown 2011-12-08 4619 mddev->hold_active = 0;
00bcb4ac7ee7e5 NeilBrown 2010-06-01 4620 sysfs_notify_dirent_safe(mddev->sysfs_state);
9e653b6342c940 NeilBrown 2006-06-26 4621 }
6791875e2e5393 NeilBrown 2014-12-15 4622 mddev_unlock(mddev);
242b3580d1a1d0 Li Nan 2024-01-25 4623
242b3580d1a1d0 Li Nan 2024-01-25 4624 if (clear_md_closing)
242b3580d1a1d0 Li Nan 2024-01-25 4625 clear_bit(MD_CLOSING, &mddev->flags);
242b3580d1a1d0 Li Nan 2024-01-25 4626
6791875e2e5393 NeilBrown 2014-12-15 4627 return err ?: len;
0fd62b861eac7d Neil Brown 2008-06-28 4628 }
80ca3a44f563a7 NeilBrown 2006-07-10 4629 static struct md_sysfs_entry md_array_state =
750f199ee8b578 NeilBrown 2014-09-30 4630 __ATTR_PREALLOC(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
9e653b6342c940 NeilBrown 2006-06-26 4631

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki