aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-14 13:00:29 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-14 13:00:29 -0400
commit28e8351ac22de25034e048c680014ad824323c65 (patch)
treefd4d137e9b761674096817943beec1936a4f702b
parent3b993e8bee32d6dfe04df560eda8e1aff6248a22 (diff)
parentd18c4d687dd4625360ee14047d7eb454217719ee (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.c69
-rw-r--r--fs/dlm/lowcomms.c24
-rw-r--r--fs/dlm/member.c4
-rw-r--r--fs/dlm/rcom.c7
-rw-r--r--fs/gfs2/lops.c6
-rw-r--r--fs/gfs2/mount.c25
-rw-r--r--fs/gfs2/ops_address.c3
-rw-r--r--fs/gfs2/ops_file.c29
-rw-r--r--fs/gfs2/rgrp.c16
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
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
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:
434out: 434out:
435 if (error) { 435 if (error) {
436 gfs2_trans_end(sdp); 436 gfs2_trans_end(sdp);
437out_trans_fail:
437 if (alloc_required) { 438 if (alloc_required) {
438 gfs2_inplace_release(ip); 439 gfs2_inplace_release(ip);
439out_qunlock: 440out_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
184static const u32 gfs2_to_fsflags[32] = { 184static 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
316static int gfs2_set_flags(struct file *filp, u32 __user *ptr) 313static 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
325static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 330static 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