diff options
author | David Teigland <teigland@redhat.com> | 2008-01-30 19:52:53 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-04-18 11:56:04 -0400 |
commit | 1693a5c0117f8ccd010a666f97aaf0f14fb0a0e4 (patch) | |
tree | 189560d59df3eebfe756698d24219008d9662606 /fs | |
parent | de551246e7bc5558371c3427889a8db1b8cc60f4 (diff) |
ocfs2: handle async EAGAIN from NOQUEUE request
When using fsdlm, -EAGAIN is returned in the async callback for NOQUEUE
requests. Fix up dlmglue to expect this.
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/dlmglue.c | 27 |
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 | 919 | out: | |
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 | ||
1626 | out: | 1645 | out: |