|
69 | 69 | #include "md-bitmap.h"
|
70 | 70 | #include "md-cluster.h"
|
71 | 71 |
|
| 72 | +static const char *action_name[NR_SYNC_ACTIONS] = { |
| 73 | + [ACTION_RESYNC] = "resync", |
| 74 | + [ACTION_RECOVER] = "recover", |
| 75 | + [ACTION_CHECK] = "check", |
| 76 | + [ACTION_REPAIR] = "repair", |
| 77 | + [ACTION_RESHAPE] = "reshape", |
| 78 | + [ACTION_FROZEN] = "frozen", |
| 79 | + [ACTION_IDLE] = "idle", |
| 80 | +}; |
| 81 | + |
72 | 82 | /* pers_list is a list of registered personalities protected by pers_lock. */
|
73 | 83 | static LIST_HEAD(pers_list);
|
74 | 84 | static DEFINE_SPINLOCK(pers_lock);
|
@@ -4868,6 +4878,75 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)
|
4868 | 4878 | static struct md_sysfs_entry md_metadata =
|
4869 | 4879 | __ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
|
4870 | 4880 |
|
| 4881 | +enum sync_action md_sync_action(struct mddev *mddev) |
| 4882 | +{ |
| 4883 | + unsigned long recovery = mddev->recovery; |
| 4884 | + |
| 4885 | + /* |
| 4886 | + * frozen has the highest priority, means running sync_thread will be |
| 4887 | + * stopped immediately, and no new sync_thread can start. |
| 4888 | + */ |
| 4889 | + if (test_bit(MD_RECOVERY_FROZEN, &recovery)) |
| 4890 | + return ACTION_FROZEN; |
| 4891 | + |
| 4892 | + /* |
| 4893 | + * read-only array can't register sync_thread, and it can only |
| 4894 | + * add/remove spares. |
| 4895 | + */ |
| 4896 | + if (!md_is_rdwr(mddev)) |
| 4897 | + return ACTION_IDLE; |
| 4898 | + |
| 4899 | + /* |
| 4900 | + * idle means no sync_thread is running, and no new sync_thread is |
| 4901 | + * requested. |
| 4902 | + */ |
| 4903 | + if (!test_bit(MD_RECOVERY_RUNNING, &recovery) && |
| 4904 | + !test_bit(MD_RECOVERY_NEEDED, &recovery)) |
| 4905 | + return ACTION_IDLE; |
| 4906 | + |
| 4907 | + if (test_bit(MD_RECOVERY_RESHAPE, &recovery) || |
| 4908 | + mddev->reshape_position != MaxSector) |
| 4909 | + return ACTION_RESHAPE; |
| 4910 | + |
| 4911 | + if (test_bit(MD_RECOVERY_RECOVER, &recovery)) |
| 4912 | + return ACTION_RECOVER; |
| 4913 | + |
| 4914 | + if (test_bit(MD_RECOVERY_SYNC, &recovery)) { |
| 4915 | + /* |
| 4916 | + * MD_RECOVERY_CHECK must be paired with |
| 4917 | + * MD_RECOVERY_REQUESTED. |
| 4918 | + */ |
| 4919 | + if (test_bit(MD_RECOVERY_CHECK, &recovery)) |
| 4920 | + return ACTION_CHECK; |
| 4921 | + if (test_bit(MD_RECOVERY_REQUESTED, &recovery)) |
| 4922 | + return ACTION_REPAIR; |
| 4923 | + return ACTION_RESYNC; |
| 4924 | + } |
| 4925 | + |
| 4926 | + /* |
| 4927 | + * MD_RECOVERY_NEEDED or MD_RECOVERY_RUNNING is set, however, no |
| 4928 | + * sync_action is specified. |
| 4929 | + */ |
| 4930 | + return ACTION_IDLE; |
| 4931 | +} |
| 4932 | + |
| 4933 | +enum sync_action md_sync_action_by_name(const char *page) |
| 4934 | +{ |
| 4935 | + enum sync_action action; |
| 4936 | + |
| 4937 | + for (action = 0; action < NR_SYNC_ACTIONS; ++action) { |
| 4938 | + if (cmd_match(page, action_name[action])) |
| 4939 | + return action; |
| 4940 | + } |
| 4941 | + |
| 4942 | + return NR_SYNC_ACTIONS; |
| 4943 | +} |
| 4944 | + |
| 4945 | +const char *md_sync_action_name(enum sync_action action) |
| 4946 | +{ |
| 4947 | + return action_name[action]; |
| 4948 | +} |
| 4949 | + |
4871 | 4950 | static ssize_t
|
4872 | 4951 | action_show(struct mddev *mddev, char *page)
|
4873 | 4952 | {
|
|
0 commit comments