aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r--fs/dlm/lock.c127
1 files changed, 94 insertions, 33 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index eb507c453c5f..17903b491298 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -56,6 +56,7 @@
56 L: receive_xxxx_reply() <- R: send_xxxx_reply() 56 L: receive_xxxx_reply() <- R: send_xxxx_reply()
57*/ 57*/
58#include <linux/types.h> 58#include <linux/types.h>
59#include <linux/slab.h>
59#include "dlm_internal.h" 60#include "dlm_internal.h"
60#include <linux/dlm_device.h> 61#include <linux/dlm_device.h>
61#include "memory.h" 62#include "memory.h"
@@ -307,7 +308,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
307 lkb->lkb_lksb->sb_status = rv; 308 lkb->lkb_lksb->sb_status = rv;
308 lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; 309 lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
309 310
310 dlm_add_ast(lkb, AST_COMP, 0); 311 dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode);
311} 312}
312 313
313static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) 314static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -320,10 +321,12 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
320{ 321{
321 lkb->lkb_time_bast = ktime_get(); 322 lkb->lkb_time_bast = ktime_get();
322 323
323 if (is_master_copy(lkb)) 324 if (is_master_copy(lkb)) {
325 lkb->lkb_bastmode = rqmode; /* printed by debugfs */
324 send_bast(r, lkb, rqmode); 326 send_bast(r, lkb, rqmode);
325 else 327 } else {
326 dlm_add_ast(lkb, AST_BAST, rqmode); 328 dlm_add_ast(lkb, AST_BAST, rqmode);
329 }
327} 330}
328 331
329/* 332/*
@@ -2280,20 +2283,30 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
2280 if (can_be_queued(lkb)) { 2283 if (can_be_queued(lkb)) {
2281 error = -EINPROGRESS; 2284 error = -EINPROGRESS;
2282 add_lkb(r, lkb, DLM_LKSTS_WAITING); 2285 add_lkb(r, lkb, DLM_LKSTS_WAITING);
2283 send_blocking_asts(r, lkb);
2284 add_timeout(lkb); 2286 add_timeout(lkb);
2285 goto out; 2287 goto out;
2286 } 2288 }
2287 2289
2288 error = -EAGAIN; 2290 error = -EAGAIN;
2289 if (force_blocking_asts(lkb))
2290 send_blocking_asts_all(r, lkb);
2291 queue_cast(r, lkb, -EAGAIN); 2291 queue_cast(r, lkb, -EAGAIN);
2292
2293 out: 2292 out:
2294 return error; 2293 return error;
2295} 2294}
2296 2295
2296static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
2297 int error)
2298{
2299 switch (error) {
2300 case -EAGAIN:
2301 if (force_blocking_asts(lkb))
2302 send_blocking_asts_all(r, lkb);
2303 break;
2304 case -EINPROGRESS:
2305 send_blocking_asts(r, lkb);
2306 break;
2307 }
2308}
2309
2297static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) 2310static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2298{ 2311{
2299 int error = 0; 2312 int error = 0;
@@ -2304,7 +2317,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2304 if (can_be_granted(r, lkb, 1, &deadlk)) { 2317 if (can_be_granted(r, lkb, 1, &deadlk)) {
2305 grant_lock(r, lkb); 2318 grant_lock(r, lkb);
2306 queue_cast(r, lkb, 0); 2319 queue_cast(r, lkb, 0);
2307 grant_pending_locks(r);
2308 goto out; 2320 goto out;
2309 } 2321 }
2310 2322
@@ -2334,7 +2346,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2334 if (_can_be_granted(r, lkb, 1)) { 2346 if (_can_be_granted(r, lkb, 1)) {
2335 grant_lock(r, lkb); 2347 grant_lock(r, lkb);
2336 queue_cast(r, lkb, 0); 2348 queue_cast(r, lkb, 0);
2337 grant_pending_locks(r);
2338 goto out; 2349 goto out;
2339 } 2350 }
2340 /* else fall through and move to convert queue */ 2351 /* else fall through and move to convert queue */
@@ -2344,28 +2355,47 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2344 error = -EINPROGRESS; 2355 error = -EINPROGRESS;
2345 del_lkb(r, lkb); 2356 del_lkb(r, lkb);
2346 add_lkb(r, lkb, DLM_LKSTS_CONVERT); 2357 add_lkb(r, lkb, DLM_LKSTS_CONVERT);
2347 send_blocking_asts(r, lkb);
2348 add_timeout(lkb); 2358 add_timeout(lkb);
2349 goto out; 2359 goto out;
2350 } 2360 }
2351 2361
2352 error = -EAGAIN; 2362 error = -EAGAIN;
2353 if (force_blocking_asts(lkb))
2354 send_blocking_asts_all(r, lkb);
2355 queue_cast(r, lkb, -EAGAIN); 2363 queue_cast(r, lkb, -EAGAIN);
2356
2357 out: 2364 out:
2358 return error; 2365 return error;
2359} 2366}
2360 2367
2368static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
2369 int error)
2370{
2371 switch (error) {
2372 case 0:
2373 grant_pending_locks(r);
2374 /* grant_pending_locks also sends basts */
2375 break;
2376 case -EAGAIN:
2377 if (force_blocking_asts(lkb))
2378 send_blocking_asts_all(r, lkb);
2379 break;
2380 case -EINPROGRESS:
2381 send_blocking_asts(r, lkb);
2382 break;
2383 }
2384}
2385
2361static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) 2386static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
2362{ 2387{
2363 remove_lock(r, lkb); 2388 remove_lock(r, lkb);
2364 queue_cast(r, lkb, -DLM_EUNLOCK); 2389 queue_cast(r, lkb, -DLM_EUNLOCK);
2365 grant_pending_locks(r);
2366 return -DLM_EUNLOCK; 2390 return -DLM_EUNLOCK;
2367} 2391}
2368 2392
2393static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
2394 int error)
2395{
2396 grant_pending_locks(r);
2397}
2398
2369/* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ 2399/* returns: 0 did nothing, -DLM_ECANCEL canceled lock */
2370 2400
2371static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) 2401static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -2375,12 +2405,18 @@ static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
2375 error = revert_lock(r, lkb); 2405 error = revert_lock(r, lkb);
2376 if (error) { 2406 if (error) {
2377 queue_cast(r, lkb, -DLM_ECANCEL); 2407 queue_cast(r, lkb, -DLM_ECANCEL);
2378 grant_pending_locks(r);
2379 return -DLM_ECANCEL; 2408 return -DLM_ECANCEL;
2380 } 2409 }
2381 return 0; 2410 return 0;
2382} 2411}
2383 2412
2413static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb,
2414 int error)
2415{
2416 if (error)
2417 grant_pending_locks(r);
2418}
2419
2384/* 2420/*
2385 * Four stage 3 varieties: 2421 * Four stage 3 varieties:
2386 * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() 2422 * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock()
@@ -2402,11 +2438,15 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
2402 goto out; 2438 goto out;
2403 } 2439 }
2404 2440
2405 if (is_remote(r)) 2441 if (is_remote(r)) {
2406 /* receive_request() calls do_request() on remote node */ 2442 /* receive_request() calls do_request() on remote node */
2407 error = send_request(r, lkb); 2443 error = send_request(r, lkb);
2408 else 2444 } else {
2409 error = do_request(r, lkb); 2445 error = do_request(r, lkb);
2446 /* for remote locks the request_reply is sent
2447 between do_request and do_request_effects */
2448 do_request_effects(r, lkb, error);
2449 }
2410 out: 2450 out:
2411 return error; 2451 return error;
2412} 2452}
@@ -2417,11 +2457,15 @@ static int _convert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
2417{ 2457{
2418 int error; 2458 int error;
2419 2459
2420 if (is_remote(r)) 2460 if (is_remote(r)) {
2421 /* receive_convert() calls do_convert() on remote node */ 2461 /* receive_convert() calls do_convert() on remote node */
2422 error = send_convert(r, lkb); 2462 error = send_convert(r, lkb);
2423 else 2463 } else {
2424 error = do_convert(r, lkb); 2464 error = do_convert(r, lkb);
2465 /* for remote locks the convert_reply is sent
2466 between do_convert and do_convert_effects */
2467 do_convert_effects(r, lkb, error);
2468 }
2425 2469
2426 return error; 2470 return error;
2427} 2471}
@@ -2432,11 +2476,15 @@ static int _unlock_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
2432{ 2476{
2433 int error; 2477 int error;
2434 2478
2435 if (is_remote(r)) 2479 if (is_remote(r)) {
2436 /* receive_unlock() calls do_unlock() on remote node */ 2480 /* receive_unlock() calls do_unlock() on remote node */
2437 error = send_unlock(r, lkb); 2481 error = send_unlock(r, lkb);
2438 else 2482 } else {
2439 error = do_unlock(r, lkb); 2483 error = do_unlock(r, lkb);
2484 /* for remote locks the unlock_reply is sent
2485 between do_unlock and do_unlock_effects */
2486 do_unlock_effects(r, lkb, error);
2487 }
2440 2488
2441 return error; 2489 return error;
2442} 2490}
@@ -2447,11 +2495,15 @@ static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
2447{ 2495{
2448 int error; 2496 int error;
2449 2497
2450 if (is_remote(r)) 2498 if (is_remote(r)) {
2451 /* receive_cancel() calls do_cancel() on remote node */ 2499 /* receive_cancel() calls do_cancel() on remote node */
2452 error = send_cancel(r, lkb); 2500 error = send_cancel(r, lkb);
2453 else 2501 } else {
2454 error = do_cancel(r, lkb); 2502 error = do_cancel(r, lkb);
2503 /* for remote locks the cancel_reply is sent
2504 between do_cancel and do_cancel_effects */
2505 do_cancel_effects(r, lkb, error);
2506 }
2455 2507
2456 return error; 2508 return error;
2457} 2509}
@@ -2689,7 +2741,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len,
2689 pass into lowcomms_commit and a message buffer (mb) that we 2741 pass into lowcomms_commit and a message buffer (mb) that we
2690 write our data into */ 2742 write our data into */
2691 2743
2692 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); 2744 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
2693 if (!mh) 2745 if (!mh)
2694 return -ENOBUFS; 2746 return -ENOBUFS;
2695 2747
@@ -3191,6 +3243,7 @@ static void receive_request(struct dlm_ls *ls, struct dlm_message *ms)
3191 attach_lkb(r, lkb); 3243 attach_lkb(r, lkb);
3192 error = do_request(r, lkb); 3244 error = do_request(r, lkb);
3193 send_request_reply(r, lkb, error); 3245 send_request_reply(r, lkb, error);
3246 do_request_effects(r, lkb, error);
3194 3247
3195 unlock_rsb(r); 3248 unlock_rsb(r);
3196 put_rsb(r); 3249 put_rsb(r);
@@ -3226,15 +3279,19 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms)
3226 goto out; 3279 goto out;
3227 3280
3228 receive_flags(lkb, ms); 3281 receive_flags(lkb, ms);
3282
3229 error = receive_convert_args(ls, lkb, ms); 3283 error = receive_convert_args(ls, lkb, ms);
3230 if (error) 3284 if (error) {
3231 goto out_reply; 3285 send_convert_reply(r, lkb, error);
3286 goto out;
3287 }
3288
3232 reply = !down_conversion(lkb); 3289 reply = !down_conversion(lkb);
3233 3290
3234 error = do_convert(r, lkb); 3291 error = do_convert(r, lkb);
3235 out_reply:
3236 if (reply) 3292 if (reply)
3237 send_convert_reply(r, lkb, error); 3293 send_convert_reply(r, lkb, error);
3294 do_convert_effects(r, lkb, error);
3238 out: 3295 out:
3239 unlock_rsb(r); 3296 unlock_rsb(r);
3240 put_rsb(r); 3297 put_rsb(r);
@@ -3266,13 +3323,16 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms)
3266 goto out; 3323 goto out;
3267 3324
3268 receive_flags(lkb, ms); 3325 receive_flags(lkb, ms);
3326
3269 error = receive_unlock_args(ls, lkb, ms); 3327 error = receive_unlock_args(ls, lkb, ms);
3270 if (error) 3328 if (error) {
3271 goto out_reply; 3329 send_unlock_reply(r, lkb, error);
3330 goto out;
3331 }
3272 3332
3273 error = do_unlock(r, lkb); 3333 error = do_unlock(r, lkb);
3274 out_reply:
3275 send_unlock_reply(r, lkb, error); 3334 send_unlock_reply(r, lkb, error);
3335 do_unlock_effects(r, lkb, error);
3276 out: 3336 out:
3277 unlock_rsb(r); 3337 unlock_rsb(r);
3278 put_rsb(r); 3338 put_rsb(r);
@@ -3307,6 +3367,7 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms)
3307 3367
3308 error = do_cancel(r, lkb); 3368 error = do_cancel(r, lkb);
3309 send_cancel_reply(r, lkb, error); 3369 send_cancel_reply(r, lkb, error);
3370 do_cancel_effects(r, lkb, error);
3310 out: 3371 out:
3311 unlock_rsb(r); 3372 unlock_rsb(r);
3312 put_rsb(r); 3373 put_rsb(r);
@@ -4512,7 +4573,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4512 } 4573 }
4513 4574
4514 if (flags & DLM_LKF_VALBLK) { 4575 if (flags & DLM_LKF_VALBLK) {
4515 ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); 4576 ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
4516 if (!ua->lksb.sb_lvbptr) { 4577 if (!ua->lksb.sb_lvbptr) {
4517 kfree(ua); 4578 kfree(ua);
4518 __put_lkb(ls, lkb); 4579 __put_lkb(ls, lkb);
@@ -4582,7 +4643,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4582 ua = lkb->lkb_ua; 4643 ua = lkb->lkb_ua;
4583 4644
4584 if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { 4645 if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
4585 ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); 4646 ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
4586 if (!ua->lksb.sb_lvbptr) { 4647 if (!ua->lksb.sb_lvbptr) {
4587 error = -ENOMEM; 4648 error = -ENOMEM;
4588 goto out_put; 4649 goto out_put;