aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/dlmglue.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 295c47f7aba2..b640423b936a 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -880,13 +880,20 @@ static void ocfs2_locking_ast(void *opaque)
880 struct ocfs2_lock_res *lockres = opaque; 880 struct ocfs2_lock_res *lockres = opaque;
881 struct ocfs2_super *osb = ocfs2_get_lockres_osb(lockres); 881 struct ocfs2_super *osb = ocfs2_get_lockres_osb(lockres);
882 unsigned long flags; 882 unsigned long flags;
883 int status;
883 884
884 spin_lock_irqsave(&lockres->l_lock, flags); 885 spin_lock_irqsave(&lockres->l_lock, flags);
885 886
886 if (ocfs2_dlm_lock_status(&lockres->l_lksb)) { 887 status = ocfs2_dlm_lock_status(&lockres->l_lksb);
888
889 if (status == -EAGAIN) {
890 lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
891 goto out;
892 }
893
894 if (status) {
887 mlog(ML_ERROR, "lockres %s: lksb status value of %d!\n", 895 mlog(ML_ERROR, "lockres %s: lksb status value of %d!\n",
888 lockres->l_name, 896 lockres->l_name, status);
889 ocfs2_dlm_lock_status(&lockres->l_lksb));
890 spin_unlock_irqrestore(&lockres->l_lock, flags); 897 spin_unlock_irqrestore(&lockres->l_lock, flags);
891 return; 898 return;
892 } 899 }
@@ -909,7 +916,7 @@ static void ocfs2_locking_ast(void *opaque)
909 lockres->l_unlock_action); 916 lockres->l_unlock_action);
910 BUG(); 917 BUG();
911 } 918 }
912 919out:
913 /* set it to something invalid so if we get called again we 920 /* set it to something invalid so if we get called again we
914 * can catch it. */ 921 * can catch it. */
915 lockres->l_action = OCFS2_AST_INVALID; 922 lockres->l_action = OCFS2_AST_INVALID;
@@ -1113,6 +1120,7 @@ static int ocfs2_cluster_lock(struct ocfs2_super *osb,
1113 int ret = 0; /* gcc doesn't realize wait = 1 guarantees ret is set */ 1120 int ret = 0; /* gcc doesn't realize wait = 1 guarantees ret is set */
1114 unsigned long flags; 1121 unsigned long flags;
1115 unsigned int gen; 1122 unsigned int gen;
1123 int noqueue_attempted = 0;
1116 1124
1117 mlog_entry_void(); 1125 mlog_entry_void();
1118 1126
@@ -1157,6 +1165,13 @@ again:
1157 } 1165 }
1158 1166
1159 if (level > lockres->l_level) { 1167 if (level > lockres->l_level) {
1168 if (noqueue_attempted > 0) {
1169 ret = -EAGAIN;
1170 goto unlock;
1171 }
1172 if (lkm_flags & DLM_LKF_NOQUEUE)
1173 noqueue_attempted = 1;
1174
1160 if (lockres->l_action != OCFS2_AST_INVALID) 1175 if (lockres->l_action != OCFS2_AST_INVALID)
1161 mlog(ML_ERROR, "lockres %s has action %u pending\n", 1176 mlog(ML_ERROR, "lockres %s has action %u pending\n",
1162 lockres->l_name, lockres->l_action); 1177 lockres->l_name, lockres->l_action);
@@ -1621,6 +1636,10 @@ int ocfs2_file_lock(struct file *file, int ex, int trylock)
1621 * to just bubble sucess back up to the user. 1636 * to just bubble sucess back up to the user.
1622 */ 1637 */
1623 ret = ocfs2_flock_handle_signal(lockres, level); 1638 ret = ocfs2_flock_handle_signal(lockres, level);
1639 } else if (!ret && (level > lockres->l_level)) {
1640 /* Trylock failed asynchronously */
1641 BUG_ON(!trylock);
1642 ret = -EAGAIN;
1624 } 1643 }
1625 1644
1626out: 1645out: