[v3,3/4] md: sync blockdev before stopping raid or setting readonly

Message ID 20240125062841.1721193-4-linan666@huaweicloud.com
State New
Headers
Series None |

Commit Message

Li Nan Jan. 25, 2024, 6:28 a.m. UTC
  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 | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
  

Comments

kernel test robot Jan. 25, 2024, 1:56 p.m. UTC | #1
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/202401252146.3yACLRcr-lkp@intel.com/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/202401252146.3yACLRcr-lkp@intel.com/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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401252146.3yACLRcr-lkp@intel.com/

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
  

Patch

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 =