@@ -1714,9 +1714,60 @@ static struct md_sysfs_entry md_raid_disks = {
17141714 .show = md_show_rdisks ,
17151715};
17161716
1717+ static ssize_t
1718+ md_show_scan (mddev_t * mddev , char * page )
1719+ {
1720+ char * type = "none" ;
1721+ if (mddev -> recovery &
1722+ ((1 <<MD_RECOVERY_RUNNING ) || (1 <<MD_RECOVERY_NEEDED ))) {
1723+ if (mddev -> recovery & (1 <<MD_RECOVERY_SYNC )) {
1724+ if (!test_bit (MD_RECOVERY_REQUESTED , & mddev -> recovery ))
1725+ type = "resync" ;
1726+ else if (test_bit (MD_RECOVERY_CHECK , & mddev -> recovery ))
1727+ type = "check" ;
1728+ else
1729+ type = "repair" ;
1730+ } else
1731+ type = "recover" ;
1732+ }
1733+ return sprintf (page , "%s\n" , type );
1734+ }
1735+
1736+ static ssize_t
1737+ md_store_scan (mddev_t * mddev , const char * page , size_t len )
1738+ {
1739+ int canscan = 0 ;
1740+ if (mddev -> recovery &
1741+ ((1 <<MD_RECOVERY_RUNNING ) || (1 <<MD_RECOVERY_NEEDED )))
1742+ return - EBUSY ;
1743+ down (& mddev -> reconfig_sem );
1744+ if (mddev -> pers && mddev -> pers -> sync_request )
1745+ canscan = 1 ;
1746+ up (& mddev -> reconfig_sem );
1747+ if (!canscan )
1748+ return - EINVAL ;
1749+
1750+ if (strcmp (page , "check" )== 0 || strcmp (page , "check\n" )== 0 )
1751+ set_bit (MD_RECOVERY_CHECK , & mddev -> recovery );
1752+ else if (strcmp (page , "repair" )!= 0 && strcmp (page , "repair\n" )!= 0 )
1753+ return - EINVAL ;
1754+ set_bit (MD_RECOVERY_REQUESTED , & mddev -> recovery );
1755+ set_bit (MD_RECOVERY_SYNC , & mddev -> recovery );
1756+ set_bit (MD_RECOVERY_NEEDED , & mddev -> recovery );
1757+ md_wakeup_thread (mddev -> thread );
1758+ return len ;
1759+ }
1760+
1761+ static struct md_sysfs_entry md_scan_mode = {
1762+ .attr = {.name = "scan_mode" , .mode = S_IRUGO |S_IWUSR },
1763+ .show = md_show_scan ,
1764+ .store = md_store_scan ,
1765+ };
1766+
17171767static struct attribute * md_default_attrs [] = {
17181768 & md_level .attr ,
17191769 & md_raid_disks .attr ,
1770+ & md_scan_mode .attr ,
17201771 NULL ,
17211772};
17221773
@@ -3855,7 +3906,8 @@ static void md_do_sync(mddev_t *mddev)
38553906
38563907 is_mddev_idle (mddev ); /* this also initializes IO event counters */
38573908 /* we don't use the checkpoint if there's a bitmap */
3858- if (test_bit (MD_RECOVERY_SYNC , & mddev -> recovery ) && !mddev -> bitmap )
3909+ if (test_bit (MD_RECOVERY_SYNC , & mddev -> recovery ) && !mddev -> bitmap
3910+ && ! test_bit (MD_RECOVERY_REQUESTED , & mddev -> recovery ))
38593911 j = mddev -> recovery_cp ;
38603912 else
38613913 j = 0 ;
@@ -4093,9 +4145,13 @@ void md_check_recovery(mddev_t *mddev)
40934145 set_bit (MD_RECOVERY_NEEDED , & mddev -> recovery );
40944146 goto unlock ;
40954147 }
4096- if (mddev -> recovery )
4097- /* probably just the RECOVERY_NEEDED flag */
4098- mddev -> recovery = 0 ;
4148+ /* Clear some bits that don't mean anything, but
4149+ * might be left set
4150+ */
4151+ clear_bit (MD_RECOVERY_NEEDED , & mddev -> recovery );
4152+ clear_bit (MD_RECOVERY_ERR , & mddev -> recovery );
4153+ clear_bit (MD_RECOVERY_INTR , & mddev -> recovery );
4154+ clear_bit (MD_RECOVERY_DONE , & mddev -> recovery );
40994155
41004156 /* no recovery is running.
41014157 * remove any failed drives, then
@@ -4129,14 +4185,17 @@ void md_check_recovery(mddev_t *mddev)
41294185 }
41304186 }
41314187
4132- if (!spares && (mddev -> recovery_cp == MaxSector )) {
4133- /* nothing we can do ... */
4188+ if (spares ) {
4189+ clear_bit (MD_RECOVERY_SYNC , & mddev -> recovery );
4190+ clear_bit (MD_RECOVERY_CHECK , & mddev -> recovery );
4191+ } else if (mddev -> recovery_cp < MaxSector ) {
4192+ set_bit (MD_RECOVERY_SYNC , & mddev -> recovery );
4193+ } else if (!test_bit (MD_RECOVERY_SYNC , & mddev -> recovery ))
4194+ /* nothing to be done ... */
41344195 goto unlock ;
4135- }
4196+
41364197 if (mddev -> pers -> sync_request ) {
41374198 set_bit (MD_RECOVERY_RUNNING , & mddev -> recovery );
4138- if (!spares )
4139- set_bit (MD_RECOVERY_SYNC , & mddev -> recovery );
41404199 if (spares && mddev -> bitmap && ! mddev -> bitmap -> file ) {
41414200 /* We are adding a device or devices to an array
41424201 * which has the bitmap stored on all devices.
0 commit comments