diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 9adf8f924e08..87778857f099 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -441,6 +441,8 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state) | |||
441 | else | 441 | else |
442 | gfs2_glock_put_nolock(gl); | 442 | gfs2_glock_put_nolock(gl); |
443 | } | 443 | } |
444 | if (held1 && held2 && list_empty(&gl->gl_holders)) | ||
445 | clear_bit(GLF_QUEUED, &gl->gl_flags); | ||
444 | 446 | ||
445 | gl->gl_state = new_state; | 447 | gl->gl_state = new_state; |
446 | gl->gl_tchange = jiffies; | 448 | gl->gl_tchange = jiffies; |
@@ -1012,6 +1014,7 @@ fail: | |||
1012 | if (unlikely((gh->gh_flags & LM_FLAG_PRIORITY) && !insert_pt)) | 1014 | if (unlikely((gh->gh_flags & LM_FLAG_PRIORITY) && !insert_pt)) |
1013 | insert_pt = &gh2->gh_list; | 1015 | insert_pt = &gh2->gh_list; |
1014 | } | 1016 | } |
1017 | set_bit(GLF_QUEUED, &gl->gl_flags); | ||
1015 | if (likely(insert_pt == NULL)) { | 1018 | if (likely(insert_pt == NULL)) { |
1016 | list_add_tail(&gh->gh_list, &gl->gl_holders); | 1019 | list_add_tail(&gh->gh_list, &gl->gl_holders); |
1017 | if (unlikely(gh->gh_flags & LM_FLAG_PRIORITY)) | 1020 | if (unlikely(gh->gh_flags & LM_FLAG_PRIORITY)) |
@@ -1310,10 +1313,12 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) | |||
1310 | 1313 | ||
1311 | gfs2_glock_hold(gl); | 1314 | gfs2_glock_hold(gl); |
1312 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; | 1315 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; |
1313 | if (time_before(now, holdtime)) | 1316 | if (test_bit(GLF_QUEUED, &gl->gl_flags)) { |
1314 | delay = holdtime - now; | 1317 | if (time_before(now, holdtime)) |
1315 | if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags)) | 1318 | delay = holdtime - now; |
1316 | delay = gl->gl_ops->go_min_hold_time; | 1319 | if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags)) |
1320 | delay = gl->gl_ops->go_min_hold_time; | ||
1321 | } | ||
1317 | 1322 | ||
1318 | spin_lock(&gl->gl_spin); | 1323 | spin_lock(&gl->gl_spin); |
1319 | handle_callback(gl, state, delay); | 1324 | handle_callback(gl, state, delay); |
@@ -1512,7 +1517,7 @@ static void clear_glock(struct gfs2_glock *gl) | |||
1512 | spin_unlock(&lru_lock); | 1517 | spin_unlock(&lru_lock); |
1513 | 1518 | ||
1514 | spin_lock(&gl->gl_spin); | 1519 | spin_lock(&gl->gl_spin); |
1515 | if (find_first_holder(gl) == NULL && gl->gl_state != LM_ST_UNLOCKED) | 1520 | if (gl->gl_state != LM_ST_UNLOCKED) |
1516 | handle_callback(gl, LM_ST_UNLOCKED, 0); | 1521 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1517 | spin_unlock(&gl->gl_spin); | 1522 | spin_unlock(&gl->gl_spin); |
1518 | gfs2_glock_hold(gl); | 1523 | gfs2_glock_hold(gl); |
@@ -1660,6 +1665,8 @@ static const char *gflags2str(char *buf, const unsigned long *gflags) | |||
1660 | *p++ = 'I'; | 1665 | *p++ = 'I'; |
1661 | if (test_bit(GLF_FROZEN, gflags)) | 1666 | if (test_bit(GLF_FROZEN, gflags)) |
1662 | *p++ = 'F'; | 1667 | *p++ = 'F'; |
1668 | if (test_bit(GLF_QUEUED, gflags)) | ||
1669 | *p++ = 'q'; | ||
1663 | *p = 0; | 1670 | *p = 0; |
1664 | return buf; | 1671 | return buf; |
1665 | } | 1672 | } |
@@ -1776,10 +1783,12 @@ int __init gfs2_glock_init(void) | |||
1776 | } | 1783 | } |
1777 | #endif | 1784 | #endif |
1778 | 1785 | ||
1779 | glock_workqueue = create_workqueue("glock_workqueue"); | 1786 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_RESCUER | |
1787 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | ||
1780 | if (IS_ERR(glock_workqueue)) | 1788 | if (IS_ERR(glock_workqueue)) |
1781 | return PTR_ERR(glock_workqueue); | 1789 | return PTR_ERR(glock_workqueue); |
1782 | gfs2_delete_workqueue = create_workqueue("delete_workqueue"); | 1790 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", WQ_RESCUER | |
1791 | WQ_FREEZEABLE, 0); | ||
1783 | if (IS_ERR(gfs2_delete_workqueue)) { | 1792 | if (IS_ERR(gfs2_delete_workqueue)) { |
1784 | destroy_workqueue(glock_workqueue); | 1793 | destroy_workqueue(glock_workqueue); |
1785 | return PTR_ERR(gfs2_delete_workqueue); | 1794 | return PTR_ERR(gfs2_delete_workqueue); |