X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_inodebits.c;h=636527b566b81d85fe5c35cb8043f56c61662c8a;hb=019a3b34c0f4d934266a185bcda048b1dab201ed;hp=0c31481b90b86adc7d04972184bf4fea3e7143e4;hpb=930dca7253bc2531bffa15dc763db1081cdf32d8;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/ldlm_inodebits.c b/lustre/ldlm/ldlm_inodebits.c index 0c31481..636527b 100644 --- a/lustre/ldlm/ldlm_inodebits.c +++ b/lustre/ldlm/ldlm_inodebits.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2013, Intel Corporation. + * Copyright (c) 2011, 2016, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -56,6 +52,7 @@ #include #include #include +#include #include "ldlm_internal.h" @@ -81,7 +78,6 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, { struct list_head *tmp; struct ldlm_lock *lock; - enum ldlm_mode req_mode = req->l_req_mode; __u64 req_bits = req->l_policy_data.l_inodebits.bits; int compat = 1; ENTRY; @@ -98,23 +94,33 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, /* We stop walking the queue if we hit ourselves so we don't * take conflicting locks enqueued after us into account, * or we'd wait forever. */ - if (req == lock) - RETURN(compat); + if (req == lock) + RETURN(compat); - /* last lock in mode group */ - LASSERT(lock->l_sl_mode.prev != NULL); + /* last lock in mode group */ + LASSERT(lock->l_sl_mode.prev != NULL); mode_tail = &list_entry(lock->l_sl_mode.prev, - struct ldlm_lock, - l_sl_mode)->l_res_link; + struct ldlm_lock, + l_sl_mode)->l_res_link; + + /* if reqest lock is not COS_INCOMPAT and COS is disabled, + * they are compatible, IOW this request is from a local + * transaction on a DNE system. */ + if (lock->l_req_mode == LCK_COS && !ldlm_is_cos_incompat(req) && + !ldlm_is_cos_enabled(req)) { + /* jump to last lock in mode group */ + tmp = mode_tail; + continue; + } - /* locks are compatible, bits don't matter */ - if (lockmode_compat(lock->l_req_mode, req_mode)) { - /* jump to last lock in mode group */ - tmp = mode_tail; - continue; - } + /* locks' mode are compatible, bits don't matter */ + if (lockmode_compat(lock->l_req_mode, req->l_req_mode)) { + /* jump to last lock in mode group */ + tmp = mode_tail; + continue; + } - for (;;) { + for (;;) { struct list_head *head; /* Advance loop cursor to last lock in policy group. */ @@ -128,6 +134,8 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, * requirement: it is only compatible with * locks from the same client. */ if (lock->l_req_mode == LCK_COS && + !ldlm_is_cos_incompat(req) && + ldlm_is_cos_enabled(req) && lock->l_client_cookie == req->l_client_cookie) goto not_conflicting; /* Found a conflicting policy group. */ @@ -206,8 +214,8 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags, ldlm_grant_lock(lock, work_list); *err = ELDLM_OK; - RETURN(LDLM_ITER_CONTINUE); - } + RETURN(LDLM_ITER_CONTINUE); + } restart: rc = ldlm_inodebits_compat_queue(&res->lr_granted, lock, &rpc_list); @@ -226,21 +234,35 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags, rc = ldlm_run_ast_work(ldlm_res_to_ns(res), &rpc_list, LDLM_WORK_BL_AST); lock_res(res); - if (rc == -ERESTART) + if (rc == -ERESTART) { + /* We were granted while waiting, nothing left to do */ + if (lock->l_granted_mode == lock->l_req_mode) + GOTO(out, rc = 0); + /* Lock was destroyed while we were waiting, abort */ + if (ldlm_is_destroyed(lock)) + GOTO(out, rc = -EAGAIN); + + /* Otherwise try again */ GOTO(restart, rc); + } *flags |= LDLM_FL_BLOCK_GRANTED; } else { ldlm_resource_unlink_lock(lock); ldlm_grant_lock(lock, NULL); } - RETURN(0); + + rc = 0; +out: + *err = rc; + LASSERT(list_empty(&rpc_list)); + + RETURN(rc); } #endif /* HAVE_SERVER_SUPPORT */ void ldlm_ibits_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy, union ldlm_policy_data *lpolicy) { - memset(lpolicy, 0, sizeof(*lpolicy)); lpolicy->l_inodebits.bits = wpolicy->l_inodebits.bits; }