aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/lock.c69
-rw-r--r--fs/dlm/lowcomms.c24
-rw-r--r--fs/dlm/member.c4
-rw-r--r--fs/dlm/rcom.c7
4 files changed, 77 insertions, 27 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index b455919c1998..2082daf083d8 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1670,9 +1670,10 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
1670 with a deadlk here, we'd have to generate something like grant_lock with 1670 with a deadlk here, we'd have to generate something like grant_lock with
1671 the deadlk error.) */ 1671 the deadlk error.) */
1672 1672
1673/* returns the highest requested mode of all blocked conversions */ 1673/* Returns the highest requested mode of all blocked conversions; sets
1674 cw if there's a blocked conversion to DLM_LOCK_CW. */
1674 1675
1675static int grant_pending_convert(struct dlm_rsb *r, int high) 1676static int grant_pending_convert(struct dlm_rsb *r, int high, int *cw)
1676{ 1677{
1677 struct dlm_lkb *lkb, *s; 1678 struct dlm_lkb *lkb, *s;
1678 int hi, demoted, quit, grant_restart, demote_restart; 1679 int hi, demoted, quit, grant_restart, demote_restart;
@@ -1709,6 +1710,9 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
1709 } 1710 }
1710 1711
1711 hi = max_t(int, lkb->lkb_rqmode, hi); 1712 hi = max_t(int, lkb->lkb_rqmode, hi);
1713
1714 if (cw && lkb->lkb_rqmode == DLM_LOCK_CW)
1715 *cw = 1;
1712 } 1716 }
1713 1717
1714 if (grant_restart) 1718 if (grant_restart)
@@ -1721,29 +1725,52 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
1721 return max_t(int, high, hi); 1725 return max_t(int, high, hi);
1722} 1726}
1723 1727
1724static int grant_pending_wait(struct dlm_rsb *r, int high) 1728static int grant_pending_wait(struct dlm_rsb *r, int high, int *cw)
1725{ 1729{
1726 struct dlm_lkb *lkb, *s; 1730 struct dlm_lkb *lkb, *s;
1727 1731
1728 list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { 1732 list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
1729 if (can_be_granted(r, lkb, 0, NULL)) 1733 if (can_be_granted(r, lkb, 0, NULL))
1730 grant_lock_pending(r, lkb); 1734 grant_lock_pending(r, lkb);
1731 else 1735 else {
1732 high = max_t(int, lkb->lkb_rqmode, high); 1736 high = max_t(int, lkb->lkb_rqmode, high);
1737 if (lkb->lkb_rqmode == DLM_LOCK_CW)
1738 *cw = 1;
1739 }
1733 } 1740 }
1734 1741
1735 return high; 1742 return high;
1736} 1743}
1737 1744
1745/* cw of 1 means there's a lock with a rqmode of DLM_LOCK_CW that's blocked
1746 on either the convert or waiting queue.
1747 high is the largest rqmode of all locks blocked on the convert or
1748 waiting queue. */
1749
1750static int lock_requires_bast(struct dlm_lkb *gr, int high, int cw)
1751{
1752 if (gr->lkb_grmode == DLM_LOCK_PR && cw) {
1753 if (gr->lkb_highbast < DLM_LOCK_EX)
1754 return 1;
1755 return 0;
1756 }
1757
1758 if (gr->lkb_highbast < high &&
1759 !__dlm_compat_matrix[gr->lkb_grmode+1][high+1])
1760 return 1;
1761 return 0;
1762}
1763
1738static void grant_pending_locks(struct dlm_rsb *r) 1764static void grant_pending_locks(struct dlm_rsb *r)
1739{ 1765{
1740 struct dlm_lkb *lkb, *s; 1766 struct dlm_lkb *lkb, *s;
1741 int high = DLM_LOCK_IV; 1767 int high = DLM_LOCK_IV;
1768 int cw = 0;
1742 1769
1743 DLM_ASSERT(is_master(r), dlm_dump_rsb(r);); 1770 DLM_ASSERT(is_master(r), dlm_dump_rsb(r););
1744 1771
1745 high = grant_pending_convert(r, high); 1772 high = grant_pending_convert(r, high, &cw);
1746 high = grant_pending_wait(r, high); 1773 high = grant_pending_wait(r, high, &cw);
1747 1774
1748 if (high == DLM_LOCK_IV) 1775 if (high == DLM_LOCK_IV)
1749 return; 1776 return;
@@ -1751,27 +1778,41 @@ static void grant_pending_locks(struct dlm_rsb *r)
1751 /* 1778 /*
1752 * If there are locks left on the wait/convert queue then send blocking 1779 * If there are locks left on the wait/convert queue then send blocking
1753 * ASTs to granted locks based on the largest requested mode (high) 1780 * ASTs to granted locks based on the largest requested mode (high)
1754 * found above. FIXME: highbast < high comparison not valid for PR/CW. 1781 * found above.
1755 */ 1782 */
1756 1783
1757 list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) { 1784 list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
1758 if (lkb->lkb_bastaddr && (lkb->lkb_highbast < high) && 1785 if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) {
1759 !__dlm_compat_matrix[lkb->lkb_grmode+1][high+1]) { 1786 if (cw && high == DLM_LOCK_PR)
1760 queue_bast(r, lkb, high); 1787 queue_bast(r, lkb, DLM_LOCK_CW);
1788 else
1789 queue_bast(r, lkb, high);
1761 lkb->lkb_highbast = high; 1790 lkb->lkb_highbast = high;
1762 } 1791 }
1763 } 1792 }
1764} 1793}
1765 1794
1795static int modes_require_bast(struct dlm_lkb *gr, struct dlm_lkb *rq)
1796{
1797 if ((gr->lkb_grmode == DLM_LOCK_PR && rq->lkb_rqmode == DLM_LOCK_CW) ||
1798 (gr->lkb_grmode == DLM_LOCK_CW && rq->lkb_rqmode == DLM_LOCK_PR)) {
1799 if (gr->lkb_highbast < DLM_LOCK_EX)
1800 return 1;
1801 return 0;
1802 }
1803
1804 if (gr->lkb_highbast < rq->lkb_rqmode && !modes_compat(gr, rq))
1805 return 1;
1806 return 0;
1807}
1808
1766static void send_bast_queue(struct dlm_rsb *r, struct list_head *head, 1809static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
1767 struct dlm_lkb *lkb) 1810 struct dlm_lkb *lkb)
1768{ 1811{
1769 struct dlm_lkb *gr; 1812 struct dlm_lkb *gr;
1770 1813
1771 list_for_each_entry(gr, head, lkb_statequeue) { 1814 list_for_each_entry(gr, head, lkb_statequeue) {
1772 if (gr->lkb_bastaddr && 1815 if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) {
1773 gr->lkb_highbast < lkb->lkb_rqmode &&
1774 !modes_compat(gr, lkb)) {
1775 queue_bast(r, gr, lkb->lkb_rqmode); 1816 queue_bast(r, gr, lkb->lkb_rqmode);
1776 gr->lkb_highbast = lkb->lkb_rqmode; 1817 gr->lkb_highbast = lkb->lkb_rqmode;
1777 } 1818 }
@@ -2235,7 +2276,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2235 before we try again to grant this one. */ 2276 before we try again to grant this one. */
2236 2277
2237 if (is_demoted(lkb)) { 2278 if (is_demoted(lkb)) {
2238 grant_pending_convert(r, DLM_LOCK_IV); 2279 grant_pending_convert(r, DLM_LOCK_IV, NULL);
2239 if (_can_be_granted(r, lkb, 1)) { 2280 if (_can_be_granted(r, lkb, 1)) {
2240 grant_lock(r, lkb); 2281 grant_lock(r, lkb);
2241 queue_cast(r, lkb, 0); 2282 queue_cast(r, lkb, 0);
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index dd362739d291..9e9d2e82f40f 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -313,6 +313,7 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
313 in6_addr->sin6_port = cpu_to_be16(port); 313 in6_addr->sin6_port = cpu_to_be16(port);
314 *addr_len = sizeof(struct sockaddr_in6); 314 *addr_len = sizeof(struct sockaddr_in6);
315 } 315 }
316 memset((char *)saddr + *addr_len, 0, sizeof(struct sockaddr_storage) - *addr_len);
316} 317}
317 318
318/* Close a remote connection and tidy up */ 319/* Close a remote connection and tidy up */
@@ -332,8 +333,19 @@ static void close_connection(struct connection *con, bool and_other)
332 __free_page(con->rx_page); 333 __free_page(con->rx_page);
333 con->rx_page = NULL; 334 con->rx_page = NULL;
334 } 335 }
335 con->retries = 0; 336
336 mutex_unlock(&con->sock_mutex); 337 /* If we are an 'othercon' then NULL the pointer to us
338 from the parent and tidy ourself up */
339 if (test_bit(CF_IS_OTHERCON, &con->flags)) {
340 struct connection *parent = __nodeid2con(con->nodeid, 0);
341 parent->othercon = NULL;
342 kmem_cache_free(con_cache, con);
343 }
344 else {
345 /* Parent connections get reused */
346 con->retries = 0;
347 mutex_unlock(&con->sock_mutex);
348 }
337} 349}
338 350
339/* We only send shutdown messages to nodes that are not part of the cluster */ 351/* We only send shutdown messages to nodes that are not part of the cluster */
@@ -631,7 +643,7 @@ out_resched:
631 643
632out_close: 644out_close:
633 mutex_unlock(&con->sock_mutex); 645 mutex_unlock(&con->sock_mutex);
634 if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { 646 if (ret != -EAGAIN) {
635 close_connection(con, false); 647 close_connection(con, false);
636 /* Reconnect when there is something to send */ 648 /* Reconnect when there is something to send */
637 } 649 }
@@ -1122,8 +1134,6 @@ static int tcp_listen_for_all(void)
1122 1134
1123 log_print("Using TCP for communications"); 1135 log_print("Using TCP for communications");
1124 1136
1125 set_bit(CF_IS_OTHERCON, &con->flags);
1126
1127 sock = tcp_create_listen_sock(con, dlm_local_addr[0]); 1137 sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
1128 if (sock) { 1138 if (sock) {
1129 add_sock(sock, con); 1139 add_sock(sock, con);
@@ -1407,7 +1417,7 @@ void dlm_lowcomms_stop(void)
1407 for (i = 0; i <= max_nodeid; i++) { 1417 for (i = 0; i <= max_nodeid; i++) {
1408 con = __nodeid2con(i, 0); 1418 con = __nodeid2con(i, 0);
1409 if (con) { 1419 if (con) {
1410 con->flags |= 0xFF; 1420 con->flags |= 0x0F;
1411 if (con->sock) 1421 if (con->sock)
1412 con->sock->sk->sk_user_data = NULL; 1422 con->sock->sk->sk_user_data = NULL;
1413 } 1423 }
@@ -1423,8 +1433,6 @@ void dlm_lowcomms_stop(void)
1423 con = __nodeid2con(i, 0); 1433 con = __nodeid2con(i, 0);
1424 if (con) { 1434 if (con) {
1425 close_connection(con, true); 1435 close_connection(con, true);
1426 if (con->othercon)
1427 kmem_cache_free(con_cache, con->othercon);
1428 kmem_cache_free(con_cache, con); 1436 kmem_cache_free(con_cache, con);
1429 } 1437 }
1430 } 1438 }
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index 073599dced2a..d09977528f69 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -56,8 +56,10 @@ static int dlm_add_member(struct dlm_ls *ls, int nodeid)
56 return -ENOMEM; 56 return -ENOMEM;
57 57
58 w = dlm_node_weight(ls->ls_name, nodeid); 58 w = dlm_node_weight(ls->ls_name, nodeid);
59 if (w < 0) 59 if (w < 0) {
60 kfree(memb);
60 return w; 61 return w;
62 }
61 63
62 memb->nodeid = nodeid; 64 memb->nodeid = nodeid;
63 memb->weight = w; 65 memb->weight = w;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index e3a1527cbdbe..188b91c027e4 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -386,8 +386,7 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
386 dlm_recover_process_copy(ls, rc_in); 386 dlm_recover_process_copy(ls, rc_in);
387} 387}
388 388
389static int send_ls_not_ready(struct dlm_ls *ls, int nodeid, 389static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
390 struct dlm_rcom *rc_in)
391{ 390{
392 struct dlm_rcom *rc; 391 struct dlm_rcom *rc;
393 struct rcom_config *rf; 392 struct rcom_config *rf;
@@ -395,7 +394,7 @@ static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
395 char *mb; 394 char *mb;
396 int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); 395 int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
397 396
398 mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb); 397 mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb);
399 if (!mh) 398 if (!mh)
400 return -ENOBUFS; 399 return -ENOBUFS;
401 memset(mb, 0, mb_len); 400 memset(mb, 0, mb_len);
@@ -465,7 +464,7 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid)
465 log_print("lockspace %x from %d type %x not found", 464 log_print("lockspace %x from %d type %x not found",
466 hd->h_lockspace, nodeid, rc->rc_type); 465 hd->h_lockspace, nodeid, rc->rc_type);
467 if (rc->rc_type == DLM_RCOM_STATUS) 466 if (rc->rc_type == DLM_RCOM_STATUS)
468 send_ls_not_ready(ls, nodeid, rc); 467 send_ls_not_ready(nodeid, rc);
469 return; 468 return;
470 } 469 }
471 470