aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_int.h1
-rw-r--r--drivers/block/drbd/drbd_main.c49
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)
322static int drbd_thread_setup(void *arg) 322static 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
333restart: 333restart:
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
370static void drbd_thread_init(struct drbd_connection *connection, struct drbd_thread *thi, 372static 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
381int drbd_thread_start(struct drbd_thread *thi) 384int 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 */
537void drbd_thread_current_set_cpu(struct drbd_thread *thi) 544void 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