diff options
Diffstat (limited to 'fs/ocfs2/cluster')
-rw-r--r-- | fs/ocfs2/cluster/heartbeat.c | 96 | ||||
-rw-r--r-- | fs/ocfs2/cluster/heartbeat.h | 6 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.c | 42 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.h | 5 | ||||
-rw-r--r-- | fs/ocfs2/cluster/tcp.c | 21 |
5 files changed, 151 insertions, 19 deletions
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 979113479c66..2bd7f788cf34 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1335,6 +1335,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1335 | ret = wait_event_interruptible(o2hb_steady_queue, | 1335 | ret = wait_event_interruptible(o2hb_steady_queue, |
1336 | atomic_read(®->hr_steady_iterations) == 0); | 1336 | atomic_read(®->hr_steady_iterations) == 0); |
1337 | if (ret) { | 1337 | if (ret) { |
1338 | /* We got interrupted (hello ptrace!). Clean up */ | ||
1338 | spin_lock(&o2hb_live_lock); | 1339 | spin_lock(&o2hb_live_lock); |
1339 | hb_task = reg->hr_task; | 1340 | hb_task = reg->hr_task; |
1340 | reg->hr_task = NULL; | 1341 | reg->hr_task = NULL; |
@@ -1345,7 +1346,16 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1345 | goto out; | 1346 | goto out; |
1346 | } | 1347 | } |
1347 | 1348 | ||
1348 | ret = count; | 1349 | /* Ok, we were woken. Make sure it wasn't by drop_item() */ |
1350 | spin_lock(&o2hb_live_lock); | ||
1351 | hb_task = reg->hr_task; | ||
1352 | spin_unlock(&o2hb_live_lock); | ||
1353 | |||
1354 | if (hb_task) | ||
1355 | ret = count; | ||
1356 | else | ||
1357 | ret = -EIO; | ||
1358 | |||
1349 | out: | 1359 | out: |
1350 | if (filp) | 1360 | if (filp) |
1351 | fput(filp); | 1361 | fput(filp); |
@@ -1523,6 +1533,15 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, | |||
1523 | if (hb_task) | 1533 | if (hb_task) |
1524 | kthread_stop(hb_task); | 1534 | kthread_stop(hb_task); |
1525 | 1535 | ||
1536 | /* | ||
1537 | * If we're racing a dev_write(), we need to wake them. They will | ||
1538 | * check reg->hr_task | ||
1539 | */ | ||
1540 | if (atomic_read(®->hr_steady_iterations) != 0) { | ||
1541 | atomic_set(®->hr_steady_iterations, 0); | ||
1542 | wake_up(&o2hb_steady_queue); | ||
1543 | } | ||
1544 | |||
1526 | config_item_put(item); | 1545 | config_item_put(item); |
1527 | } | 1546 | } |
1528 | 1547 | ||
@@ -1665,7 +1684,67 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, | |||
1665 | } | 1684 | } |
1666 | EXPORT_SYMBOL_GPL(o2hb_setup_callback); | 1685 | EXPORT_SYMBOL_GPL(o2hb_setup_callback); |
1667 | 1686 | ||
1668 | int o2hb_register_callback(struct o2hb_callback_func *hc) | 1687 | static struct o2hb_region *o2hb_find_region(const char *region_uuid) |
1688 | { | ||
1689 | struct o2hb_region *p, *reg = NULL; | ||
1690 | |||
1691 | assert_spin_locked(&o2hb_live_lock); | ||
1692 | |||
1693 | list_for_each_entry(p, &o2hb_all_regions, hr_all_item) { | ||
1694 | if (!strcmp(region_uuid, config_item_name(&p->hr_item))) { | ||
1695 | reg = p; | ||
1696 | break; | ||
1697 | } | ||
1698 | } | ||
1699 | |||
1700 | return reg; | ||
1701 | } | ||
1702 | |||
1703 | static int o2hb_region_get(const char *region_uuid) | ||
1704 | { | ||
1705 | int ret = 0; | ||
1706 | struct o2hb_region *reg; | ||
1707 | |||
1708 | spin_lock(&o2hb_live_lock); | ||
1709 | |||
1710 | reg = o2hb_find_region(region_uuid); | ||
1711 | if (!reg) | ||
1712 | ret = -ENOENT; | ||
1713 | spin_unlock(&o2hb_live_lock); | ||
1714 | |||
1715 | if (ret) | ||
1716 | goto out; | ||
1717 | |||
1718 | ret = o2nm_depend_this_node(); | ||
1719 | if (ret) | ||
1720 | goto out; | ||
1721 | |||
1722 | ret = o2nm_depend_item(®->hr_item); | ||
1723 | if (ret) | ||
1724 | o2nm_undepend_this_node(); | ||
1725 | |||
1726 | out: | ||
1727 | return ret; | ||
1728 | } | ||
1729 | |||
1730 | static void o2hb_region_put(const char *region_uuid) | ||
1731 | { | ||
1732 | struct o2hb_region *reg; | ||
1733 | |||
1734 | spin_lock(&o2hb_live_lock); | ||
1735 | |||
1736 | reg = o2hb_find_region(region_uuid); | ||
1737 | |||
1738 | spin_unlock(&o2hb_live_lock); | ||
1739 | |||
1740 | if (reg) { | ||
1741 | o2nm_undepend_item(®->hr_item); | ||
1742 | o2nm_undepend_this_node(); | ||
1743 | } | ||
1744 | } | ||
1745 | |||
1746 | int o2hb_register_callback(const char *region_uuid, | ||
1747 | struct o2hb_callback_func *hc) | ||
1669 | { | 1748 | { |
1670 | struct o2hb_callback_func *tmp; | 1749 | struct o2hb_callback_func *tmp; |
1671 | struct list_head *iter; | 1750 | struct list_head *iter; |
@@ -1681,6 +1760,12 @@ int o2hb_register_callback(struct o2hb_callback_func *hc) | |||
1681 | goto out; | 1760 | goto out; |
1682 | } | 1761 | } |
1683 | 1762 | ||
1763 | if (region_uuid) { | ||
1764 | ret = o2hb_region_get(region_uuid); | ||
1765 | if (ret) | ||
1766 | goto out; | ||
1767 | } | ||
1768 | |||
1684 | down_write(&o2hb_callback_sem); | 1769 | down_write(&o2hb_callback_sem); |
1685 | 1770 | ||
1686 | list_for_each(iter, &hbcall->list) { | 1771 | list_for_each(iter, &hbcall->list) { |
@@ -1702,16 +1787,21 @@ out: | |||
1702 | } | 1787 | } |
1703 | EXPORT_SYMBOL_GPL(o2hb_register_callback); | 1788 | EXPORT_SYMBOL_GPL(o2hb_register_callback); |
1704 | 1789 | ||
1705 | void o2hb_unregister_callback(struct o2hb_callback_func *hc) | 1790 | void o2hb_unregister_callback(const char *region_uuid, |
1791 | struct o2hb_callback_func *hc) | ||
1706 | { | 1792 | { |
1707 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); | 1793 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); |
1708 | 1794 | ||
1709 | mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n", | 1795 | mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n", |
1710 | __builtin_return_address(0), hc); | 1796 | __builtin_return_address(0), hc); |
1711 | 1797 | ||
1798 | /* XXX Can this happen _with_ a region reference? */ | ||
1712 | if (list_empty(&hc->hc_item)) | 1799 | if (list_empty(&hc->hc_item)) |
1713 | return; | 1800 | return; |
1714 | 1801 | ||
1802 | if (region_uuid) | ||
1803 | o2hb_region_put(region_uuid); | ||
1804 | |||
1715 | down_write(&o2hb_callback_sem); | 1805 | down_write(&o2hb_callback_sem); |
1716 | 1806 | ||
1717 | list_del_init(&hc->hc_item); | 1807 | list_del_init(&hc->hc_item); |
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h index cc6d40b39771..35397dd5ecdb 100644 --- a/fs/ocfs2/cluster/heartbeat.h +++ b/fs/ocfs2/cluster/heartbeat.h | |||
@@ -69,8 +69,10 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, | |||
69 | o2hb_cb_func *func, | 69 | o2hb_cb_func *func, |
70 | void *data, | 70 | void *data, |
71 | int priority); | 71 | int priority); |
72 | int o2hb_register_callback(struct o2hb_callback_func *hc); | 72 | int o2hb_register_callback(const char *region_uuid, |
73 | void o2hb_unregister_callback(struct o2hb_callback_func *hc); | 73 | struct o2hb_callback_func *hc); |
74 | void o2hb_unregister_callback(const char *region_uuid, | ||
75 | struct o2hb_callback_func *hc); | ||
74 | void o2hb_fill_node_map(unsigned long *map, | 76 | void o2hb_fill_node_map(unsigned long *map, |
75 | unsigned bytes); | 77 | unsigned bytes); |
76 | void o2hb_init(void); | 78 | void o2hb_init(void); |
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 9f5ad0f01ce0..af2070da308b 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
@@ -900,6 +900,46 @@ static struct o2nm_cluster_group o2nm_cluster_group = { | |||
900 | }, | 900 | }, |
901 | }; | 901 | }; |
902 | 902 | ||
903 | int o2nm_depend_item(struct config_item *item) | ||
904 | { | ||
905 | return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item); | ||
906 | } | ||
907 | |||
908 | void o2nm_undepend_item(struct config_item *item) | ||
909 | { | ||
910 | configfs_undepend_item(&o2nm_cluster_group.cs_subsys, item); | ||
911 | } | ||
912 | |||
913 | int o2nm_depend_this_node(void) | ||
914 | { | ||
915 | int ret = 0; | ||
916 | struct o2nm_node *local_node; | ||
917 | |||
918 | local_node = o2nm_get_node_by_num(o2nm_this_node()); | ||
919 | if (!local_node) { | ||
920 | ret = -EINVAL; | ||
921 | goto out; | ||
922 | } | ||
923 | |||
924 | ret = o2nm_depend_item(&local_node->nd_item); | ||
925 | o2nm_node_put(local_node); | ||
926 | |||
927 | out: | ||
928 | return ret; | ||
929 | } | ||
930 | |||
931 | void o2nm_undepend_this_node(void) | ||
932 | { | ||
933 | struct o2nm_node *local_node; | ||
934 | |||
935 | local_node = o2nm_get_node_by_num(o2nm_this_node()); | ||
936 | BUG_ON(!local_node); | ||
937 | |||
938 | o2nm_undepend_item(&local_node->nd_item); | ||
939 | o2nm_node_put(local_node); | ||
940 | } | ||
941 | |||
942 | |||
903 | static void __exit exit_o2nm(void) | 943 | static void __exit exit_o2nm(void) |
904 | { | 944 | { |
905 | if (ocfs2_table_header) | 945 | if (ocfs2_table_header) |
@@ -934,7 +974,7 @@ static int __init init_o2nm(void) | |||
934 | goto out_sysctl; | 974 | goto out_sysctl; |
935 | 975 | ||
936 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); | 976 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); |
937 | init_MUTEX(&o2nm_cluster_group.cs_subsys.su_sem); | 977 | mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); |
938 | ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys); | 978 | ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys); |
939 | if (ret) { | 979 | if (ret) { |
940 | printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); | 980 | printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); |
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index 070522138ae2..7c860361b8dd 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h | |||
@@ -77,4 +77,9 @@ struct o2nm_node *o2nm_get_node_by_ip(__be32 addr); | |||
77 | void o2nm_node_get(struct o2nm_node *node); | 77 | void o2nm_node_get(struct o2nm_node *node); |
78 | void o2nm_node_put(struct o2nm_node *node); | 78 | void o2nm_node_put(struct o2nm_node *node); |
79 | 79 | ||
80 | int o2nm_depend_item(struct config_item *item); | ||
81 | void o2nm_undepend_item(struct config_item *item); | ||
82 | int o2nm_depend_this_node(void); | ||
83 | void o2nm_undepend_this_node(void); | ||
84 | |||
80 | #endif /* O2CLUSTER_NODEMANAGER_H */ | 85 | #endif /* O2CLUSTER_NODEMANAGER_H */ |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 0b229a9c7952..f0bdfd944c44 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -261,14 +261,12 @@ out: | |||
261 | 261 | ||
262 | static void o2net_complete_nodes_nsw(struct o2net_node *nn) | 262 | static void o2net_complete_nodes_nsw(struct o2net_node *nn) |
263 | { | 263 | { |
264 | struct list_head *iter, *tmp; | 264 | struct o2net_status_wait *nsw, *tmp; |
265 | unsigned int num_kills = 0; | 265 | unsigned int num_kills = 0; |
266 | struct o2net_status_wait *nsw; | ||
267 | 266 | ||
268 | assert_spin_locked(&nn->nn_lock); | 267 | assert_spin_locked(&nn->nn_lock); |
269 | 268 | ||
270 | list_for_each_safe(iter, tmp, &nn->nn_status_list) { | 269 | list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) { |
271 | nsw = list_entry(iter, struct o2net_status_wait, ns_node_item); | ||
272 | o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0); | 270 | o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0); |
273 | num_kills++; | 271 | num_kills++; |
274 | } | 272 | } |
@@ -764,13 +762,10 @@ EXPORT_SYMBOL_GPL(o2net_register_handler); | |||
764 | 762 | ||
765 | void o2net_unregister_handler_list(struct list_head *list) | 763 | void o2net_unregister_handler_list(struct list_head *list) |
766 | { | 764 | { |
767 | struct list_head *pos, *n; | 765 | struct o2net_msg_handler *nmh, *n; |
768 | struct o2net_msg_handler *nmh; | ||
769 | 766 | ||
770 | write_lock(&o2net_handler_lock); | 767 | write_lock(&o2net_handler_lock); |
771 | list_for_each_safe(pos, n, list) { | 768 | list_for_each_entry_safe(nmh, n, list, nh_unregister_item) { |
772 | nmh = list_entry(pos, struct o2net_msg_handler, | ||
773 | nh_unregister_item); | ||
774 | mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", | 769 | mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", |
775 | nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); | 770 | nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); |
776 | rb_erase(&nmh->nh_node, &o2net_handler_tree); | 771 | rb_erase(&nmh->nh_node, &o2net_handler_tree); |
@@ -1638,8 +1633,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, | |||
1638 | 1633 | ||
1639 | void o2net_unregister_hb_callbacks(void) | 1634 | void o2net_unregister_hb_callbacks(void) |
1640 | { | 1635 | { |
1641 | o2hb_unregister_callback(&o2net_hb_up); | 1636 | o2hb_unregister_callback(NULL, &o2net_hb_up); |
1642 | o2hb_unregister_callback(&o2net_hb_down); | 1637 | o2hb_unregister_callback(NULL, &o2net_hb_down); |
1643 | } | 1638 | } |
1644 | 1639 | ||
1645 | int o2net_register_hb_callbacks(void) | 1640 | int o2net_register_hb_callbacks(void) |
@@ -1651,9 +1646,9 @@ int o2net_register_hb_callbacks(void) | |||
1651 | o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB, | 1646 | o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB, |
1652 | o2net_hb_node_up_cb, NULL, O2NET_HB_PRI); | 1647 | o2net_hb_node_up_cb, NULL, O2NET_HB_PRI); |
1653 | 1648 | ||
1654 | ret = o2hb_register_callback(&o2net_hb_up); | 1649 | ret = o2hb_register_callback(NULL, &o2net_hb_up); |
1655 | if (ret == 0) | 1650 | if (ret == 0) |
1656 | ret = o2hb_register_callback(&o2net_hb_down); | 1651 | ret = o2hb_register_callback(NULL, &o2net_hb_down); |
1657 | 1652 | ||
1658 | if (ret) | 1653 | if (ret) |
1659 | o2net_unregister_hb_callbacks(); | 1654 | o2net_unregister_hb_callbacks(); |