diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 5 | ||||
-rw-r--r-- | drivers/md/dm-exception-store.c | 13 | ||||
-rw-r--r-- | drivers/md/dm-exception-store.h | 4 | ||||
-rw-r--r-- | drivers/md/dm-ioctl.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-log-userspace-base.c | 39 | ||||
-rw-r--r-- | drivers/md/dm-log-userspace-transfer.c | 8 | ||||
-rw-r--r-- | drivers/md/dm-log-userspace-transfer.h | 2 | ||||
-rw-r--r-- | drivers/md/dm-mpath.c | 42 | ||||
-rw-r--r-- | drivers/md/dm-raid1.c | 10 | ||||
-rw-r--r-- | drivers/md/dm-snap-persistent.c | 88 | ||||
-rw-r--r-- | drivers/md/dm-snap.c | 23 | ||||
-rw-r--r-- | drivers/md/dm-stripe.c | 15 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 51 | ||||
-rw-r--r-- | drivers/md/dm.c | 47 | ||||
-rw-r--r-- | drivers/md/linear.c | 5 | ||||
-rw-r--r-- | drivers/md/md.c | 29 | ||||
-rw-r--r-- | drivers/md/md.h | 3 | ||||
-rw-r--r-- | drivers/md/multipath.c | 11 | ||||
-rw-r--r-- | drivers/md/raid0.c | 10 | ||||
-rw-r--r-- | drivers/md/raid1.c | 29 | ||||
-rw-r--r-- | drivers/md/raid10.c | 18 | ||||
-rw-r--r-- | drivers/md/raid5.c | 20 |
22 files changed, 323 insertions, 151 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 3319c2fec28e..6986b0059d23 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -108,6 +108,8 @@ static void bitmap_free_page(struct bitmap *bitmap, unsigned char *page) | |||
108 | * allocated while we're using it | 108 | * allocated while we're using it |
109 | */ | 109 | */ |
110 | static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int create) | 110 | static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int create) |
111 | __releases(bitmap->lock) | ||
112 | __acquires(bitmap->lock) | ||
111 | { | 113 | { |
112 | unsigned char *mappage; | 114 | unsigned char *mappage; |
113 | 115 | ||
@@ -325,7 +327,6 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
325 | return 0; | 327 | return 0; |
326 | 328 | ||
327 | bad_alignment: | 329 | bad_alignment: |
328 | rcu_read_unlock(); | ||
329 | return -EINVAL; | 330 | return -EINVAL; |
330 | } | 331 | } |
331 | 332 | ||
@@ -1207,6 +1208,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1207 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | 1208 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, |
1208 | sector_t offset, int *blocks, | 1209 | sector_t offset, int *blocks, |
1209 | int create) | 1210 | int create) |
1211 | __releases(bitmap->lock) | ||
1212 | __acquires(bitmap->lock) | ||
1210 | { | 1213 | { |
1211 | /* If 'create', we might release the lock and reclaim it. | 1214 | /* If 'create', we might release the lock and reclaim it. |
1212 | * The lock must have been taken with interrupts enabled. | 1215 | * The lock must have been taken with interrupts enabled. |
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 3710ff88fc10..556acff3952f 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c | |||
@@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exception_store *store, | |||
171 | */ | 171 | */ |
172 | chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9); | 172 | chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9); |
173 | 173 | ||
174 | return dm_exception_store_set_chunk_size(store, chunk_size_ulong, | ||
175 | error); | ||
176 | } | ||
177 | |||
178 | int dm_exception_store_set_chunk_size(struct dm_exception_store *store, | ||
179 | unsigned long chunk_size_ulong, | ||
180 | char **error) | ||
181 | { | ||
174 | /* Check chunk_size is a power of 2 */ | 182 | /* Check chunk_size is a power of 2 */ |
175 | if (!is_power_of_2(chunk_size_ulong)) { | 183 | if (!is_power_of_2(chunk_size_ulong)) { |
176 | *error = "Chunk size is not a power of 2"; | 184 | *error = "Chunk size is not a power of 2"; |
@@ -183,6 +191,11 @@ static int set_chunk_size(struct dm_exception_store *store, | |||
183 | return -EINVAL; | 191 | return -EINVAL; |
184 | } | 192 | } |
185 | 193 | ||
194 | if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) { | ||
195 | *error = "Chunk size is too high"; | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
186 | store->chunk_size = chunk_size_ulong; | 199 | store->chunk_size = chunk_size_ulong; |
187 | store->chunk_mask = chunk_size_ulong - 1; | 200 | store->chunk_mask = chunk_size_ulong - 1; |
188 | store->chunk_shift = ffs(chunk_size_ulong) - 1; | 201 | store->chunk_shift = ffs(chunk_size_ulong) - 1; |
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 2442c8c07898..812c71872ba0 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h | |||
@@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(struct dm_exception_store *store, | |||
168 | int dm_exception_store_type_register(struct dm_exception_store_type *type); | 168 | int dm_exception_store_type_register(struct dm_exception_store_type *type); |
169 | int dm_exception_store_type_unregister(struct dm_exception_store_type *type); | 169 | int dm_exception_store_type_unregister(struct dm_exception_store_type *type); |
170 | 170 | ||
171 | int dm_exception_store_set_chunk_size(struct dm_exception_store *store, | ||
172 | unsigned long chunk_size_ulong, | ||
173 | char **error); | ||
174 | |||
171 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | 175 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, |
172 | unsigned *args_used, | 176 | unsigned *args_used, |
173 | struct dm_exception_store **store); | 177 | struct dm_exception_store **store); |
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 7f77f18fcafa..a67942931582 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = { | |||
1532 | static struct miscdevice _dm_misc = { | 1532 | static struct miscdevice _dm_misc = { |
1533 | .minor = MISC_DYNAMIC_MINOR, | 1533 | .minor = MISC_DYNAMIC_MINOR, |
1534 | .name = DM_NAME, | 1534 | .name = DM_NAME, |
1535 | .devnode = "mapper/control", | 1535 | .nodename = "mapper/control", |
1536 | .fops = &_ctl_fops | 1536 | .fops = &_ctl_fops |
1537 | }; | 1537 | }; |
1538 | 1538 | ||
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index e69b96560997..652bd33109e3 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c | |||
@@ -21,6 +21,7 @@ struct log_c { | |||
21 | struct dm_target *ti; | 21 | struct dm_target *ti; |
22 | uint32_t region_size; | 22 | uint32_t region_size; |
23 | region_t region_count; | 23 | region_t region_count; |
24 | uint64_t luid; | ||
24 | char uuid[DM_UUID_LEN]; | 25 | char uuid[DM_UUID_LEN]; |
25 | 26 | ||
26 | char *usr_argv_str; | 27 | char *usr_argv_str; |
@@ -63,7 +64,7 @@ static int userspace_do_request(struct log_c *lc, const char *uuid, | |||
63 | * restored. | 64 | * restored. |
64 | */ | 65 | */ |
65 | retry: | 66 | retry: |
66 | r = dm_consult_userspace(uuid, request_type, data, | 67 | r = dm_consult_userspace(uuid, lc->luid, request_type, data, |
67 | data_size, rdata, rdata_size); | 68 | data_size, rdata, rdata_size); |
68 | 69 | ||
69 | if (r != -ESRCH) | 70 | if (r != -ESRCH) |
@@ -74,14 +75,15 @@ retry: | |||
74 | set_current_state(TASK_INTERRUPTIBLE); | 75 | set_current_state(TASK_INTERRUPTIBLE); |
75 | schedule_timeout(2*HZ); | 76 | schedule_timeout(2*HZ); |
76 | DMWARN("Attempting to contact userspace log server..."); | 77 | DMWARN("Attempting to contact userspace log server..."); |
77 | r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str, | 78 | r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_CTR, |
79 | lc->usr_argv_str, | ||
78 | strlen(lc->usr_argv_str) + 1, | 80 | strlen(lc->usr_argv_str) + 1, |
79 | NULL, NULL); | 81 | NULL, NULL); |
80 | if (!r) | 82 | if (!r) |
81 | break; | 83 | break; |
82 | } | 84 | } |
83 | DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); | 85 | DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); |
84 | r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL, | 86 | r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_RESUME, NULL, |
85 | 0, NULL, NULL); | 87 | 0, NULL, NULL); |
86 | if (!r) | 88 | if (!r) |
87 | goto retry; | 89 | goto retry; |
@@ -111,10 +113,9 @@ static int build_constructor_string(struct dm_target *ti, | |||
111 | return -ENOMEM; | 113 | return -ENOMEM; |
112 | } | 114 | } |
113 | 115 | ||
114 | for (i = 0, str_size = 0; i < argc; i++) | 116 | str_size = sprintf(str, "%llu", (unsigned long long)ti->len); |
115 | str_size += sprintf(str + str_size, "%s ", argv[i]); | 117 | for (i = 0; i < argc; i++) |
116 | str_size += sprintf(str + str_size, "%llu", | 118 | str_size += sprintf(str + str_size, " %s", argv[i]); |
117 | (unsigned long long)ti->len); | ||
118 | 119 | ||
119 | *ctr_str = str; | 120 | *ctr_str = str; |
120 | return str_size; | 121 | return str_size; |
@@ -154,6 +155,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
154 | return -ENOMEM; | 155 | return -ENOMEM; |
155 | } | 156 | } |
156 | 157 | ||
158 | /* The ptr value is sufficient for local unique id */ | ||
159 | lc->luid = (uint64_t)lc; | ||
160 | |||
157 | lc->ti = ti; | 161 | lc->ti = ti; |
158 | 162 | ||
159 | if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { | 163 | if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { |
@@ -173,7 +177,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
173 | } | 177 | } |
174 | 178 | ||
175 | /* Send table string */ | 179 | /* Send table string */ |
176 | r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR, | 180 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR, |
177 | ctr_str, str_size, NULL, NULL); | 181 | ctr_str, str_size, NULL, NULL); |
178 | 182 | ||
179 | if (r == -ESRCH) { | 183 | if (r == -ESRCH) { |
@@ -183,7 +187,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
183 | 187 | ||
184 | /* Since the region size does not change, get it now */ | 188 | /* Since the region size does not change, get it now */ |
185 | rdata_size = sizeof(rdata); | 189 | rdata_size = sizeof(rdata); |
186 | r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE, | 190 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_GET_REGION_SIZE, |
187 | NULL, 0, (char *)&rdata, &rdata_size); | 191 | NULL, 0, (char *)&rdata, &rdata_size); |
188 | 192 | ||
189 | if (r) { | 193 | if (r) { |
@@ -212,7 +216,7 @@ static void userspace_dtr(struct dm_dirty_log *log) | |||
212 | int r; | 216 | int r; |
213 | struct log_c *lc = log->context; | 217 | struct log_c *lc = log->context; |
214 | 218 | ||
215 | r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR, | 219 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR, |
216 | NULL, 0, | 220 | NULL, 0, |
217 | NULL, NULL); | 221 | NULL, NULL); |
218 | 222 | ||
@@ -227,7 +231,7 @@ static int userspace_presuspend(struct dm_dirty_log *log) | |||
227 | int r; | 231 | int r; |
228 | struct log_c *lc = log->context; | 232 | struct log_c *lc = log->context; |
229 | 233 | ||
230 | r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND, | 234 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND, |
231 | NULL, 0, | 235 | NULL, 0, |
232 | NULL, NULL); | 236 | NULL, NULL); |
233 | 237 | ||
@@ -239,7 +243,7 @@ static int userspace_postsuspend(struct dm_dirty_log *log) | |||
239 | int r; | 243 | int r; |
240 | struct log_c *lc = log->context; | 244 | struct log_c *lc = log->context; |
241 | 245 | ||
242 | r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND, | 246 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND, |
243 | NULL, 0, | 247 | NULL, 0, |
244 | NULL, NULL); | 248 | NULL, NULL); |
245 | 249 | ||
@@ -252,7 +256,7 @@ static int userspace_resume(struct dm_dirty_log *log) | |||
252 | struct log_c *lc = log->context; | 256 | struct log_c *lc = log->context; |
253 | 257 | ||
254 | lc->in_sync_hint = 0; | 258 | lc->in_sync_hint = 0; |
255 | r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME, | 259 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_RESUME, |
256 | NULL, 0, | 260 | NULL, 0, |
257 | NULL, NULL); | 261 | NULL, NULL); |
258 | 262 | ||
@@ -561,6 +565,7 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type, | |||
561 | char *result, unsigned maxlen) | 565 | char *result, unsigned maxlen) |
562 | { | 566 | { |
563 | int r = 0; | 567 | int r = 0; |
568 | char *table_args; | ||
564 | size_t sz = (size_t)maxlen; | 569 | size_t sz = (size_t)maxlen; |
565 | struct log_c *lc = log->context; | 570 | struct log_c *lc = log->context; |
566 | 571 | ||
@@ -577,8 +582,12 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type, | |||
577 | break; | 582 | break; |
578 | case STATUSTYPE_TABLE: | 583 | case STATUSTYPE_TABLE: |
579 | sz = 0; | 584 | sz = 0; |
580 | DMEMIT("%s %u %s %s", log->type->name, lc->usr_argc + 1, | 585 | table_args = strchr(lc->usr_argv_str, ' '); |
581 | lc->uuid, lc->usr_argv_str); | 586 | BUG_ON(!table_args); /* There will always be a ' ' */ |
587 | table_args++; | ||
588 | |||
589 | DMEMIT("%s %u %s %s ", log->type->name, lc->usr_argc, | ||
590 | lc->uuid, table_args); | ||
582 | break; | 591 | break; |
583 | } | 592 | } |
584 | return (r) ? 0 : (int)sz; | 593 | return (r) ? 0 : (int)sz; |
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c index 0ca1ee768a1f..ba0edad2d048 100644 --- a/drivers/md/dm-log-userspace-transfer.c +++ b/drivers/md/dm-log-userspace-transfer.c | |||
@@ -108,7 +108,7 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr) | |||
108 | *(pkg->data_size) = 0; | 108 | *(pkg->data_size) = 0; |
109 | } else if (tfr->data_size > *(pkg->data_size)) { | 109 | } else if (tfr->data_size > *(pkg->data_size)) { |
110 | DMERR("Insufficient space to receive package [%u] " | 110 | DMERR("Insufficient space to receive package [%u] " |
111 | "(%u vs %lu)", tfr->request_type, | 111 | "(%u vs %zu)", tfr->request_type, |
112 | tfr->data_size, *(pkg->data_size)); | 112 | tfr->data_size, *(pkg->data_size)); |
113 | 113 | ||
114 | *(pkg->data_size) = 0; | 114 | *(pkg->data_size) = 0; |
@@ -147,7 +147,8 @@ static void cn_ulog_callback(void *data) | |||
147 | 147 | ||
148 | /** | 148 | /** |
149 | * dm_consult_userspace | 149 | * dm_consult_userspace |
150 | * @uuid: log's uuid (must be DM_UUID_LEN in size) | 150 | * @uuid: log's universal unique identifier (must be DM_UUID_LEN in size) |
151 | * @luid: log's local unique identifier | ||
151 | * @request_type: found in include/linux/dm-log-userspace.h | 152 | * @request_type: found in include/linux/dm-log-userspace.h |
152 | * @data: data to tx to the server | 153 | * @data: data to tx to the server |
153 | * @data_size: size of data in bytes | 154 | * @data_size: size of data in bytes |
@@ -163,7 +164,7 @@ static void cn_ulog_callback(void *data) | |||
163 | * | 164 | * |
164 | * Returns: 0 on success, -EXXX on failure | 165 | * Returns: 0 on success, -EXXX on failure |
165 | **/ | 166 | **/ |
166 | int dm_consult_userspace(const char *uuid, int request_type, | 167 | int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type, |
167 | char *data, size_t data_size, | 168 | char *data, size_t data_size, |
168 | char *rdata, size_t *rdata_size) | 169 | char *rdata, size_t *rdata_size) |
169 | { | 170 | { |
@@ -190,6 +191,7 @@ resend: | |||
190 | 191 | ||
191 | memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); | 192 | memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); |
192 | memcpy(tfr->uuid, uuid, DM_UUID_LEN); | 193 | memcpy(tfr->uuid, uuid, DM_UUID_LEN); |
194 | tfr->luid = luid; | ||
193 | tfr->seq = dm_ulog_seq++; | 195 | tfr->seq = dm_ulog_seq++; |
194 | 196 | ||
195 | /* | 197 | /* |
diff --git a/drivers/md/dm-log-userspace-transfer.h b/drivers/md/dm-log-userspace-transfer.h index c26d8e4e2710..04ee874f9153 100644 --- a/drivers/md/dm-log-userspace-transfer.h +++ b/drivers/md/dm-log-userspace-transfer.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | int dm_ulog_tfr_init(void); | 12 | int dm_ulog_tfr_init(void); |
13 | void dm_ulog_tfr_exit(void); | 13 | void dm_ulog_tfr_exit(void); |
14 | int dm_consult_userspace(const char *uuid, int request_type, | 14 | int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type, |
15 | char *data, size_t data_size, | 15 | char *data, size_t data_size, |
16 | char *rdata, size_t *rdata_size); | 16 | char *rdata, size_t *rdata_size); |
17 | 17 | ||
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 6f0d90d4a541..32d0b878eccc 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -64,6 +64,7 @@ struct multipath { | |||
64 | spinlock_t lock; | 64 | spinlock_t lock; |
65 | 65 | ||
66 | const char *hw_handler_name; | 66 | const char *hw_handler_name; |
67 | char *hw_handler_params; | ||
67 | unsigned nr_priority_groups; | 68 | unsigned nr_priority_groups; |
68 | struct list_head priority_groups; | 69 | struct list_head priority_groups; |
69 | unsigned pg_init_required; /* pg_init needs calling? */ | 70 | unsigned pg_init_required; /* pg_init needs calling? */ |
@@ -219,6 +220,7 @@ static void free_multipath(struct multipath *m) | |||
219 | } | 220 | } |
220 | 221 | ||
221 | kfree(m->hw_handler_name); | 222 | kfree(m->hw_handler_name); |
223 | kfree(m->hw_handler_params); | ||
222 | mempool_destroy(m->mpio_pool); | 224 | mempool_destroy(m->mpio_pool); |
223 | kfree(m); | 225 | kfree(m); |
224 | } | 226 | } |
@@ -615,6 +617,17 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, | |||
615 | dm_put_device(ti, p->path.dev); | 617 | dm_put_device(ti, p->path.dev); |
616 | goto bad; | 618 | goto bad; |
617 | } | 619 | } |
620 | |||
621 | if (m->hw_handler_params) { | ||
622 | r = scsi_dh_set_params(q, m->hw_handler_params); | ||
623 | if (r < 0) { | ||
624 | ti->error = "unable to set hardware " | ||
625 | "handler parameters"; | ||
626 | scsi_dh_detach(q); | ||
627 | dm_put_device(ti, p->path.dev); | ||
628 | goto bad; | ||
629 | } | ||
630 | } | ||
618 | } | 631 | } |
619 | 632 | ||
620 | r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); | 633 | r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); |
@@ -705,6 +718,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as, | |||
705 | static int parse_hw_handler(struct arg_set *as, struct multipath *m) | 718 | static int parse_hw_handler(struct arg_set *as, struct multipath *m) |
706 | { | 719 | { |
707 | unsigned hw_argc; | 720 | unsigned hw_argc; |
721 | int ret; | ||
708 | struct dm_target *ti = m->ti; | 722 | struct dm_target *ti = m->ti; |
709 | 723 | ||
710 | static struct param _params[] = { | 724 | static struct param _params[] = { |
@@ -726,17 +740,33 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) | |||
726 | request_module("scsi_dh_%s", m->hw_handler_name); | 740 | request_module("scsi_dh_%s", m->hw_handler_name); |
727 | if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { | 741 | if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { |
728 | ti->error = "unknown hardware handler type"; | 742 | ti->error = "unknown hardware handler type"; |
729 | kfree(m->hw_handler_name); | 743 | ret = -EINVAL; |
730 | m->hw_handler_name = NULL; | 744 | goto fail; |
731 | return -EINVAL; | ||
732 | } | 745 | } |
733 | 746 | ||
734 | if (hw_argc > 1) | 747 | if (hw_argc > 1) { |
735 | DMWARN("Ignoring user-specified arguments for " | 748 | char *p; |
736 | "hardware handler \"%s\"", m->hw_handler_name); | 749 | int i, j, len = 4; |
750 | |||
751 | for (i = 0; i <= hw_argc - 2; i++) | ||
752 | len += strlen(as->argv[i]) + 1; | ||
753 | p = m->hw_handler_params = kzalloc(len, GFP_KERNEL); | ||
754 | if (!p) { | ||
755 | ti->error = "memory allocation failed"; | ||
756 | ret = -ENOMEM; | ||
757 | goto fail; | ||
758 | } | ||
759 | j = sprintf(p, "%d", hw_argc - 1); | ||
760 | for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1) | ||
761 | j = sprintf(p, "%s", as->argv[i]); | ||
762 | } | ||
737 | consume(as, hw_argc - 1); | 763 | consume(as, hw_argc - 1); |
738 | 764 | ||
739 | return 0; | 765 | return 0; |
766 | fail: | ||
767 | kfree(m->hw_handler_name); | ||
768 | m->hw_handler_name = NULL; | ||
769 | return ret; | ||
740 | } | 770 | } |
741 | 771 | ||
742 | static int parse_features(struct arg_set *as, struct multipath *m) | 772 | static int parse_features(struct arg_set *as, struct multipath *m) |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 9726577cde49..cc9dc79b0784 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -648,7 +648,13 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
648 | */ | 648 | */ |
649 | dm_rh_inc_pending(ms->rh, &sync); | 649 | dm_rh_inc_pending(ms->rh, &sync); |
650 | dm_rh_inc_pending(ms->rh, &nosync); | 650 | dm_rh_inc_pending(ms->rh, &nosync); |
651 | ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0; | 651 | |
652 | /* | ||
653 | * If the flush fails on a previous call and succeeds here, | ||
654 | * we must not reset the log_failure variable. We need | ||
655 | * userspace interaction to do that. | ||
656 | */ | ||
657 | ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure; | ||
652 | 658 | ||
653 | /* | 659 | /* |
654 | * Dispatch io. | 660 | * Dispatch io. |
@@ -1123,7 +1129,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1123 | if (error == -EOPNOTSUPP) | 1129 | if (error == -EOPNOTSUPP) |
1124 | goto out; | 1130 | goto out; |
1125 | 1131 | ||
1126 | if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) | 1132 | if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD)) |
1127 | goto out; | 1133 | goto out; |
1128 | 1134 | ||
1129 | if (unlikely(error)) { | 1135 | if (unlikely(error)) { |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 6e3fe4f14934..d5b2e08750d5 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -106,6 +106,13 @@ struct pstore { | |||
106 | void *zero_area; | 106 | void *zero_area; |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * An area used for header. The header can be written | ||
110 | * concurrently with metadata (when invalidating the snapshot), | ||
111 | * so it needs a separate buffer. | ||
112 | */ | ||
113 | void *header_area; | ||
114 | |||
115 | /* | ||
109 | * Used to keep track of which metadata area the data in | 116 | * Used to keep track of which metadata area the data in |
110 | * 'chunk' refers to. | 117 | * 'chunk' refers to. |
111 | */ | 118 | */ |
@@ -148,16 +155,27 @@ static int alloc_area(struct pstore *ps) | |||
148 | */ | 155 | */ |
149 | ps->area = vmalloc(len); | 156 | ps->area = vmalloc(len); |
150 | if (!ps->area) | 157 | if (!ps->area) |
151 | return r; | 158 | goto err_area; |
152 | 159 | ||
153 | ps->zero_area = vmalloc(len); | 160 | ps->zero_area = vmalloc(len); |
154 | if (!ps->zero_area) { | 161 | if (!ps->zero_area) |
155 | vfree(ps->area); | 162 | goto err_zero_area; |
156 | return r; | ||
157 | } | ||
158 | memset(ps->zero_area, 0, len); | 163 | memset(ps->zero_area, 0, len); |
159 | 164 | ||
165 | ps->header_area = vmalloc(len); | ||
166 | if (!ps->header_area) | ||
167 | goto err_header_area; | ||
168 | |||
160 | return 0; | 169 | return 0; |
170 | |||
171 | err_header_area: | ||
172 | vfree(ps->zero_area); | ||
173 | |||
174 | err_zero_area: | ||
175 | vfree(ps->area); | ||
176 | |||
177 | err_area: | ||
178 | return r; | ||
161 | } | 179 | } |
162 | 180 | ||
163 | static void free_area(struct pstore *ps) | 181 | static void free_area(struct pstore *ps) |
@@ -169,6 +187,10 @@ static void free_area(struct pstore *ps) | |||
169 | if (ps->zero_area) | 187 | if (ps->zero_area) |
170 | vfree(ps->zero_area); | 188 | vfree(ps->zero_area); |
171 | ps->zero_area = NULL; | 189 | ps->zero_area = NULL; |
190 | |||
191 | if (ps->header_area) | ||
192 | vfree(ps->header_area); | ||
193 | ps->header_area = NULL; | ||
172 | } | 194 | } |
173 | 195 | ||
174 | struct mdata_req { | 196 | struct mdata_req { |
@@ -188,7 +210,8 @@ static void do_metadata(struct work_struct *work) | |||
188 | /* | 210 | /* |
189 | * Read or write a chunk aligned and sized block of data from a device. | 211 | * Read or write a chunk aligned and sized block of data from a device. |
190 | */ | 212 | */ |
191 | static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata) | 213 | static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, |
214 | int metadata) | ||
192 | { | 215 | { |
193 | struct dm_io_region where = { | 216 | struct dm_io_region where = { |
194 | .bdev = ps->store->cow->bdev, | 217 | .bdev = ps->store->cow->bdev, |
@@ -198,7 +221,7 @@ static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata) | |||
198 | struct dm_io_request io_req = { | 221 | struct dm_io_request io_req = { |
199 | .bi_rw = rw, | 222 | .bi_rw = rw, |
200 | .mem.type = DM_IO_VMA, | 223 | .mem.type = DM_IO_VMA, |
201 | .mem.ptr.vma = ps->area, | 224 | .mem.ptr.vma = area, |
202 | .client = ps->io_client, | 225 | .client = ps->io_client, |
203 | .notify.fn = NULL, | 226 | .notify.fn = NULL, |
204 | }; | 227 | }; |
@@ -240,7 +263,7 @@ static int area_io(struct pstore *ps, int rw) | |||
240 | 263 | ||
241 | chunk = area_location(ps, ps->current_area); | 264 | chunk = area_location(ps, ps->current_area); |
242 | 265 | ||
243 | r = chunk_io(ps, chunk, rw, 0); | 266 | r = chunk_io(ps, ps->area, chunk, rw, 0); |
244 | if (r) | 267 | if (r) |
245 | return r; | 268 | return r; |
246 | 269 | ||
@@ -254,20 +277,7 @@ static void zero_memory_area(struct pstore *ps) | |||
254 | 277 | ||
255 | static int zero_disk_area(struct pstore *ps, chunk_t area) | 278 | static int zero_disk_area(struct pstore *ps, chunk_t area) |
256 | { | 279 | { |
257 | struct dm_io_region where = { | 280 | return chunk_io(ps, ps->zero_area, area_location(ps, area), WRITE, 0); |
258 | .bdev = ps->store->cow->bdev, | ||
259 | .sector = ps->store->chunk_size * area_location(ps, area), | ||
260 | .count = ps->store->chunk_size, | ||
261 | }; | ||
262 | struct dm_io_request io_req = { | ||
263 | .bi_rw = WRITE, | ||
264 | .mem.type = DM_IO_VMA, | ||
265 | .mem.ptr.vma = ps->zero_area, | ||
266 | .client = ps->io_client, | ||
267 | .notify.fn = NULL, | ||
268 | }; | ||
269 | |||
270 | return dm_io(&io_req, 1, &where, NULL); | ||
271 | } | 281 | } |
272 | 282 | ||
273 | static int read_header(struct pstore *ps, int *new_snapshot) | 283 | static int read_header(struct pstore *ps, int *new_snapshot) |
@@ -276,6 +286,7 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
276 | struct disk_header *dh; | 286 | struct disk_header *dh; |
277 | chunk_t chunk_size; | 287 | chunk_t chunk_size; |
278 | int chunk_size_supplied = 1; | 288 | int chunk_size_supplied = 1; |
289 | char *chunk_err; | ||
279 | 290 | ||
280 | /* | 291 | /* |
281 | * Use default chunk size (or hardsect_size, if larger) if none supplied | 292 | * Use default chunk size (or hardsect_size, if larger) if none supplied |
@@ -297,11 +308,11 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
297 | if (r) | 308 | if (r) |
298 | return r; | 309 | return r; |
299 | 310 | ||
300 | r = chunk_io(ps, 0, READ, 1); | 311 | r = chunk_io(ps, ps->header_area, 0, READ, 1); |
301 | if (r) | 312 | if (r) |
302 | goto bad; | 313 | goto bad; |
303 | 314 | ||
304 | dh = (struct disk_header *) ps->area; | 315 | dh = ps->header_area; |
305 | 316 | ||
306 | if (le32_to_cpu(dh->magic) == 0) { | 317 | if (le32_to_cpu(dh->magic) == 0) { |
307 | *new_snapshot = 1; | 318 | *new_snapshot = 1; |
@@ -319,20 +330,25 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
319 | ps->version = le32_to_cpu(dh->version); | 330 | ps->version = le32_to_cpu(dh->version); |
320 | chunk_size = le32_to_cpu(dh->chunk_size); | 331 | chunk_size = le32_to_cpu(dh->chunk_size); |
321 | 332 | ||
322 | if (!chunk_size_supplied || ps->store->chunk_size == chunk_size) | 333 | if (ps->store->chunk_size == chunk_size) |
323 | return 0; | 334 | return 0; |
324 | 335 | ||
325 | DMWARN("chunk size %llu in device metadata overrides " | 336 | if (chunk_size_supplied) |
326 | "table chunk size of %llu.", | 337 | DMWARN("chunk size %llu in device metadata overrides " |
327 | (unsigned long long)chunk_size, | 338 | "table chunk size of %llu.", |
328 | (unsigned long long)ps->store->chunk_size); | 339 | (unsigned long long)chunk_size, |
340 | (unsigned long long)ps->store->chunk_size); | ||
329 | 341 | ||
330 | /* We had a bogus chunk_size. Fix stuff up. */ | 342 | /* We had a bogus chunk_size. Fix stuff up. */ |
331 | free_area(ps); | 343 | free_area(ps); |
332 | 344 | ||
333 | ps->store->chunk_size = chunk_size; | 345 | r = dm_exception_store_set_chunk_size(ps->store, chunk_size, |
334 | ps->store->chunk_mask = chunk_size - 1; | 346 | &chunk_err); |
335 | ps->store->chunk_shift = ffs(chunk_size) - 1; | 347 | if (r) { |
348 | DMERR("invalid on-disk chunk size %llu: %s.", | ||
349 | (unsigned long long)chunk_size, chunk_err); | ||
350 | return r; | ||
351 | } | ||
336 | 352 | ||
337 | r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), | 353 | r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), |
338 | ps->io_client); | 354 | ps->io_client); |
@@ -351,15 +367,15 @@ static int write_header(struct pstore *ps) | |||
351 | { | 367 | { |
352 | struct disk_header *dh; | 368 | struct disk_header *dh; |
353 | 369 | ||
354 | memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT); | 370 | memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT); |
355 | 371 | ||
356 | dh = (struct disk_header *) ps->area; | 372 | dh = ps->header_area; |
357 | dh->magic = cpu_to_le32(SNAP_MAGIC); | 373 | dh->magic = cpu_to_le32(SNAP_MAGIC); |
358 | dh->valid = cpu_to_le32(ps->valid); | 374 | dh->valid = cpu_to_le32(ps->valid); |
359 | dh->version = cpu_to_le32(ps->version); | 375 | dh->version = cpu_to_le32(ps->version); |
360 | dh->chunk_size = cpu_to_le32(ps->store->chunk_size); | 376 | dh->chunk_size = cpu_to_le32(ps->store->chunk_size); |
361 | 377 | ||
362 | return chunk_io(ps, 0, WRITE, 1); | 378 | return chunk_io(ps, ps->header_area, 0, WRITE, 1); |
363 | } | 379 | } |
364 | 380 | ||
365 | /* | 381 | /* |
@@ -679,6 +695,8 @@ static int persistent_ctr(struct dm_exception_store *store, | |||
679 | ps->valid = 1; | 695 | ps->valid = 1; |
680 | ps->version = SNAPSHOT_DISK_VERSION; | 696 | ps->version = SNAPSHOT_DISK_VERSION; |
681 | ps->area = NULL; | 697 | ps->area = NULL; |
698 | ps->zero_area = NULL; | ||
699 | ps->header_area = NULL; | ||
682 | ps->next_free = 2; /* skipping the header and first area */ | 700 | ps->next_free = 2; /* skipping the header and first area */ |
683 | ps->current_committed = 0; | 701 | ps->current_committed = 0; |
684 | 702 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index d573165cd2b7..57f1bf7f3b7a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -1176,6 +1176,15 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, | |||
1176 | return 0; | 1176 | return 0; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int snapshot_iterate_devices(struct dm_target *ti, | ||
1180 | iterate_devices_callout_fn fn, void *data) | ||
1181 | { | ||
1182 | struct dm_snapshot *snap = ti->private; | ||
1183 | |||
1184 | return fn(ti, snap->origin, 0, ti->len, data); | ||
1185 | } | ||
1186 | |||
1187 | |||
1179 | /*----------------------------------------------------------------- | 1188 | /*----------------------------------------------------------------- |
1180 | * Origin methods | 1189 | * Origin methods |
1181 | *---------------------------------------------------------------*/ | 1190 | *---------------------------------------------------------------*/ |
@@ -1410,20 +1419,29 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, | |||
1410 | return 0; | 1419 | return 0; |
1411 | } | 1420 | } |
1412 | 1421 | ||
1422 | static int origin_iterate_devices(struct dm_target *ti, | ||
1423 | iterate_devices_callout_fn fn, void *data) | ||
1424 | { | ||
1425 | struct dm_dev *dev = ti->private; | ||
1426 | |||
1427 | return fn(ti, dev, 0, ti->len, data); | ||
1428 | } | ||
1429 | |||
1413 | static struct target_type origin_target = { | 1430 | static struct target_type origin_target = { |
1414 | .name = "snapshot-origin", | 1431 | .name = "snapshot-origin", |
1415 | .version = {1, 6, 0}, | 1432 | .version = {1, 7, 0}, |
1416 | .module = THIS_MODULE, | 1433 | .module = THIS_MODULE, |
1417 | .ctr = origin_ctr, | 1434 | .ctr = origin_ctr, |
1418 | .dtr = origin_dtr, | 1435 | .dtr = origin_dtr, |
1419 | .map = origin_map, | 1436 | .map = origin_map, |
1420 | .resume = origin_resume, | 1437 | .resume = origin_resume, |
1421 | .status = origin_status, | 1438 | .status = origin_status, |
1439 | .iterate_devices = origin_iterate_devices, | ||
1422 | }; | 1440 | }; |
1423 | 1441 | ||
1424 | static struct target_type snapshot_target = { | 1442 | static struct target_type snapshot_target = { |
1425 | .name = "snapshot", | 1443 | .name = "snapshot", |
1426 | .version = {1, 6, 0}, | 1444 | .version = {1, 7, 0}, |
1427 | .module = THIS_MODULE, | 1445 | .module = THIS_MODULE, |
1428 | .ctr = snapshot_ctr, | 1446 | .ctr = snapshot_ctr, |
1429 | .dtr = snapshot_dtr, | 1447 | .dtr = snapshot_dtr, |
@@ -1431,6 +1449,7 @@ static struct target_type snapshot_target = { | |||
1431 | .end_io = snapshot_end_io, | 1449 | .end_io = snapshot_end_io, |
1432 | .resume = snapshot_resume, | 1450 | .resume = snapshot_resume, |
1433 | .status = snapshot_status, | 1451 | .status = snapshot_status, |
1452 | .iterate_devices = snapshot_iterate_devices, | ||
1434 | }; | 1453 | }; |
1435 | 1454 | ||
1436 | static int __init dm_snapshot_init(void) | 1455 | static int __init dm_snapshot_init(void) |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 4e0e5937e42a..e0efc1adcaff 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -285,7 +285,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio, | |||
285 | if (!error) | 285 | if (!error) |
286 | return 0; /* I/O complete */ | 286 | return 0; /* I/O complete */ |
287 | 287 | ||
288 | if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) | 288 | if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD)) |
289 | return error; | 289 | return error; |
290 | 290 | ||
291 | if (error == -EOPNOTSUPP) | 291 | if (error == -EOPNOTSUPP) |
@@ -329,9 +329,19 @@ static int stripe_iterate_devices(struct dm_target *ti, | |||
329 | return ret; | 329 | return ret; |
330 | } | 330 | } |
331 | 331 | ||
332 | static void stripe_io_hints(struct dm_target *ti, | ||
333 | struct queue_limits *limits) | ||
334 | { | ||
335 | struct stripe_c *sc = ti->private; | ||
336 | unsigned chunk_size = (sc->chunk_mask + 1) << 9; | ||
337 | |||
338 | blk_limits_io_min(limits, chunk_size); | ||
339 | blk_limits_io_opt(limits, chunk_size * sc->stripes); | ||
340 | } | ||
341 | |||
332 | static struct target_type stripe_target = { | 342 | static struct target_type stripe_target = { |
333 | .name = "striped", | 343 | .name = "striped", |
334 | .version = {1, 2, 0}, | 344 | .version = {1, 3, 0}, |
335 | .module = THIS_MODULE, | 345 | .module = THIS_MODULE, |
336 | .ctr = stripe_ctr, | 346 | .ctr = stripe_ctr, |
337 | .dtr = stripe_dtr, | 347 | .dtr = stripe_dtr, |
@@ -339,6 +349,7 @@ static struct target_type stripe_target = { | |||
339 | .end_io = stripe_end_io, | 349 | .end_io = stripe_end_io, |
340 | .status = stripe_status, | 350 | .status = stripe_status, |
341 | .iterate_devices = stripe_iterate_devices, | 351 | .iterate_devices = stripe_iterate_devices, |
352 | .io_hints = stripe_io_hints, | ||
342 | }; | 353 | }; |
343 | 354 | ||
344 | int __init dm_stripe_init(void) | 355 | int __init dm_stripe_init(void) |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index d952b3441913..1a6cb3c7822e 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -343,10 +343,10 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
343 | } | 343 | } |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * If possible, this checks an area of a destination device is valid. | 346 | * If possible, this checks an area of a destination device is invalid. |
347 | */ | 347 | */ |
348 | static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | 348 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, |
349 | sector_t start, sector_t len, void *data) | 349 | sector_t start, sector_t len, void *data) |
350 | { | 350 | { |
351 | struct queue_limits *limits = data; | 351 | struct queue_limits *limits = data; |
352 | struct block_device *bdev = dev->bdev; | 352 | struct block_device *bdev = dev->bdev; |
@@ -357,36 +357,40 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | |||
357 | char b[BDEVNAME_SIZE]; | 357 | char b[BDEVNAME_SIZE]; |
358 | 358 | ||
359 | if (!dev_size) | 359 | if (!dev_size) |
360 | return 1; | 360 | return 0; |
361 | 361 | ||
362 | if ((start >= dev_size) || (start + len > dev_size)) { | 362 | if ((start >= dev_size) || (start + len > dev_size)) { |
363 | DMWARN("%s: %s too small for target", | 363 | DMWARN("%s: %s too small for target: " |
364 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 364 | "start=%llu, len=%llu, dev_size=%llu", |
365 | return 0; | 365 | dm_device_name(ti->table->md), bdevname(bdev, b), |
366 | (unsigned long long)start, | ||
367 | (unsigned long long)len, | ||
368 | (unsigned long long)dev_size); | ||
369 | return 1; | ||
366 | } | 370 | } |
367 | 371 | ||
368 | if (logical_block_size_sectors <= 1) | 372 | if (logical_block_size_sectors <= 1) |
369 | return 1; | 373 | return 0; |
370 | 374 | ||
371 | if (start & (logical_block_size_sectors - 1)) { | 375 | if (start & (logical_block_size_sectors - 1)) { |
372 | DMWARN("%s: start=%llu not aligned to h/w " | 376 | DMWARN("%s: start=%llu not aligned to h/w " |
373 | "logical block size %hu of %s", | 377 | "logical block size %u of %s", |
374 | dm_device_name(ti->table->md), | 378 | dm_device_name(ti->table->md), |
375 | (unsigned long long)start, | 379 | (unsigned long long)start, |
376 | limits->logical_block_size, bdevname(bdev, b)); | 380 | limits->logical_block_size, bdevname(bdev, b)); |
377 | return 0; | 381 | return 1; |
378 | } | 382 | } |
379 | 383 | ||
380 | if (len & (logical_block_size_sectors - 1)) { | 384 | if (len & (logical_block_size_sectors - 1)) { |
381 | DMWARN("%s: len=%llu not aligned to h/w " | 385 | DMWARN("%s: len=%llu not aligned to h/w " |
382 | "logical block size %hu of %s", | 386 | "logical block size %u of %s", |
383 | dm_device_name(ti->table->md), | 387 | dm_device_name(ti->table->md), |
384 | (unsigned long long)len, | 388 | (unsigned long long)len, |
385 | limits->logical_block_size, bdevname(bdev, b)); | 389 | limits->logical_block_size, bdevname(bdev, b)); |
386 | return 0; | 390 | return 1; |
387 | } | 391 | } |
388 | 392 | ||
389 | return 1; | 393 | return 0; |
390 | } | 394 | } |
391 | 395 | ||
392 | /* | 396 | /* |
@@ -496,8 +500,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
496 | } | 500 | } |
497 | 501 | ||
498 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) | 502 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) |
499 | DMWARN("%s: target device %s is misaligned", | 503 | DMWARN("%s: target device %s is misaligned: " |
500 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 504 | "physical_block_size=%u, logical_block_size=%u, " |
505 | "alignment_offset=%u, start=%llu", | ||
506 | dm_device_name(ti->table->md), bdevname(bdev, b), | ||
507 | q->limits.physical_block_size, | ||
508 | q->limits.logical_block_size, | ||
509 | q->limits.alignment_offset, | ||
510 | (unsigned long long) start << 9); | ||
511 | |||
501 | 512 | ||
502 | /* | 513 | /* |
503 | * Check if merge fn is supported. | 514 | * Check if merge fn is supported. |
@@ -698,7 +709,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table, | |||
698 | 709 | ||
699 | if (remaining) { | 710 | if (remaining) { |
700 | DMWARN("%s: table line %u (start sect %llu len %llu) " | 711 | DMWARN("%s: table line %u (start sect %llu len %llu) " |
701 | "not aligned to h/w logical block size %hu", | 712 | "not aligned to h/w logical block size %u", |
702 | dm_device_name(table->md), i, | 713 | dm_device_name(table->md), i, |
703 | (unsigned long long) ti->begin, | 714 | (unsigned long long) ti->begin, |
704 | (unsigned long long) ti->len, | 715 | (unsigned long long) ti->len, |
@@ -996,12 +1007,16 @@ int dm_calculate_queue_limits(struct dm_table *table, | |||
996 | ti->type->iterate_devices(ti, dm_set_device_limits, | 1007 | ti->type->iterate_devices(ti, dm_set_device_limits, |
997 | &ti_limits); | 1008 | &ti_limits); |
998 | 1009 | ||
1010 | /* Set I/O hints portion of queue limits */ | ||
1011 | if (ti->type->io_hints) | ||
1012 | ti->type->io_hints(ti, &ti_limits); | ||
1013 | |||
999 | /* | 1014 | /* |
1000 | * Check each device area is consistent with the target's | 1015 | * Check each device area is consistent with the target's |
1001 | * overall queue limits. | 1016 | * overall queue limits. |
1002 | */ | 1017 | */ |
1003 | if (!ti->type->iterate_devices(ti, device_area_is_valid, | 1018 | if (ti->type->iterate_devices(ti, device_area_is_invalid, |
1004 | &ti_limits)) | 1019 | &ti_limits)) |
1005 | return -EINVAL; | 1020 | return -EINVAL; |
1006 | 1021 | ||
1007 | combine_limits: | 1022 | combine_limits: |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 8a311ea0d441..376f1ab48a24 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -130,7 +130,7 @@ struct mapped_device { | |||
130 | /* | 130 | /* |
131 | * A list of ios that arrived while we were suspended. | 131 | * A list of ios that arrived while we were suspended. |
132 | */ | 132 | */ |
133 | atomic_t pending; | 133 | atomic_t pending[2]; |
134 | wait_queue_head_t wait; | 134 | wait_queue_head_t wait; |
135 | struct work_struct work; | 135 | struct work_struct work; |
136 | struct bio_list deferred; | 136 | struct bio_list deferred; |
@@ -453,13 +453,14 @@ static void start_io_acct(struct dm_io *io) | |||
453 | { | 453 | { |
454 | struct mapped_device *md = io->md; | 454 | struct mapped_device *md = io->md; |
455 | int cpu; | 455 | int cpu; |
456 | int rw = bio_data_dir(io->bio); | ||
456 | 457 | ||
457 | io->start_time = jiffies; | 458 | io->start_time = jiffies; |
458 | 459 | ||
459 | cpu = part_stat_lock(); | 460 | cpu = part_stat_lock(); |
460 | part_round_stats(cpu, &dm_disk(md)->part0); | 461 | part_round_stats(cpu, &dm_disk(md)->part0); |
461 | part_stat_unlock(); | 462 | part_stat_unlock(); |
462 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); | 463 | dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); |
463 | } | 464 | } |
464 | 465 | ||
465 | static void end_io_acct(struct dm_io *io) | 466 | static void end_io_acct(struct dm_io *io) |
@@ -479,8 +480,9 @@ static void end_io_acct(struct dm_io *io) | |||
479 | * After this is decremented the bio must not be touched if it is | 480 | * After this is decremented the bio must not be touched if it is |
480 | * a barrier. | 481 | * a barrier. |
481 | */ | 482 | */ |
482 | dm_disk(md)->part0.in_flight = pending = | 483 | dm_disk(md)->part0.in_flight[rw] = pending = |
483 | atomic_dec_return(&md->pending); | 484 | atomic_dec_return(&md->pending[rw]); |
485 | pending += atomic_read(&md->pending[rw^0x1]); | ||
484 | 486 | ||
485 | /* nudge anyone waiting on suspend queue */ | 487 | /* nudge anyone waiting on suspend queue */ |
486 | if (!pending) | 488 | if (!pending) |
@@ -586,7 +588,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
586 | */ | 588 | */ |
587 | spin_lock_irqsave(&md->deferred_lock, flags); | 589 | spin_lock_irqsave(&md->deferred_lock, flags); |
588 | if (__noflush_suspending(md)) { | 590 | if (__noflush_suspending(md)) { |
589 | if (!bio_barrier(io->bio)) | 591 | if (!bio_rw_flagged(io->bio, BIO_RW_BARRIER)) |
590 | bio_list_add_head(&md->deferred, | 592 | bio_list_add_head(&md->deferred, |
591 | io->bio); | 593 | io->bio); |
592 | } else | 594 | } else |
@@ -598,7 +600,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
598 | io_error = io->error; | 600 | io_error = io->error; |
599 | bio = io->bio; | 601 | bio = io->bio; |
600 | 602 | ||
601 | if (bio_barrier(bio)) { | 603 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) { |
602 | /* | 604 | /* |
603 | * There can be just one barrier request so we use | 605 | * There can be just one barrier request so we use |
604 | * a per-device variable for error reporting. | 606 | * a per-device variable for error reporting. |
@@ -738,16 +740,22 @@ static void rq_completed(struct mapped_device *md, int run_queue) | |||
738 | dm_put(md); | 740 | dm_put(md); |
739 | } | 741 | } |
740 | 742 | ||
743 | static void free_rq_clone(struct request *clone) | ||
744 | { | ||
745 | struct dm_rq_target_io *tio = clone->end_io_data; | ||
746 | |||
747 | blk_rq_unprep_clone(clone); | ||
748 | free_rq_tio(tio); | ||
749 | } | ||
750 | |||
741 | static void dm_unprep_request(struct request *rq) | 751 | static void dm_unprep_request(struct request *rq) |
742 | { | 752 | { |
743 | struct request *clone = rq->special; | 753 | struct request *clone = rq->special; |
744 | struct dm_rq_target_io *tio = clone->end_io_data; | ||
745 | 754 | ||
746 | rq->special = NULL; | 755 | rq->special = NULL; |
747 | rq->cmd_flags &= ~REQ_DONTPREP; | 756 | rq->cmd_flags &= ~REQ_DONTPREP; |
748 | 757 | ||
749 | blk_rq_unprep_clone(clone); | 758 | free_rq_clone(clone); |
750 | free_rq_tio(tio); | ||
751 | } | 759 | } |
752 | 760 | ||
753 | /* | 761 | /* |
@@ -825,8 +833,7 @@ static void dm_end_request(struct request *clone, int error) | |||
825 | rq->sense_len = clone->sense_len; | 833 | rq->sense_len = clone->sense_len; |
826 | } | 834 | } |
827 | 835 | ||
828 | BUG_ON(clone->bio); | 836 | free_rq_clone(clone); |
829 | free_rq_tio(tio); | ||
830 | 837 | ||
831 | blk_end_request_all(rq, error); | 838 | blk_end_request_all(rq, error); |
832 | 839 | ||
@@ -1204,7 +1211,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) | |||
1204 | 1211 | ||
1205 | ci.map = dm_get_table(md); | 1212 | ci.map = dm_get_table(md); |
1206 | if (unlikely(!ci.map)) { | 1213 | if (unlikely(!ci.map)) { |
1207 | if (!bio_barrier(bio)) | 1214 | if (!bio_rw_flagged(bio, BIO_RW_BARRIER)) |
1208 | bio_io_error(bio); | 1215 | bio_io_error(bio); |
1209 | else | 1216 | else |
1210 | if (!md->barrier_error) | 1217 | if (!md->barrier_error) |
@@ -1316,7 +1323,7 @@ static int _dm_request(struct request_queue *q, struct bio *bio) | |||
1316 | * we have to queue this io for later. | 1323 | * we have to queue this io for later. |
1317 | */ | 1324 | */ |
1318 | if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) || | 1325 | if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) || |
1319 | unlikely(bio_barrier(bio))) { | 1326 | unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
1320 | up_read(&md->io_lock); | 1327 | up_read(&md->io_lock); |
1321 | 1328 | ||
1322 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) && | 1329 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) && |
@@ -1339,7 +1346,7 @@ static int dm_make_request(struct request_queue *q, struct bio *bio) | |||
1339 | { | 1346 | { |
1340 | struct mapped_device *md = q->queuedata; | 1347 | struct mapped_device *md = q->queuedata; |
1341 | 1348 | ||
1342 | if (unlikely(bio_barrier(bio))) { | 1349 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
1343 | bio_endio(bio, -EOPNOTSUPP); | 1350 | bio_endio(bio, -EOPNOTSUPP); |
1344 | return 0; | 1351 | return 0; |
1345 | } | 1352 | } |
@@ -1709,7 +1716,7 @@ out: | |||
1709 | return r; | 1716 | return r; |
1710 | } | 1717 | } |
1711 | 1718 | ||
1712 | static struct block_device_operations dm_blk_dops; | 1719 | static const struct block_device_operations dm_blk_dops; |
1713 | 1720 | ||
1714 | static void dm_wq_work(struct work_struct *work); | 1721 | static void dm_wq_work(struct work_struct *work); |
1715 | 1722 | ||
@@ -1780,7 +1787,8 @@ static struct mapped_device *alloc_dev(int minor) | |||
1780 | if (!md->disk) | 1787 | if (!md->disk) |
1781 | goto bad_disk; | 1788 | goto bad_disk; |
1782 | 1789 | ||
1783 | atomic_set(&md->pending, 0); | 1790 | atomic_set(&md->pending[0], 0); |
1791 | atomic_set(&md->pending[1], 0); | ||
1784 | init_waitqueue_head(&md->wait); | 1792 | init_waitqueue_head(&md->wait); |
1785 | INIT_WORK(&md->work, dm_wq_work); | 1793 | INIT_WORK(&md->work, dm_wq_work); |
1786 | init_waitqueue_head(&md->eventq); | 1794 | init_waitqueue_head(&md->eventq); |
@@ -2083,7 +2091,8 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) | |||
2083 | break; | 2091 | break; |
2084 | } | 2092 | } |
2085 | spin_unlock_irqrestore(q->queue_lock, flags); | 2093 | spin_unlock_irqrestore(q->queue_lock, flags); |
2086 | } else if (!atomic_read(&md->pending)) | 2094 | } else if (!atomic_read(&md->pending[0]) && |
2095 | !atomic_read(&md->pending[1])) | ||
2087 | break; | 2096 | break; |
2088 | 2097 | ||
2089 | if (interruptible == TASK_INTERRUPTIBLE && | 2098 | if (interruptible == TASK_INTERRUPTIBLE && |
@@ -2159,7 +2168,7 @@ static void dm_wq_work(struct work_struct *work) | |||
2159 | if (dm_request_based(md)) | 2168 | if (dm_request_based(md)) |
2160 | generic_make_request(c); | 2169 | generic_make_request(c); |
2161 | else { | 2170 | else { |
2162 | if (bio_barrier(c)) | 2171 | if (bio_rw_flagged(c, BIO_RW_BARRIER)) |
2163 | process_barrier(md, c); | 2172 | process_barrier(md, c); |
2164 | else | 2173 | else |
2165 | __split_and_process_bio(md, c); | 2174 | __split_and_process_bio(md, c); |
@@ -2654,7 +2663,7 @@ void dm_free_md_mempools(struct dm_md_mempools *pools) | |||
2654 | kfree(pools); | 2663 | kfree(pools); |
2655 | } | 2664 | } |
2656 | 2665 | ||
2657 | static struct block_device_operations dm_blk_dops = { | 2666 | static const struct block_device_operations dm_blk_dops = { |
2658 | .open = dm_blk_open, | 2667 | .open = dm_blk_open, |
2659 | .release = dm_blk_close, | 2668 | .release = dm_blk_close, |
2660 | .ioctl = dm_blk_ioctl, | 2669 | .ioctl = dm_blk_ioctl, |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 5fe39c2a3d2b..1ceceb334d5e 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -108,6 +108,9 @@ static int linear_congested(void *data, int bits) | |||
108 | linear_conf_t *conf; | 108 | linear_conf_t *conf; |
109 | int i, ret = 0; | 109 | int i, ret = 0; |
110 | 110 | ||
111 | if (mddev_congested(mddev, bits)) | ||
112 | return 1; | ||
113 | |||
111 | rcu_read_lock(); | 114 | rcu_read_lock(); |
112 | conf = rcu_dereference(mddev->private); | 115 | conf = rcu_dereference(mddev->private); |
113 | 116 | ||
@@ -288,7 +291,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
288 | sector_t start_sector; | 291 | sector_t start_sector; |
289 | int cpu; | 292 | int cpu; |
290 | 293 | ||
291 | if (unlikely(bio_barrier(bio))) { | 294 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
292 | bio_endio(bio, -EOPNOTSUPP); | 295 | bio_endio(bio, -EOPNOTSUPP); |
293 | return 0; | 296 | return 0; |
294 | } | 297 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9dd872000cec..26ba42a79129 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -138,7 +138,7 @@ static ctl_table raid_root_table[] = { | |||
138 | { .ctl_name = 0 } | 138 | { .ctl_name = 0 } |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static struct block_device_operations md_fops; | 141 | static const struct block_device_operations md_fops; |
142 | 142 | ||
143 | static int start_readonly; | 143 | static int start_readonly; |
144 | 144 | ||
@@ -262,6 +262,12 @@ static void mddev_resume(mddev_t *mddev) | |||
262 | mddev->pers->quiesce(mddev, 0); | 262 | mddev->pers->quiesce(mddev, 0); |
263 | } | 263 | } |
264 | 264 | ||
265 | int mddev_congested(mddev_t *mddev, int bits) | ||
266 | { | ||
267 | return mddev->suspended; | ||
268 | } | ||
269 | EXPORT_SYMBOL(mddev_congested); | ||
270 | |||
265 | 271 | ||
266 | static inline mddev_t *mddev_get(mddev_t *mddev) | 272 | static inline mddev_t *mddev_get(mddev_t *mddev) |
267 | { | 273 | { |
@@ -4218,7 +4224,7 @@ static int do_md_run(mddev_t * mddev) | |||
4218 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 4224 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
4219 | mddev->sync_thread = md_register_thread(md_do_sync, | 4225 | mddev->sync_thread = md_register_thread(md_do_sync, |
4220 | mddev, | 4226 | mddev, |
4221 | "%s_resync"); | 4227 | "resync"); |
4222 | if (!mddev->sync_thread) { | 4228 | if (!mddev->sync_thread) { |
4223 | printk(KERN_ERR "%s: could not start resync" | 4229 | printk(KERN_ERR "%s: could not start resync" |
4224 | " thread...\n", | 4230 | " thread...\n", |
@@ -4575,10 +4581,10 @@ static int get_version(void __user * arg) | |||
4575 | static int get_array_info(mddev_t * mddev, void __user * arg) | 4581 | static int get_array_info(mddev_t * mddev, void __user * arg) |
4576 | { | 4582 | { |
4577 | mdu_array_info_t info; | 4583 | mdu_array_info_t info; |
4578 | int nr,working,active,failed,spare; | 4584 | int nr,working,insync,failed,spare; |
4579 | mdk_rdev_t *rdev; | 4585 | mdk_rdev_t *rdev; |
4580 | 4586 | ||
4581 | nr=working=active=failed=spare=0; | 4587 | nr=working=insync=failed=spare=0; |
4582 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 4588 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
4583 | nr++; | 4589 | nr++; |
4584 | if (test_bit(Faulty, &rdev->flags)) | 4590 | if (test_bit(Faulty, &rdev->flags)) |
@@ -4586,7 +4592,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
4586 | else { | 4592 | else { |
4587 | working++; | 4593 | working++; |
4588 | if (test_bit(In_sync, &rdev->flags)) | 4594 | if (test_bit(In_sync, &rdev->flags)) |
4589 | active++; | 4595 | insync++; |
4590 | else | 4596 | else |
4591 | spare++; | 4597 | spare++; |
4592 | } | 4598 | } |
@@ -4611,7 +4617,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
4611 | info.state = (1<<MD_SB_CLEAN); | 4617 | info.state = (1<<MD_SB_CLEAN); |
4612 | if (mddev->bitmap && mddev->bitmap_offset) | 4618 | if (mddev->bitmap && mddev->bitmap_offset) |
4613 | info.state = (1<<MD_SB_BITMAP_PRESENT); | 4619 | info.state = (1<<MD_SB_BITMAP_PRESENT); |
4614 | info.active_disks = active; | 4620 | info.active_disks = insync; |
4615 | info.working_disks = working; | 4621 | info.working_disks = working; |
4616 | info.failed_disks = failed; | 4622 | info.failed_disks = failed; |
4617 | info.spare_disks = spare; | 4623 | info.spare_disks = spare; |
@@ -4721,7 +4727,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4721 | if (!list_empty(&mddev->disks)) { | 4727 | if (!list_empty(&mddev->disks)) { |
4722 | mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, | 4728 | mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, |
4723 | mdk_rdev_t, same_set); | 4729 | mdk_rdev_t, same_set); |
4724 | int err = super_types[mddev->major_version] | 4730 | err = super_types[mddev->major_version] |
4725 | .load_super(rdev, rdev0, mddev->minor_version); | 4731 | .load_super(rdev, rdev0, mddev->minor_version); |
4726 | if (err < 0) { | 4732 | if (err < 0) { |
4727 | printk(KERN_WARNING | 4733 | printk(KERN_WARNING |
@@ -5556,7 +5562,7 @@ static int md_revalidate(struct gendisk *disk) | |||
5556 | mddev->changed = 0; | 5562 | mddev->changed = 0; |
5557 | return 0; | 5563 | return 0; |
5558 | } | 5564 | } |
5559 | static struct block_device_operations md_fops = | 5565 | static const struct block_device_operations md_fops = |
5560 | { | 5566 | { |
5561 | .owner = THIS_MODULE, | 5567 | .owner = THIS_MODULE, |
5562 | .open = md_open, | 5568 | .open = md_open, |
@@ -5631,7 +5637,10 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, | |||
5631 | thread->run = run; | 5637 | thread->run = run; |
5632 | thread->mddev = mddev; | 5638 | thread->mddev = mddev; |
5633 | thread->timeout = MAX_SCHEDULE_TIMEOUT; | 5639 | thread->timeout = MAX_SCHEDULE_TIMEOUT; |
5634 | thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev)); | 5640 | thread->tsk = kthread_run(md_thread, thread, |
5641 | "%s_%s", | ||
5642 | mdname(thread->mddev), | ||
5643 | name ?: mddev->pers->name); | ||
5635 | if (IS_ERR(thread->tsk)) { | 5644 | if (IS_ERR(thread->tsk)) { |
5636 | kfree(thread); | 5645 | kfree(thread); |
5637 | return NULL; | 5646 | return NULL; |
@@ -6745,7 +6754,7 @@ void md_check_recovery(mddev_t *mddev) | |||
6745 | } | 6754 | } |
6746 | mddev->sync_thread = md_register_thread(md_do_sync, | 6755 | mddev->sync_thread = md_register_thread(md_do_sync, |
6747 | mddev, | 6756 | mddev, |
6748 | "%s_resync"); | 6757 | "resync"); |
6749 | if (!mddev->sync_thread) { | 6758 | if (!mddev->sync_thread) { |
6750 | printk(KERN_ERR "%s: could not start resync" | 6759 | printk(KERN_ERR "%s: could not start resync" |
6751 | " thread...\n", | 6760 | " thread...\n", |
diff --git a/drivers/md/md.h b/drivers/md/md.h index f8fc188bc762..f184b69ef337 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -201,7 +201,7 @@ struct mddev_s | |||
201 | * INTR: resync needs to be aborted for some reason | 201 | * INTR: resync needs to be aborted for some reason |
202 | * DONE: thread is done and is waiting to be reaped | 202 | * DONE: thread is done and is waiting to be reaped |
203 | * REQUEST: user-space has requested a sync (used with SYNC) | 203 | * REQUEST: user-space has requested a sync (used with SYNC) |
204 | * CHECK: user-space request for for check-only, no repair | 204 | * CHECK: user-space request for check-only, no repair |
205 | * RESHAPE: A reshape is happening | 205 | * RESHAPE: A reshape is happening |
206 | * | 206 | * |
207 | * If neither SYNC or RESHAPE are set, then it is a recovery. | 207 | * If neither SYNC or RESHAPE are set, then it is a recovery. |
@@ -430,6 +430,7 @@ extern void md_write_end(mddev_t *mddev); | |||
430 | extern void md_done_sync(mddev_t *mddev, int blocks, int ok); | 430 | extern void md_done_sync(mddev_t *mddev, int blocks, int ok); |
431 | extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev); | 431 | extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev); |
432 | 432 | ||
433 | extern int mddev_congested(mddev_t *mddev, int bits); | ||
433 | extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | 434 | extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, |
434 | sector_t sector, int size, struct page *page); | 435 | sector_t sector, int size, struct page *page); |
435 | extern void md_super_wait(mddev_t *mddev); | 436 | extern void md_super_wait(mddev_t *mddev); |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 7140909f6662..ee7646f974a0 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -90,7 +90,7 @@ static void multipath_end_request(struct bio *bio, int error) | |||
90 | 90 | ||
91 | if (uptodate) | 91 | if (uptodate) |
92 | multipath_end_bh_io(mp_bh, 0); | 92 | multipath_end_bh_io(mp_bh, 0); |
93 | else if (!bio_rw_ahead(bio)) { | 93 | else if (!bio_rw_flagged(bio, BIO_RW_AHEAD)) { |
94 | /* | 94 | /* |
95 | * oops, IO error: | 95 | * oops, IO error: |
96 | */ | 96 | */ |
@@ -144,7 +144,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) | |||
144 | const int rw = bio_data_dir(bio); | 144 | const int rw = bio_data_dir(bio); |
145 | int cpu; | 145 | int cpu; |
146 | 146 | ||
147 | if (unlikely(bio_barrier(bio))) { | 147 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
148 | bio_endio(bio, -EOPNOTSUPP); | 148 | bio_endio(bio, -EOPNOTSUPP); |
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
@@ -198,6 +198,9 @@ static int multipath_congested(void *data, int bits) | |||
198 | multipath_conf_t *conf = mddev->private; | 198 | multipath_conf_t *conf = mddev->private; |
199 | int i, ret = 0; | 199 | int i, ret = 0; |
200 | 200 | ||
201 | if (mddev_congested(mddev, bits)) | ||
202 | return 1; | ||
203 | |||
201 | rcu_read_lock(); | 204 | rcu_read_lock(); |
202 | for (i = 0; i < mddev->raid_disks ; i++) { | 205 | for (i = 0; i < mddev->raid_disks ; i++) { |
203 | mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev); | 206 | mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev); |
@@ -493,7 +496,7 @@ static int multipath_run (mddev_t *mddev) | |||
493 | } | 496 | } |
494 | mddev->degraded = conf->raid_disks - conf->working_disks; | 497 | mddev->degraded = conf->raid_disks - conf->working_disks; |
495 | 498 | ||
496 | conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, | 499 | conf->pool = mempool_create_kmalloc_pool(NR_RESERVED_BUFS, |
497 | sizeof(struct multipath_bh)); | 500 | sizeof(struct multipath_bh)); |
498 | if (conf->pool == NULL) { | 501 | if (conf->pool == NULL) { |
499 | printk(KERN_ERR | 502 | printk(KERN_ERR |
@@ -503,7 +506,7 @@ static int multipath_run (mddev_t *mddev) | |||
503 | } | 506 | } |
504 | 507 | ||
505 | { | 508 | { |
506 | mddev->thread = md_register_thread(multipathd, mddev, "%s_multipath"); | 509 | mddev->thread = md_register_thread(multipathd, mddev, NULL); |
507 | if (!mddev->thread) { | 510 | if (!mddev->thread) { |
508 | printk(KERN_ERR "multipath: couldn't allocate thread" | 511 | printk(KERN_ERR "multipath: couldn't allocate thread" |
509 | " for %s\n", mdname(mddev)); | 512 | " for %s\n", mdname(mddev)); |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 898e2bdfee47..d3a4ce06015a 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -44,6 +44,9 @@ static int raid0_congested(void *data, int bits) | |||
44 | mdk_rdev_t **devlist = conf->devlist; | 44 | mdk_rdev_t **devlist = conf->devlist; |
45 | int i, ret = 0; | 45 | int i, ret = 0; |
46 | 46 | ||
47 | if (mddev_congested(mddev, bits)) | ||
48 | return 1; | ||
49 | |||
47 | for (i = 0; i < mddev->raid_disks && !ret ; i++) { | 50 | for (i = 0; i < mddev->raid_disks && !ret ; i++) { |
48 | struct request_queue *q = bdev_get_queue(devlist[i]->bdev); | 51 | struct request_queue *q = bdev_get_queue(devlist[i]->bdev); |
49 | 52 | ||
@@ -86,7 +89,7 @@ static void dump_zones(mddev_t *mddev) | |||
86 | 89 | ||
87 | static int create_strip_zones(mddev_t *mddev) | 90 | static int create_strip_zones(mddev_t *mddev) |
88 | { | 91 | { |
89 | int i, c, j, err; | 92 | int i, c, err; |
90 | sector_t curr_zone_end, sectors; | 93 | sector_t curr_zone_end, sectors; |
91 | mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev, **dev; | 94 | mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev, **dev; |
92 | struct strip_zone *zone; | 95 | struct strip_zone *zone; |
@@ -198,6 +201,8 @@ static int create_strip_zones(mddev_t *mddev) | |||
198 | /* now do the other zones */ | 201 | /* now do the other zones */ |
199 | for (i = 1; i < conf->nr_strip_zones; i++) | 202 | for (i = 1; i < conf->nr_strip_zones; i++) |
200 | { | 203 | { |
204 | int j; | ||
205 | |||
201 | zone = conf->strip_zone + i; | 206 | zone = conf->strip_zone + i; |
202 | dev = conf->devlist + i * mddev->raid_disks; | 207 | dev = conf->devlist + i * mddev->raid_disks; |
203 | 208 | ||
@@ -207,7 +212,6 @@ static int create_strip_zones(mddev_t *mddev) | |||
207 | c = 0; | 212 | c = 0; |
208 | 213 | ||
209 | for (j=0; j<cnt; j++) { | 214 | for (j=0; j<cnt; j++) { |
210 | char b[BDEVNAME_SIZE]; | ||
211 | rdev = conf->devlist[j]; | 215 | rdev = conf->devlist[j]; |
212 | printk(KERN_INFO "raid0: checking %s ...", | 216 | printk(KERN_INFO "raid0: checking %s ...", |
213 | bdevname(rdev->bdev, b)); | 217 | bdevname(rdev->bdev, b)); |
@@ -448,7 +452,7 @@ static int raid0_make_request(struct request_queue *q, struct bio *bio) | |||
448 | const int rw = bio_data_dir(bio); | 452 | const int rw = bio_data_dir(bio); |
449 | int cpu; | 453 | int cpu; |
450 | 454 | ||
451 | if (unlikely(bio_barrier(bio))) { | 455 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
452 | bio_endio(bio, -EOPNOTSUPP); | 456 | bio_endio(bio, -EOPNOTSUPP); |
453 | return 0; | 457 | return 0; |
454 | } | 458 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 8726fd7ebce5..d1b9bd5fd4f6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -576,6 +576,9 @@ static int raid1_congested(void *data, int bits) | |||
576 | conf_t *conf = mddev->private; | 576 | conf_t *conf = mddev->private; |
577 | int i, ret = 0; | 577 | int i, ret = 0; |
578 | 578 | ||
579 | if (mddev_congested(mddev, bits)) | ||
580 | return 1; | ||
581 | |||
579 | rcu_read_lock(); | 582 | rcu_read_lock(); |
580 | for (i = 0; i < mddev->raid_disks; i++) { | 583 | for (i = 0; i < mddev->raid_disks; i++) { |
581 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | 584 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); |
@@ -782,8 +785,9 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
782 | struct bio_list bl; | 785 | struct bio_list bl; |
783 | struct page **behind_pages = NULL; | 786 | struct page **behind_pages = NULL; |
784 | const int rw = bio_data_dir(bio); | 787 | const int rw = bio_data_dir(bio); |
785 | const int do_sync = bio_sync(bio); | 788 | const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); |
786 | int cpu, do_barriers; | 789 | int cpu; |
790 | bool do_barriers; | ||
787 | mdk_rdev_t *blocked_rdev; | 791 | mdk_rdev_t *blocked_rdev; |
788 | 792 | ||
789 | /* | 793 | /* |
@@ -797,7 +801,8 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
797 | 801 | ||
798 | md_write_start(mddev, bio); /* wait on superblock update early */ | 802 | md_write_start(mddev, bio); /* wait on superblock update early */ |
799 | 803 | ||
800 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | 804 | if (unlikely(!mddev->barriers_work && |
805 | bio_rw_flagged(bio, BIO_RW_BARRIER))) { | ||
801 | if (rw == WRITE) | 806 | if (rw == WRITE) |
802 | md_write_end(mddev); | 807 | md_write_end(mddev); |
803 | bio_endio(bio, -EOPNOTSUPP); | 808 | bio_endio(bio, -EOPNOTSUPP); |
@@ -849,7 +854,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
849 | read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset; | 854 | read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset; |
850 | read_bio->bi_bdev = mirror->rdev->bdev; | 855 | read_bio->bi_bdev = mirror->rdev->bdev; |
851 | read_bio->bi_end_io = raid1_end_read_request; | 856 | read_bio->bi_end_io = raid1_end_read_request; |
852 | read_bio->bi_rw = READ | do_sync; | 857 | read_bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO); |
853 | read_bio->bi_private = r1_bio; | 858 | read_bio->bi_private = r1_bio; |
854 | 859 | ||
855 | generic_make_request(read_bio); | 860 | generic_make_request(read_bio); |
@@ -925,7 +930,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
925 | atomic_set(&r1_bio->remaining, 0); | 930 | atomic_set(&r1_bio->remaining, 0); |
926 | atomic_set(&r1_bio->behind_remaining, 0); | 931 | atomic_set(&r1_bio->behind_remaining, 0); |
927 | 932 | ||
928 | do_barriers = bio_barrier(bio); | 933 | do_barriers = bio_rw_flagged(bio, BIO_RW_BARRIER); |
929 | if (do_barriers) | 934 | if (do_barriers) |
930 | set_bit(R1BIO_Barrier, &r1_bio->state); | 935 | set_bit(R1BIO_Barrier, &r1_bio->state); |
931 | 936 | ||
@@ -941,7 +946,8 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
941 | mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; | 946 | mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; |
942 | mbio->bi_bdev = conf->mirrors[i].rdev->bdev; | 947 | mbio->bi_bdev = conf->mirrors[i].rdev->bdev; |
943 | mbio->bi_end_io = raid1_end_write_request; | 948 | mbio->bi_end_io = raid1_end_write_request; |
944 | mbio->bi_rw = WRITE | do_barriers | do_sync; | 949 | mbio->bi_rw = WRITE | (do_barriers << BIO_RW_BARRIER) | |
950 | (do_sync << BIO_RW_SYNCIO); | ||
945 | mbio->bi_private = r1_bio; | 951 | mbio->bi_private = r1_bio; |
946 | 952 | ||
947 | if (behind_pages) { | 953 | if (behind_pages) { |
@@ -1600,7 +1606,7 @@ static void raid1d(mddev_t *mddev) | |||
1600 | * We already have a nr_pending reference on these rdevs. | 1606 | * We already have a nr_pending reference on these rdevs. |
1601 | */ | 1607 | */ |
1602 | int i; | 1608 | int i; |
1603 | const int do_sync = bio_sync(r1_bio->master_bio); | 1609 | const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO); |
1604 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1610 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
1605 | clear_bit(R1BIO_Barrier, &r1_bio->state); | 1611 | clear_bit(R1BIO_Barrier, &r1_bio->state); |
1606 | for (i=0; i < conf->raid_disks; i++) | 1612 | for (i=0; i < conf->raid_disks; i++) |
@@ -1621,7 +1627,8 @@ static void raid1d(mddev_t *mddev) | |||
1621 | conf->mirrors[i].rdev->data_offset; | 1627 | conf->mirrors[i].rdev->data_offset; |
1622 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1628 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1623 | bio->bi_end_io = raid1_end_write_request; | 1629 | bio->bi_end_io = raid1_end_write_request; |
1624 | bio->bi_rw = WRITE | do_sync; | 1630 | bio->bi_rw = WRITE | |
1631 | (do_sync << BIO_RW_SYNCIO); | ||
1625 | bio->bi_private = r1_bio; | 1632 | bio->bi_private = r1_bio; |
1626 | r1_bio->bios[i] = bio; | 1633 | r1_bio->bios[i] = bio; |
1627 | generic_make_request(bio); | 1634 | generic_make_request(bio); |
@@ -1654,7 +1661,7 @@ static void raid1d(mddev_t *mddev) | |||
1654 | (unsigned long long)r1_bio->sector); | 1661 | (unsigned long long)r1_bio->sector); |
1655 | raid_end_bio_io(r1_bio); | 1662 | raid_end_bio_io(r1_bio); |
1656 | } else { | 1663 | } else { |
1657 | const int do_sync = bio_sync(r1_bio->master_bio); | 1664 | const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO); |
1658 | r1_bio->bios[r1_bio->read_disk] = | 1665 | r1_bio->bios[r1_bio->read_disk] = |
1659 | mddev->ro ? IO_BLOCKED : NULL; | 1666 | mddev->ro ? IO_BLOCKED : NULL; |
1660 | r1_bio->read_disk = disk; | 1667 | r1_bio->read_disk = disk; |
@@ -1670,7 +1677,7 @@ static void raid1d(mddev_t *mddev) | |||
1670 | bio->bi_sector = r1_bio->sector + rdev->data_offset; | 1677 | bio->bi_sector = r1_bio->sector + rdev->data_offset; |
1671 | bio->bi_bdev = rdev->bdev; | 1678 | bio->bi_bdev = rdev->bdev; |
1672 | bio->bi_end_io = raid1_end_read_request; | 1679 | bio->bi_end_io = raid1_end_read_request; |
1673 | bio->bi_rw = READ | do_sync; | 1680 | bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO); |
1674 | bio->bi_private = r1_bio; | 1681 | bio->bi_private = r1_bio; |
1675 | unplug = 1; | 1682 | unplug = 1; |
1676 | generic_make_request(bio); | 1683 | generic_make_request(bio); |
@@ -2045,7 +2052,7 @@ static int run(mddev_t *mddev) | |||
2045 | conf->last_used = j; | 2052 | conf->last_used = j; |
2046 | 2053 | ||
2047 | 2054 | ||
2048 | mddev->thread = md_register_thread(raid1d, mddev, "%s_raid1"); | 2055 | mddev->thread = md_register_thread(raid1d, mddev, NULL); |
2049 | if (!mddev->thread) { | 2056 | if (!mddev->thread) { |
2050 | printk(KERN_ERR | 2057 | printk(KERN_ERR |
2051 | "raid1: couldn't allocate thread for %s\n", | 2058 | "raid1: couldn't allocate thread for %s\n", |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3d9020cf6f6e..51c4c5c4d87a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -631,6 +631,8 @@ static int raid10_congested(void *data, int bits) | |||
631 | conf_t *conf = mddev->private; | 631 | conf_t *conf = mddev->private; |
632 | int i, ret = 0; | 632 | int i, ret = 0; |
633 | 633 | ||
634 | if (mddev_congested(mddev, bits)) | ||
635 | return 1; | ||
634 | rcu_read_lock(); | 636 | rcu_read_lock(); |
635 | for (i = 0; i < mddev->raid_disks && ret == 0; i++) { | 637 | for (i = 0; i < mddev->raid_disks && ret == 0; i++) { |
636 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | 638 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); |
@@ -796,12 +798,12 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
796 | int i; | 798 | int i; |
797 | int chunk_sects = conf->chunk_mask + 1; | 799 | int chunk_sects = conf->chunk_mask + 1; |
798 | const int rw = bio_data_dir(bio); | 800 | const int rw = bio_data_dir(bio); |
799 | const int do_sync = bio_sync(bio); | 801 | const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); |
800 | struct bio_list bl; | 802 | struct bio_list bl; |
801 | unsigned long flags; | 803 | unsigned long flags; |
802 | mdk_rdev_t *blocked_rdev; | 804 | mdk_rdev_t *blocked_rdev; |
803 | 805 | ||
804 | if (unlikely(bio_barrier(bio))) { | 806 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
805 | bio_endio(bio, -EOPNOTSUPP); | 807 | bio_endio(bio, -EOPNOTSUPP); |
806 | return 0; | 808 | return 0; |
807 | } | 809 | } |
@@ -882,7 +884,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
882 | mirror->rdev->data_offset; | 884 | mirror->rdev->data_offset; |
883 | read_bio->bi_bdev = mirror->rdev->bdev; | 885 | read_bio->bi_bdev = mirror->rdev->bdev; |
884 | read_bio->bi_end_io = raid10_end_read_request; | 886 | read_bio->bi_end_io = raid10_end_read_request; |
885 | read_bio->bi_rw = READ | do_sync; | 887 | read_bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO); |
886 | read_bio->bi_private = r10_bio; | 888 | read_bio->bi_private = r10_bio; |
887 | 889 | ||
888 | generic_make_request(read_bio); | 890 | generic_make_request(read_bio); |
@@ -950,7 +952,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
950 | conf->mirrors[d].rdev->data_offset; | 952 | conf->mirrors[d].rdev->data_offset; |
951 | mbio->bi_bdev = conf->mirrors[d].rdev->bdev; | 953 | mbio->bi_bdev = conf->mirrors[d].rdev->bdev; |
952 | mbio->bi_end_io = raid10_end_write_request; | 954 | mbio->bi_end_io = raid10_end_write_request; |
953 | mbio->bi_rw = WRITE | do_sync; | 955 | mbio->bi_rw = WRITE | (do_sync << BIO_RW_SYNCIO); |
954 | mbio->bi_private = r10_bio; | 956 | mbio->bi_private = r10_bio; |
955 | 957 | ||
956 | atomic_inc(&r10_bio->remaining); | 958 | atomic_inc(&r10_bio->remaining); |
@@ -1610,7 +1612,7 @@ static void raid10d(mddev_t *mddev) | |||
1610 | raid_end_bio_io(r10_bio); | 1612 | raid_end_bio_io(r10_bio); |
1611 | bio_put(bio); | 1613 | bio_put(bio); |
1612 | } else { | 1614 | } else { |
1613 | const int do_sync = bio_sync(r10_bio->master_bio); | 1615 | const bool do_sync = bio_rw_flagged(r10_bio->master_bio, BIO_RW_SYNCIO); |
1614 | bio_put(bio); | 1616 | bio_put(bio); |
1615 | rdev = conf->mirrors[mirror].rdev; | 1617 | rdev = conf->mirrors[mirror].rdev; |
1616 | if (printk_ratelimit()) | 1618 | if (printk_ratelimit()) |
@@ -1623,7 +1625,7 @@ static void raid10d(mddev_t *mddev) | |||
1623 | bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr | 1625 | bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr |
1624 | + rdev->data_offset; | 1626 | + rdev->data_offset; |
1625 | bio->bi_bdev = rdev->bdev; | 1627 | bio->bi_bdev = rdev->bdev; |
1626 | bio->bi_rw = READ | do_sync; | 1628 | bio->bi_rw = READ | (do_sync << BIO_RW_SYNCIO); |
1627 | bio->bi_private = r10_bio; | 1629 | bio->bi_private = r10_bio; |
1628 | bio->bi_end_io = raid10_end_read_request; | 1630 | bio->bi_end_io = raid10_end_read_request; |
1629 | unplug = 1; | 1631 | unplug = 1; |
@@ -1773,7 +1775,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1773 | max_sync = RESYNC_PAGES << (PAGE_SHIFT-9); | 1775 | max_sync = RESYNC_PAGES << (PAGE_SHIFT-9); |
1774 | if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | 1776 | if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
1775 | /* recovery... the complicated one */ | 1777 | /* recovery... the complicated one */ |
1776 | int i, j, k; | 1778 | int j, k; |
1777 | r10_bio = NULL; | 1779 | r10_bio = NULL; |
1778 | 1780 | ||
1779 | for (i=0 ; i<conf->raid_disks; i++) | 1781 | for (i=0 ; i<conf->raid_disks; i++) |
@@ -2188,7 +2190,7 @@ static int run(mddev_t *mddev) | |||
2188 | } | 2190 | } |
2189 | 2191 | ||
2190 | 2192 | ||
2191 | mddev->thread = md_register_thread(raid10d, mddev, "%s_raid10"); | 2193 | mddev->thread = md_register_thread(raid10d, mddev, NULL); |
2192 | if (!mddev->thread) { | 2194 | if (!mddev->thread) { |
2193 | printk(KERN_ERR | 2195 | printk(KERN_ERR |
2194 | "raid10: couldn't allocate thread for %s\n", | 2196 | "raid10: couldn't allocate thread for %s\n", |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1898eda60722..94829804ab7f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2924,7 +2924,8 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
2924 | rcu_read_lock(); | 2924 | rcu_read_lock(); |
2925 | for (i=disks; i--; ) { | 2925 | for (i=disks; i--; ) { |
2926 | mdk_rdev_t *rdev; | 2926 | mdk_rdev_t *rdev; |
2927 | struct r5dev *dev = &sh->dev[i]; | 2927 | |
2928 | dev = &sh->dev[i]; | ||
2928 | clear_bit(R5_Insync, &dev->flags); | 2929 | clear_bit(R5_Insync, &dev->flags); |
2929 | 2930 | ||
2930 | pr_debug("check %d: state 0x%lx toread %p read %p write %p " | 2931 | pr_debug("check %d: state 0x%lx toread %p read %p write %p " |
@@ -3548,6 +3549,9 @@ static int raid5_congested(void *data, int bits) | |||
3548 | /* No difference between reads and writes. Just check | 3549 | /* No difference between reads and writes. Just check |
3549 | * how busy the stripe_cache is | 3550 | * how busy the stripe_cache is |
3550 | */ | 3551 | */ |
3552 | |||
3553 | if (mddev_congested(mddev, bits)) | ||
3554 | return 1; | ||
3551 | if (conf->inactive_blocked) | 3555 | if (conf->inactive_blocked) |
3552 | return 1; | 3556 | return 1; |
3553 | if (conf->quiesce) | 3557 | if (conf->quiesce) |
@@ -3823,7 +3827,7 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3823 | const int rw = bio_data_dir(bi); | 3827 | const int rw = bio_data_dir(bi); |
3824 | int cpu, remaining; | 3828 | int cpu, remaining; |
3825 | 3829 | ||
3826 | if (unlikely(bio_barrier(bi))) { | 3830 | if (unlikely(bio_rw_flagged(bi, BIO_RW_BARRIER))) { |
3827 | bio_endio(bi, -EOPNOTSUPP); | 3831 | bio_endio(bi, -EOPNOTSUPP); |
3828 | return 0; | 3832 | return 0; |
3829 | } | 3833 | } |
@@ -4097,7 +4101,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4097 | INIT_LIST_HEAD(&stripes); | 4101 | INIT_LIST_HEAD(&stripes); |
4098 | for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { | 4102 | for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { |
4099 | int j; | 4103 | int j; |
4100 | int skipped = 0; | 4104 | int skipped_disk = 0; |
4101 | sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1); | 4105 | sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1); |
4102 | set_bit(STRIPE_EXPANDING, &sh->state); | 4106 | set_bit(STRIPE_EXPANDING, &sh->state); |
4103 | atomic_inc(&conf->reshape_stripes); | 4107 | atomic_inc(&conf->reshape_stripes); |
@@ -4113,14 +4117,14 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4113 | continue; | 4117 | continue; |
4114 | s = compute_blocknr(sh, j, 0); | 4118 | s = compute_blocknr(sh, j, 0); |
4115 | if (s < raid5_size(mddev, 0, 0)) { | 4119 | if (s < raid5_size(mddev, 0, 0)) { |
4116 | skipped = 1; | 4120 | skipped_disk = 1; |
4117 | continue; | 4121 | continue; |
4118 | } | 4122 | } |
4119 | memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE); | 4123 | memset(page_address(sh->dev[j].page), 0, STRIPE_SIZE); |
4120 | set_bit(R5_Expanded, &sh->dev[j].flags); | 4124 | set_bit(R5_Expanded, &sh->dev[j].flags); |
4121 | set_bit(R5_UPTODATE, &sh->dev[j].flags); | 4125 | set_bit(R5_UPTODATE, &sh->dev[j].flags); |
4122 | } | 4126 | } |
4123 | if (!skipped) { | 4127 | if (!skipped_disk) { |
4124 | set_bit(STRIPE_EXPAND_READY, &sh->state); | 4128 | set_bit(STRIPE_EXPAND_READY, &sh->state); |
4125 | set_bit(STRIPE_HANDLE, &sh->state); | 4129 | set_bit(STRIPE_HANDLE, &sh->state); |
4126 | } | 4130 | } |
@@ -4798,7 +4802,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) | |||
4798 | printk(KERN_INFO "raid5: allocated %dkB for %s\n", | 4802 | printk(KERN_INFO "raid5: allocated %dkB for %s\n", |
4799 | memory, mdname(mddev)); | 4803 | memory, mdname(mddev)); |
4800 | 4804 | ||
4801 | conf->thread = md_register_thread(raid5d, mddev, "%s_raid5"); | 4805 | conf->thread = md_register_thread(raid5d, mddev, NULL); |
4802 | if (!conf->thread) { | 4806 | if (!conf->thread) { |
4803 | printk(KERN_ERR | 4807 | printk(KERN_ERR |
4804 | "raid5: couldn't allocate thread for %s\n", | 4808 | "raid5: couldn't allocate thread for %s\n", |
@@ -4964,7 +4968,7 @@ static int run(mddev_t *mddev) | |||
4964 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 4968 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
4965 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 4969 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
4966 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, | 4970 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, |
4967 | "%s_reshape"); | 4971 | "reshape"); |
4968 | } | 4972 | } |
4969 | 4973 | ||
4970 | /* read-ahead size must cover two whole stripes, which is | 4974 | /* read-ahead size must cover two whole stripes, which is |
@@ -5382,7 +5386,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
5382 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 5386 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
5383 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 5387 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
5384 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, | 5388 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, |
5385 | "%s_reshape"); | 5389 | "reshape"); |
5386 | if (!mddev->sync_thread) { | 5390 | if (!mddev->sync_thread) { |
5387 | mddev->recovery = 0; | 5391 | mddev->recovery = 0; |
5388 | spin_lock_irq(&conf->device_lock); | 5392 | spin_lock_irq(&conf->device_lock); |