diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 49 |
2 files changed, 31 insertions, 19 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b3f46fb4dda3..e7093d4291f1 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -263,6 +263,7 @@ struct drbd_thread { | |||
263 | struct completion stop; | 263 | struct completion stop; |
264 | enum drbd_thread_state t_state; | 264 | enum drbd_thread_state t_state; |
265 | int (*function) (struct drbd_thread *); | 265 | int (*function) (struct drbd_thread *); |
266 | struct drbd_resource *resource; | ||
266 | struct drbd_connection *connection; | 267 | struct drbd_connection *connection; |
267 | int reset_cpu_mask; | 268 | int reset_cpu_mask; |
268 | const char *name; | 269 | const char *name; |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 232cd570d3ae..331e5cc1227d 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -322,13 +322,13 @@ void tl_abort_disk_io(struct drbd_device *device) | |||
322 | static int drbd_thread_setup(void *arg) | 322 | static int drbd_thread_setup(void *arg) |
323 | { | 323 | { |
324 | struct drbd_thread *thi = (struct drbd_thread *) arg; | 324 | struct drbd_thread *thi = (struct drbd_thread *) arg; |
325 | struct drbd_connection *connection = thi->connection; | 325 | struct drbd_resource *resource = thi->resource; |
326 | unsigned long flags; | 326 | unsigned long flags; |
327 | int retval; | 327 | int retval; |
328 | 328 | ||
329 | snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s", | 329 | snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s", |
330 | thi->name[0], | 330 | thi->name[0], |
331 | thi->connection->resource->name); | 331 | resource->name); |
332 | 332 | ||
333 | restart: | 333 | restart: |
334 | retval = thi->function(thi); | 334 | retval = thi->function(thi); |
@@ -346,7 +346,7 @@ restart: | |||
346 | */ | 346 | */ |
347 | 347 | ||
348 | if (thi->t_state == RESTARTING) { | 348 | if (thi->t_state == RESTARTING) { |
349 | drbd_info(connection, "Restarting %s thread\n", thi->name); | 349 | drbd_info(resource, "Restarting %s thread\n", thi->name); |
350 | thi->t_state = RUNNING; | 350 | thi->t_state = RUNNING; |
351 | spin_unlock_irqrestore(&thi->t_lock, flags); | 351 | spin_unlock_irqrestore(&thi->t_lock, flags); |
352 | goto restart; | 352 | goto restart; |
@@ -358,29 +358,32 @@ restart: | |||
358 | complete_all(&thi->stop); | 358 | complete_all(&thi->stop); |
359 | spin_unlock_irqrestore(&thi->t_lock, flags); | 359 | spin_unlock_irqrestore(&thi->t_lock, flags); |
360 | 360 | ||
361 | drbd_info(connection, "Terminating %s\n", current->comm); | 361 | drbd_info(resource, "Terminating %s\n", current->comm); |
362 | 362 | ||
363 | /* Release mod reference taken when thread was started */ | 363 | /* Release mod reference taken when thread was started */ |
364 | 364 | ||
365 | kref_put(&connection->kref, drbd_destroy_connection); | 365 | if (thi->connection) |
366 | kref_put(&thi->connection->kref, drbd_destroy_connection); | ||
367 | kref_put(&resource->kref, drbd_destroy_resource); | ||
366 | module_put(THIS_MODULE); | 368 | module_put(THIS_MODULE); |
367 | return retval; | 369 | return retval; |
368 | } | 370 | } |
369 | 371 | ||
370 | static void drbd_thread_init(struct drbd_connection *connection, struct drbd_thread *thi, | 372 | static void drbd_thread_init(struct drbd_resource *resource, struct drbd_thread *thi, |
371 | int (*func) (struct drbd_thread *), const char *name) | 373 | int (*func) (struct drbd_thread *), const char *name) |
372 | { | 374 | { |
373 | spin_lock_init(&thi->t_lock); | 375 | spin_lock_init(&thi->t_lock); |
374 | thi->task = NULL; | 376 | thi->task = NULL; |
375 | thi->t_state = NONE; | 377 | thi->t_state = NONE; |
376 | thi->function = func; | 378 | thi->function = func; |
377 | thi->connection = connection; | 379 | thi->resource = resource; |
380 | thi->connection = NULL; | ||
378 | thi->name = name; | 381 | thi->name = name; |
379 | } | 382 | } |
380 | 383 | ||
381 | int drbd_thread_start(struct drbd_thread *thi) | 384 | int drbd_thread_start(struct drbd_thread *thi) |
382 | { | 385 | { |
383 | struct drbd_connection *connection = thi->connection; | 386 | struct drbd_resource *resource = thi->resource; |
384 | struct task_struct *nt; | 387 | struct task_struct *nt; |
385 | unsigned long flags; | 388 | unsigned long flags; |
386 | 389 | ||
@@ -390,17 +393,19 @@ int drbd_thread_start(struct drbd_thread *thi) | |||
390 | 393 | ||
391 | switch (thi->t_state) { | 394 | switch (thi->t_state) { |
392 | case NONE: | 395 | case NONE: |
393 | drbd_info(connection, "Starting %s thread (from %s [%d])\n", | 396 | drbd_info(resource, "Starting %s thread (from %s [%d])\n", |
394 | thi->name, current->comm, current->pid); | 397 | thi->name, current->comm, current->pid); |
395 | 398 | ||
396 | /* Get ref on module for thread - this is released when thread exits */ | 399 | /* Get ref on module for thread - this is released when thread exits */ |
397 | if (!try_module_get(THIS_MODULE)) { | 400 | if (!try_module_get(THIS_MODULE)) { |
398 | drbd_err(connection, "Failed to get module reference in drbd_thread_start\n"); | 401 | drbd_err(resource, "Failed to get module reference in drbd_thread_start\n"); |
399 | spin_unlock_irqrestore(&thi->t_lock, flags); | 402 | spin_unlock_irqrestore(&thi->t_lock, flags); |
400 | return false; | 403 | return false; |
401 | } | 404 | } |
402 | 405 | ||
403 | kref_get(&thi->connection->kref); | 406 | kref_get(&resource->kref); |
407 | if (thi->connection) | ||
408 | kref_get(&thi->connection->kref); | ||
404 | 409 | ||
405 | init_completion(&thi->stop); | 410 | init_completion(&thi->stop); |
406 | thi->reset_cpu_mask = 1; | 411 | thi->reset_cpu_mask = 1; |
@@ -409,12 +414,14 @@ int drbd_thread_start(struct drbd_thread *thi) | |||
409 | flush_signals(current); /* otherw. may get -ERESTARTNOINTR */ | 414 | flush_signals(current); /* otherw. may get -ERESTARTNOINTR */ |
410 | 415 | ||
411 | nt = kthread_create(drbd_thread_setup, (void *) thi, | 416 | nt = kthread_create(drbd_thread_setup, (void *) thi, |
412 | "drbd_%c_%s", thi->name[0], thi->connection->resource->name); | 417 | "drbd_%c_%s", thi->name[0], thi->resource->name); |
413 | 418 | ||
414 | if (IS_ERR(nt)) { | 419 | if (IS_ERR(nt)) { |
415 | drbd_err(connection, "Couldn't start thread\n"); | 420 | drbd_err(resource, "Couldn't start thread\n"); |
416 | 421 | ||
417 | kref_put(&connection->kref, drbd_destroy_connection); | 422 | if (thi->connection) |
423 | kref_put(&thi->connection->kref, drbd_destroy_connection); | ||
424 | kref_put(&resource->kref, drbd_destroy_resource); | ||
418 | module_put(THIS_MODULE); | 425 | module_put(THIS_MODULE); |
419 | return false; | 426 | return false; |
420 | } | 427 | } |
@@ -426,7 +433,7 @@ int drbd_thread_start(struct drbd_thread *thi) | |||
426 | break; | 433 | break; |
427 | case EXITING: | 434 | case EXITING: |
428 | thi->t_state = RESTARTING; | 435 | thi->t_state = RESTARTING; |
429 | drbd_info(connection, "Restarting %s thread (from %s [%d])\n", | 436 | drbd_info(resource, "Restarting %s thread (from %s [%d])\n", |
430 | thi->name, current->comm, current->pid); | 437 | thi->name, current->comm, current->pid); |
431 | /* fall through */ | 438 | /* fall through */ |
432 | case RUNNING: | 439 | case RUNNING: |
@@ -536,12 +543,13 @@ static void drbd_calc_cpu_mask(cpumask_var_t *cpu_mask) | |||
536 | */ | 543 | */ |
537 | void drbd_thread_current_set_cpu(struct drbd_thread *thi) | 544 | void drbd_thread_current_set_cpu(struct drbd_thread *thi) |
538 | { | 545 | { |
546 | struct drbd_resource *resource = thi->resource; | ||
539 | struct task_struct *p = current; | 547 | struct task_struct *p = current; |
540 | 548 | ||
541 | if (!thi->reset_cpu_mask) | 549 | if (!thi->reset_cpu_mask) |
542 | return; | 550 | return; |
543 | thi->reset_cpu_mask = 0; | 551 | thi->reset_cpu_mask = 0; |
544 | set_cpus_allowed_ptr(p, thi->connection->resource->cpu_mask); | 552 | set_cpus_allowed_ptr(p, resource->cpu_mask); |
545 | } | 553 | } |
546 | #else | 554 | #else |
547 | #define drbd_calc_cpu_mask(A) ({}) | 555 | #define drbd_calc_cpu_mask(A) ({}) |
@@ -2616,9 +2624,12 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) | |||
2616 | mutex_init(&connection->data.mutex); | 2624 | mutex_init(&connection->data.mutex); |
2617 | mutex_init(&connection->meta.mutex); | 2625 | mutex_init(&connection->meta.mutex); |
2618 | 2626 | ||
2619 | drbd_thread_init(connection, &connection->receiver, drbd_receiver, "receiver"); | 2627 | drbd_thread_init(resource, &connection->receiver, drbd_receiver, "receiver"); |
2620 | drbd_thread_init(connection, &connection->worker, drbd_worker, "worker"); | 2628 | connection->receiver.connection = connection; |
2621 | drbd_thread_init(connection, &connection->asender, drbd_asender, "asender"); | 2629 | drbd_thread_init(resource, &connection->worker, drbd_worker, "worker"); |
2630 | connection->worker.connection = connection; | ||
2631 | drbd_thread_init(resource, &connection->asender, drbd_asender, "asender"); | ||
2632 | connection->asender.connection = connection; | ||
2622 | 2633 | ||
2623 | kref_init(&connection->kref); | 2634 | kref_init(&connection->kref); |
2624 | 2635 | ||