diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-14 13:00:29 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-14 13:00:29 -0400 |
| commit | 28e8351ac22de25034e048c680014ad824323c65 (patch) | |
| tree | fd4d137e9b761674096817943beec1936a4f702b | |
| parent | 3b993e8bee32d6dfe04df560eda8e1aff6248a22 (diff) | |
| parent | d18c4d687dd4625360ee14047d7eb454217719ee (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
[GFS2] Revert remounting w/o acl option leaves acls enabled
[GFS2] Fix setting of inherit jdata attr
[GFS2] Fix incorrect error path in prepare_write()
[GFS2] Fix incorrect return code in rgrp.c
[GFS2] soft lockup in rgblk_search
[GFS2] soft lockup detected in databuf_lo_before_commit
[DLM] fix basts for granted PR waiting CW
[DLM] More othercon fixes
[DLM] Fix memory leak in dlm_add_member() when dlm_node_weight() returns less than zero
[DLM] zero unused parts of sockaddr_storage
[DLM] fix NULL ls usage
[DLM] Clear othercon pointers when a connection is closed
| -rw-r--r-- | fs/dlm/lock.c | 69 | ||||
| -rw-r--r-- | fs/dlm/lowcomms.c | 24 | ||||
| -rw-r--r-- | fs/dlm/member.c | 4 | ||||
| -rw-r--r-- | fs/dlm/rcom.c | 7 | ||||
| -rw-r--r-- | fs/gfs2/lops.c | 6 | ||||
| -rw-r--r-- | fs/gfs2/mount.c | 25 | ||||
| -rw-r--r-- | fs/gfs2/ops_address.c | 3 | ||||
| -rw-r--r-- | fs/gfs2/ops_file.c | 29 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 16 |
9 files changed, 124 insertions, 59 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 | ||
| 1675 | static int grant_pending_convert(struct dlm_rsb *r, int high) | 1676 | static 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 | ||
| 1724 | static int grant_pending_wait(struct dlm_rsb *r, int high) | 1728 | static 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 | |||
| 1750 | static 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 | |||
| 1738 | static void grant_pending_locks(struct dlm_rsb *r) | 1764 | static 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 | ||
| 1795 | static 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 | |||
| 1766 | static void send_bast_queue(struct dlm_rsb *r, struct list_head *head, | 1809 | static 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 | ||
| 632 | out_close: | 644 | out_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 | ||
| 389 | static int send_ls_not_ready(struct dlm_ls *ls, int nodeid, | 389 | static 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 | ||
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index aff70f0698fd..3b395c41b2f3 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
| @@ -486,8 +486,8 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | |||
| 486 | gfs2_pin(sdp, bd->bd_bh); | 486 | gfs2_pin(sdp, bd->bd_bh); |
| 487 | tr->tr_num_databuf_new++; | 487 | tr->tr_num_databuf_new++; |
| 488 | } | 488 | } |
| 489 | sdp->sd_log_num_databuf++; | ||
| 490 | gfs2_log_lock(sdp); | 489 | gfs2_log_lock(sdp); |
| 490 | sdp->sd_log_num_databuf++; | ||
| 491 | list_add(&le->le_list, &sdp->sd_log_le_databuf); | 491 | list_add(&le->le_list, &sdp->sd_log_le_databuf); |
| 492 | gfs2_log_unlock(sdp); | 492 | gfs2_log_unlock(sdp); |
| 493 | } | 493 | } |
| @@ -523,7 +523,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
| 523 | struct buffer_head *bh = NULL,*bh1 = NULL; | 523 | struct buffer_head *bh = NULL,*bh1 = NULL; |
| 524 | struct gfs2_log_descriptor *ld; | 524 | struct gfs2_log_descriptor *ld; |
| 525 | unsigned int limit; | 525 | unsigned int limit; |
| 526 | unsigned int total_dbuf = sdp->sd_log_num_databuf; | 526 | unsigned int total_dbuf; |
| 527 | unsigned int total_jdata = sdp->sd_log_num_jdata; | 527 | unsigned int total_jdata = sdp->sd_log_num_jdata; |
| 528 | unsigned int num, n; | 528 | unsigned int num, n; |
| 529 | __be64 *ptr = NULL; | 529 | __be64 *ptr = NULL; |
| @@ -535,6 +535,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
| 535 | * into the log along with a header | 535 | * into the log along with a header |
| 536 | */ | 536 | */ |
| 537 | gfs2_log_lock(sdp); | 537 | gfs2_log_lock(sdp); |
| 538 | total_dbuf = sdp->sd_log_num_databuf; | ||
| 538 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, | 539 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, |
| 539 | bd_le.le_list); | 540 | bd_le.le_list); |
| 540 | while(total_dbuf) { | 541 | while(total_dbuf) { |
| @@ -653,6 +654,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
| 653 | break; | 654 | break; |
| 654 | } | 655 | } |
| 655 | bh = NULL; | 656 | bh = NULL; |
| 657 | BUG_ON(total_dbuf < num); | ||
| 656 | total_dbuf -= num; | 658 | total_dbuf -= num; |
| 657 | total_jdata -= num; | 659 | total_jdata -= num; |
| 658 | } | 660 | } |
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c index 6f006a804db3..4864659555d4 100644 --- a/fs/gfs2/mount.c +++ b/fs/gfs2/mount.c | |||
| @@ -82,19 +82,20 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) | |||
| 82 | char *options, *o, *v; | 82 | char *options, *o, *v; |
| 83 | int error = 0; | 83 | int error = 0; |
| 84 | 84 | ||
| 85 | /* If someone preloaded options, use those instead */ | 85 | if (!remount) { |
| 86 | spin_lock(&gfs2_sys_margs_lock); | 86 | /* If someone preloaded options, use those instead */ |
| 87 | if (!remount && gfs2_sys_margs) { | 87 | spin_lock(&gfs2_sys_margs_lock); |
| 88 | data = gfs2_sys_margs; | 88 | if (gfs2_sys_margs) { |
| 89 | gfs2_sys_margs = NULL; | 89 | data = gfs2_sys_margs; |
| 90 | } | 90 | gfs2_sys_margs = NULL; |
| 91 | spin_unlock(&gfs2_sys_margs_lock); | 91 | } |
| 92 | spin_unlock(&gfs2_sys_margs_lock); | ||
| 92 | 93 | ||
| 93 | /* Set some defaults */ | 94 | /* Set some defaults */ |
| 94 | memset(args, 0, sizeof(struct gfs2_args)); | 95 | args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; |
| 95 | args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; | 96 | args->ar_quota = GFS2_QUOTA_DEFAULT; |
| 96 | args->ar_quota = GFS2_QUOTA_DEFAULT; | 97 | args->ar_data = GFS2_DATA_DEFAULT; |
| 97 | args->ar_data = GFS2_DATA_DEFAULT; | 98 | } |
| 98 | 99 | ||
| 99 | /* Split the options into tokens with the "," character and | 100 | /* Split the options into tokens with the "," character and |
| 100 | process them */ | 101 | process them */ |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index ce90032c010e..42a5f58f6fca 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
| @@ -416,7 +416,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
| 416 | 416 | ||
| 417 | error = gfs2_trans_begin(sdp, rblocks, 0); | 417 | error = gfs2_trans_begin(sdp, rblocks, 0); |
| 418 | if (error) | 418 | if (error) |
| 419 | goto out; | 419 | goto out_trans_fail; |
| 420 | 420 | ||
| 421 | if (gfs2_is_stuffed(ip)) { | 421 | if (gfs2_is_stuffed(ip)) { |
| 422 | if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { | 422 | if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { |
| @@ -434,6 +434,7 @@ prepare_write: | |||
| 434 | out: | 434 | out: |
| 435 | if (error) { | 435 | if (error) { |
| 436 | gfs2_trans_end(sdp); | 436 | gfs2_trans_end(sdp); |
| 437 | out_trans_fail: | ||
| 437 | if (alloc_required) { | 438 | if (alloc_required) { |
| 438 | gfs2_inplace_release(ip); | 439 | gfs2_inplace_release(ip); |
| 439 | out_qunlock: | 440 | out_qunlock: |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 773421130116..94d76ace0b95 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
| @@ -177,8 +177,8 @@ static const u32 fsflags_to_gfs2[32] = { | |||
| 177 | [5] = GFS2_DIF_APPENDONLY, | 177 | [5] = GFS2_DIF_APPENDONLY, |
| 178 | [7] = GFS2_DIF_NOATIME, | 178 | [7] = GFS2_DIF_NOATIME, |
| 179 | [12] = GFS2_DIF_EXHASH, | 179 | [12] = GFS2_DIF_EXHASH, |
| 180 | [14] = GFS2_DIF_JDATA, | 180 | [14] = GFS2_DIF_INHERIT_JDATA, |
| 181 | [20] = GFS2_DIF_DIRECTIO, | 181 | [20] = GFS2_DIF_INHERIT_DIRECTIO, |
| 182 | }; | 182 | }; |
| 183 | 183 | ||
| 184 | static const u32 gfs2_to_fsflags[32] = { | 184 | static const u32 gfs2_to_fsflags[32] = { |
| @@ -187,8 +187,6 @@ static const u32 gfs2_to_fsflags[32] = { | |||
| 187 | [gfs2fl_AppendOnly] = FS_APPEND_FL, | 187 | [gfs2fl_AppendOnly] = FS_APPEND_FL, |
| 188 | [gfs2fl_NoAtime] = FS_NOATIME_FL, | 188 | [gfs2fl_NoAtime] = FS_NOATIME_FL, |
| 189 | [gfs2fl_ExHash] = FS_INDEX_FL, | 189 | [gfs2fl_ExHash] = FS_INDEX_FL, |
| 190 | [gfs2fl_Jdata] = FS_JOURNAL_DATA_FL, | ||
| 191 | [gfs2fl_Directio] = FS_DIRECTIO_FL, | ||
| 192 | [gfs2fl_InheritDirectio] = FS_DIRECTIO_FL, | 190 | [gfs2fl_InheritDirectio] = FS_DIRECTIO_FL, |
| 193 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, | 191 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, |
| 194 | }; | 192 | }; |
| @@ -207,6 +205,12 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
| 207 | return error; | 205 | return error; |
| 208 | 206 | ||
| 209 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); | 207 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); |
| 208 | if (!S_ISDIR(inode->i_mode)) { | ||
| 209 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | ||
| 210 | fsflags |= FS_JOURNAL_DATA_FL; | ||
| 211 | if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) | ||
| 212 | fsflags |= FS_DIRECTIO_FL; | ||
| 213 | } | ||
| 210 | if (put_user(fsflags, ptr)) | 214 | if (put_user(fsflags, ptr)) |
| 211 | error = -EFAULT; | 215 | error = -EFAULT; |
| 212 | 216 | ||
| @@ -270,13 +274,6 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
| 270 | if ((new_flags ^ flags) == 0) | 274 | if ((new_flags ^ flags) == 0) |
| 271 | goto out; | 275 | goto out; |
| 272 | 276 | ||
| 273 | if (S_ISDIR(inode->i_mode)) { | ||
| 274 | if ((new_flags ^ flags) & GFS2_DIF_JDATA) | ||
| 275 | new_flags ^= (GFS2_DIF_JDATA|GFS2_DIF_INHERIT_JDATA); | ||
| 276 | if ((new_flags ^ flags) & GFS2_DIF_DIRECTIO) | ||
| 277 | new_flags ^= (GFS2_DIF_DIRECTIO|GFS2_DIF_INHERIT_DIRECTIO); | ||
| 278 | } | ||
| 279 | |||
| 280 | error = -EINVAL; | 277 | error = -EINVAL; |
| 281 | if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET) | 278 | if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET) |
| 282 | goto out; | 279 | goto out; |
| @@ -315,11 +312,19 @@ out: | |||
| 315 | 312 | ||
| 316 | static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | 313 | static int gfs2_set_flags(struct file *filp, u32 __user *ptr) |
| 317 | { | 314 | { |
| 315 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 318 | u32 fsflags, gfsflags; | 316 | u32 fsflags, gfsflags; |
| 319 | if (get_user(fsflags, ptr)) | 317 | if (get_user(fsflags, ptr)) |
| 320 | return -EFAULT; | 318 | return -EFAULT; |
| 321 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); | 319 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); |
| 322 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 320 | if (!S_ISDIR(inode->i_mode)) { |
| 321 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | ||
| 322 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | ||
| 323 | if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO) | ||
| 324 | gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO); | ||
| 325 | return do_gfs2_set_flags(filp, gfsflags, ~0); | ||
| 326 | } | ||
| 327 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); | ||
| 323 | } | 328 | } |
| 324 | 329 | ||
| 325 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 330 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e4e040625153..ce48c4594ec8 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -863,16 +863,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
| 863 | u64 no_addr; | 863 | u64 no_addr; |
| 864 | 864 | ||
| 865 | for(;;) { | 865 | for(;;) { |
| 866 | if (goal >= rgd->rd_data) | ||
| 867 | break; | ||
| 866 | goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | 868 | goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, |
| 867 | GFS2_BLKST_UNLINKED); | 869 | GFS2_BLKST_UNLINKED); |
| 868 | if (goal == 0) | 870 | if (goal == BFITNOENT) |
| 869 | return 0; | 871 | break; |
| 870 | no_addr = goal + rgd->rd_data0; | 872 | no_addr = goal + rgd->rd_data0; |
| 871 | if (no_addr <= *last_unlinked) | 873 | goal++; |
| 874 | if (no_addr < *last_unlinked) | ||
| 872 | continue; | 875 | continue; |
| 873 | *last_unlinked = no_addr; | 876 | *last_unlinked = no_addr; |
| 874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, | 877 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, |
| 875 | no_addr, -1); | 878 | no_addr, -1); |
| 876 | if (!IS_ERR(inode)) | 879 | if (!IS_ERR(inode)) |
| 877 | return inode; | 880 | return inode; |
| 878 | } | 881 | } |
| @@ -1313,7 +1316,7 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
| 1313 | bi->bi_len, blk, new_state); | 1316 | bi->bi_len, blk, new_state); |
| 1314 | } | 1317 | } |
| 1315 | 1318 | ||
| 1316 | return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk; | 1319 | return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk; |
| 1317 | } | 1320 | } |
| 1318 | 1321 | ||
| 1319 | /** | 1322 | /** |
| @@ -1393,6 +1396,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
| 1393 | goal = rgd->rd_last_alloc_data; | 1396 | goal = rgd->rd_last_alloc_data; |
| 1394 | 1397 | ||
| 1395 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | 1398 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
| 1399 | BUG_ON(blk == BFITNOENT); | ||
| 1396 | rgd->rd_last_alloc_data = blk; | 1400 | rgd->rd_last_alloc_data = blk; |
| 1397 | 1401 | ||
| 1398 | block = rgd->rd_data0 + blk; | 1402 | block = rgd->rd_data0 + blk; |
| @@ -1437,6 +1441,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) | |||
| 1437 | goal = rgd->rd_last_alloc_meta; | 1441 | goal = rgd->rd_last_alloc_meta; |
| 1438 | 1442 | ||
| 1439 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); | 1443 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
| 1444 | BUG_ON(blk == BFITNOENT); | ||
| 1440 | rgd->rd_last_alloc_meta = blk; | 1445 | rgd->rd_last_alloc_meta = blk; |
| 1441 | 1446 | ||
| 1442 | block = rgd->rd_data0 + blk; | 1447 | block = rgd->rd_data0 + blk; |
| @@ -1478,6 +1483,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | |||
| 1478 | 1483 | ||
| 1479 | blk = rgblk_search(rgd, rgd->rd_last_alloc_meta, | 1484 | blk = rgblk_search(rgd, rgd->rd_last_alloc_meta, |
| 1480 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE); | 1485 | GFS2_BLKST_FREE, GFS2_BLKST_DINODE); |
| 1486 | BUG_ON(blk == BFITNOENT); | ||
| 1481 | 1487 | ||
| 1482 | rgd->rd_last_alloc_meta = blk; | 1488 | rgd->rd_last_alloc_meta = blk; |
| 1483 | 1489 | ||
