aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/user.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/user.c')
-rw-r--r--fs/dlm/user.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 37aad3fe8949..329da1b5285f 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -138,6 +138,35 @@ static void compat_output(struct dlm_lock_result *res,
138} 138}
139#endif 139#endif
140 140
141/* Figure out if this lock is at the end of its life and no longer
142 available for the application to use. The lkb still exists until
143 the final ast is read. A lock becomes EOL in three situations:
144 1. a noqueue request fails with EAGAIN
145 2. an unlock completes with EUNLOCK
146 3. a cancel of a waiting request completes with ECANCEL/EDEADLK
147 An EOL lock needs to be removed from the process's list of locks.
148 And we can't allow any new operation on an EOL lock. This is
149 not related to the lifetime of the lkb struct which is managed
150 entirely by refcount. */
151
152static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type)
153{
154 switch (sb_status) {
155 case -DLM_EUNLOCK:
156 return 1;
157 case -DLM_ECANCEL:
158 case -ETIMEDOUT:
159 if (lkb->lkb_grmode == DLM_LOCK_IV)
160 return 1;
161 break;
162 case -EAGAIN:
163 if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV)
164 return 1;
165 break;
166 }
167 return 0;
168}
169
141/* we could possibly check if the cancel of an orphan has resulted in the lkb 170/* we could possibly check if the cancel of an orphan has resulted in the lkb
142 being removed and then remove that lkb from the orphans list and free it */ 171 being removed and then remove that lkb from the orphans list and free it */
143 172
@@ -184,25 +213,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
184 log_debug(ls, "ast overlap %x status %x %x", 213 log_debug(ls, "ast overlap %x status %x %x",
185 lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags); 214 lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags);
186 215
187 /* Figure out if this lock is at the end of its life and no longer 216 eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type);
188 available for the application to use. The lkb still exists until
189 the final ast is read. A lock becomes EOL in three situations:
190 1. a noqueue request fails with EAGAIN
191 2. an unlock completes with EUNLOCK
192 3. a cancel of a waiting request completes with ECANCEL
193 An EOL lock needs to be removed from the process's list of locks.
194 And we can't allow any new operation on an EOL lock. This is
195 not related to the lifetime of the lkb struct which is managed
196 entirely by refcount. */
197
198 if (type == AST_COMP &&
199 lkb->lkb_grmode == DLM_LOCK_IV &&
200 ua->lksb.sb_status == -EAGAIN)
201 eol = 1;
202 else if (ua->lksb.sb_status == -DLM_EUNLOCK ||
203 (ua->lksb.sb_status == -DLM_ECANCEL &&
204 lkb->lkb_grmode == DLM_LOCK_IV))
205 eol = 1;
206 if (eol) { 217 if (eol) {
207 lkb->lkb_ast_type &= ~AST_BAST; 218 lkb->lkb_ast_type &= ~AST_BAST;
208 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; 219 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;