diff options
Diffstat (limited to 'fs/ocfs2/cluster/heartbeat.c')
| -rw-r--r-- | fs/ocfs2/cluster/heartbeat.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 5a9779bb9236..eba282da500e 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
| @@ -1234,6 +1234,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
| 1234 | const char *page, | 1234 | const char *page, |
| 1235 | size_t count) | 1235 | size_t count) |
| 1236 | { | 1236 | { |
| 1237 | struct task_struct *hb_task; | ||
| 1237 | long fd; | 1238 | long fd; |
| 1238 | int sectsize; | 1239 | int sectsize; |
| 1239 | char *p = (char *)page; | 1240 | char *p = (char *)page; |
| @@ -1319,20 +1320,28 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
| 1319 | */ | 1320 | */ |
| 1320 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); | 1321 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); |
| 1321 | 1322 | ||
| 1322 | reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s", | 1323 | hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", |
| 1323 | reg->hr_item.ci_name); | 1324 | reg->hr_item.ci_name); |
| 1324 | if (IS_ERR(reg->hr_task)) { | 1325 | if (IS_ERR(hb_task)) { |
| 1325 | ret = PTR_ERR(reg->hr_task); | 1326 | ret = PTR_ERR(hb_task); |
| 1326 | mlog_errno(ret); | 1327 | mlog_errno(ret); |
| 1327 | reg->hr_task = NULL; | ||
| 1328 | goto out; | 1328 | goto out; |
| 1329 | } | 1329 | } |
| 1330 | 1330 | ||
| 1331 | spin_lock(&o2hb_live_lock); | ||
| 1332 | reg->hr_task = hb_task; | ||
| 1333 | spin_unlock(&o2hb_live_lock); | ||
| 1334 | |||
| 1331 | ret = wait_event_interruptible(o2hb_steady_queue, | 1335 | ret = wait_event_interruptible(o2hb_steady_queue, |
| 1332 | atomic_read(®->hr_steady_iterations) == 0); | 1336 | atomic_read(®->hr_steady_iterations) == 0); |
| 1333 | if (ret) { | 1337 | if (ret) { |
| 1334 | kthread_stop(reg->hr_task); | 1338 | spin_lock(&o2hb_live_lock); |
| 1339 | hb_task = reg->hr_task; | ||
| 1335 | reg->hr_task = NULL; | 1340 | reg->hr_task = NULL; |
| 1341 | spin_unlock(&o2hb_live_lock); | ||
| 1342 | |||
| 1343 | if (hb_task) | ||
| 1344 | kthread_stop(hb_task); | ||
| 1336 | goto out; | 1345 | goto out; |
| 1337 | } | 1346 | } |
| 1338 | 1347 | ||
| @@ -1354,10 +1363,17 @@ out: | |||
| 1354 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | 1363 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, |
| 1355 | char *page) | 1364 | char *page) |
| 1356 | { | 1365 | { |
| 1357 | if (!reg->hr_task) | 1366 | pid_t pid = 0; |
| 1367 | |||
| 1368 | spin_lock(&o2hb_live_lock); | ||
| 1369 | if (reg->hr_task) | ||
| 1370 | pid = reg->hr_task->pid; | ||
| 1371 | spin_unlock(&o2hb_live_lock); | ||
| 1372 | |||
| 1373 | if (!pid) | ||
| 1358 | return 0; | 1374 | return 0; |
| 1359 | 1375 | ||
| 1360 | return sprintf(page, "%u\n", reg->hr_task->pid); | 1376 | return sprintf(page, "%u\n", pid); |
| 1361 | } | 1377 | } |
| 1362 | 1378 | ||
| 1363 | struct o2hb_region_attribute { | 1379 | struct o2hb_region_attribute { |
| @@ -1495,13 +1511,17 @@ out: | |||
| 1495 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, | 1511 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, |
| 1496 | struct config_item *item) | 1512 | struct config_item *item) |
| 1497 | { | 1513 | { |
| 1514 | struct task_struct *hb_task; | ||
| 1498 | struct o2hb_region *reg = to_o2hb_region(item); | 1515 | struct o2hb_region *reg = to_o2hb_region(item); |
| 1499 | 1516 | ||
| 1500 | /* stop the thread when the user removes the region dir */ | 1517 | /* stop the thread when the user removes the region dir */ |
| 1501 | if (reg->hr_task) { | 1518 | spin_lock(&o2hb_live_lock); |
| 1502 | kthread_stop(reg->hr_task); | 1519 | hb_task = reg->hr_task; |
| 1503 | reg->hr_task = NULL; | 1520 | reg->hr_task = NULL; |
| 1504 | } | 1521 | spin_unlock(&o2hb_live_lock); |
| 1522 | |||
| 1523 | if (hb_task) | ||
| 1524 | kthread_stop(hb_task); | ||
| 1505 | 1525 | ||
| 1506 | config_item_put(item); | 1526 | config_item_put(item); |
| 1507 | } | 1527 | } |
| @@ -1682,7 +1702,7 @@ out: | |||
| 1682 | } | 1702 | } |
| 1683 | EXPORT_SYMBOL_GPL(o2hb_register_callback); | 1703 | EXPORT_SYMBOL_GPL(o2hb_register_callback); |
| 1684 | 1704 | ||
| 1685 | int o2hb_unregister_callback(struct o2hb_callback_func *hc) | 1705 | void o2hb_unregister_callback(struct o2hb_callback_func *hc) |
| 1686 | { | 1706 | { |
| 1687 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); | 1707 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); |
| 1688 | 1708 | ||
| @@ -1690,15 +1710,13 @@ int o2hb_unregister_callback(struct o2hb_callback_func *hc) | |||
| 1690 | __builtin_return_address(0), hc); | 1710 | __builtin_return_address(0), hc); |
| 1691 | 1711 | ||
| 1692 | if (list_empty(&hc->hc_item)) | 1712 | if (list_empty(&hc->hc_item)) |
| 1693 | return 0; | 1713 | return; |
| 1694 | 1714 | ||
| 1695 | down_write(&o2hb_callback_sem); | 1715 | down_write(&o2hb_callback_sem); |
| 1696 | 1716 | ||
| 1697 | list_del_init(&hc->hc_item); | 1717 | list_del_init(&hc->hc_item); |
| 1698 | 1718 | ||
| 1699 | up_write(&o2hb_callback_sem); | 1719 | up_write(&o2hb_callback_sem); |
| 1700 | |||
| 1701 | return 0; | ||
| 1702 | } | 1720 | } |
| 1703 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); | 1721 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); |
| 1704 | 1722 | ||
