X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_inodebits.c;h=1cc1d05da6609e45838256400c99c2f67daea75b;hb=2c7a41a5c5958d36fa839ea91f3e63375cbd90fc;hp=9755425d15f82593d29a28e49dacf37d2629a23c;hpb=c1f6b32958c799412c830f35f8d16ed7275407ea;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/ldlm_inodebits.c b/lustre/ldlm/ldlm_inodebits.c index 9755425..1cc1d05 100644 --- a/lustre/ldlm/ldlm_inodebits.c +++ b/lustre/ldlm/ldlm_inodebits.c @@ -1,24 +1,42 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: +/* + * GPL HEADER START * - * Copyright (c) 2002, 2003, 2004 Cluster File Systems, Inc. - * Author: Peter Braam - * Author: Phil Schwan + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * This file is part of Lustre, http://www.lustre.org. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * 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 * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2011, Whamcloud, Inc. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/ldlm/ldlm_inodebits.c + * + * Author: Peter Braam + * Author: Phil Schwan */ #define DEBUG_SUBSYSTEM S_LDLM @@ -32,12 +50,13 @@ #include "ldlm_internal.h" +#ifdef HAVE_SERVER_SUPPORT /* Determine if the lock is compatible with all locks on the queue. */ static int -ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, - struct list_head *work_list) +ldlm_inodebits_compat_queue(cfs_list_t *queue, struct ldlm_lock *req, + cfs_list_t *work_list) { - struct list_head *tmp, *tmp_tail; + cfs_list_t *tmp; struct ldlm_lock *lock; ldlm_mode_t req_mode = req->l_req_mode; __u64 req_bits = req->l_policy_data.l_inodebits.bits; @@ -47,65 +66,70 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, LASSERT(req_bits); /* There is no sense in lock with no bits set, I think. Also such a lock would be compatible with any other bit lock */ - list_for_each(tmp, queue) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); + + cfs_list_for_each(tmp, queue) { + cfs_list_t *mode_tail; + + lock = cfs_list_entry(tmp, struct ldlm_lock, l_res_link); if (req == lock) RETURN(compat); + /* last lock in mode group */ + LASSERT(lock->l_sl_mode.prev != NULL); + mode_tail = &cfs_list_entry(lock->l_sl_mode.prev, + struct ldlm_lock, + l_sl_mode)->l_res_link; + /* locks are compatible, bits don't matter */ if (lockmode_compat(lock->l_req_mode, req_mode)) { - /* jump to next mode group */ - if (LDLM_SL_HEAD(&lock->l_sl_mode)) - tmp = &list_entry(lock->l_sl_mode.next, - struct ldlm_lock, - l_sl_mode)->l_res_link; + /* jump to last lock in mode group */ + tmp = mode_tail; continue; } - - tmp_tail = tmp; - if (LDLM_SL_HEAD(&lock->l_sl_mode)) - tmp_tail = &list_entry(lock->l_sl_mode.next, - struct ldlm_lock, - l_sl_mode)->l_res_link; + for (;;) { + cfs_list_t *head; + + /* last lock in policy group */ + tmp = &cfs_list_entry(lock->l_sl_policy.prev, + struct ldlm_lock, + l_sl_policy)->l_res_link; + /* locks with bits overlapped are conflicting locks */ if (lock->l_policy_data.l_inodebits.bits & req_bits) { + /* COS lock from the same client is + not conflicting */ + if (lock->l_req_mode == LCK_COS && + lock->l_client_cookie == req->l_client_cookie) + goto not_conflicting; /* conflicting policy */ if (!work_list) RETURN(0); compat = 0; + + /* add locks of the policy group to + * @work_list as blocking locks for + * @req */ if (lock->l_blocking_ast) - ldlm_add_ast_work_item(lock, req, + ldlm_add_ast_work_item(lock, req, work_list); - /* add all members of the policy group */ - if (LDLM_SL_HEAD(&lock->l_sl_policy)) { - do { - tmp = lock->l_res_link.next; - lock = list_entry(tmp, - struct ldlm_lock, - l_res_link); - if (lock->l_blocking_ast) - ldlm_add_ast_work_item( - lock, - req, - work_list); - } while (!LDLM_SL_TAIL(&lock->l_sl_policy)); - } - } else if (LDLM_SL_HEAD(&lock->l_sl_policy)) { - /* jump to next policy group */ - tmp = &list_entry(lock->l_sl_policy.next, - struct ldlm_lock, - l_sl_policy)->l_res_link; + head = &lock->l_sl_policy; + cfs_list_for_each_entry(lock, head, l_sl_policy) + if (lock->l_blocking_ast) + ldlm_add_ast_work_item(lock, req, + work_list); } - if (tmp == tmp_tail) + not_conflicting: + if (tmp == mode_tail) break; - else - tmp = tmp->next; - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - } /* for locks in a mode group */ - } /* for each lock in the queue */ + + tmp = tmp->next; + lock = cfs_list_entry(tmp, struct ldlm_lock, + l_res_link); + } /* loop over policy groups within one mode group */ + } /* loop over mode groups within @queue */ RETURN(compat); } @@ -119,14 +143,14 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req, * - must call this function with the ns lock held once */ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, int *flags, int first_enq, ldlm_error_t *err, - struct list_head *work_list) + cfs_list_t *work_list) { struct ldlm_resource *res = lock->l_resource; CFS_LIST_HEAD(rpc_list); int rc; ENTRY; - LASSERT(list_empty(&res->lr_converting)); + LASSERT(cfs_list_empty(&res->lr_converting)); check_res_locked(res); if (!first_enq) { @@ -154,10 +178,11 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, int *flags, * bug 2322: we used to unlink and re-add here, which was a * terrible folly -- if we goto restart, we could get * re-ordered! Causes deadlock, because ASTs aren't sent! */ - if (list_empty(&lock->l_res_link)) + if (cfs_list_empty(&lock->l_res_link)) ldlm_resource_add_lock(res, &res->lr_waiting, lock); unlock_res(res); - rc = ldlm_run_ast_work(&rpc_list, LDLM_WORK_BL_AST); + rc = ldlm_run_ast_work(ldlm_res_to_ns(res), &rpc_list, + LDLM_WORK_BL_AST); lock_res(res); if (rc == -ERESTART) GOTO(restart, -ERESTART); @@ -168,3 +193,18 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, int *flags, } RETURN(0); } +#endif /* HAVE_SERVER_SUPPORT */ + +void ldlm_ibits_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy, + ldlm_policy_data_t *lpolicy) +{ + memset(lpolicy, 0, sizeof(*lpolicy)); + lpolicy->l_inodebits.bits = wpolicy->l_inodebits.bits; +} + +void ldlm_ibits_policy_local_to_wire(const ldlm_policy_data_t *lpolicy, + ldlm_wire_policy_data_t *wpolicy) +{ + memset(wpolicy, 0, sizeof(*wpolicy)); + wpolicy->l_inodebits.bits = lpolicy->l_inodebits.bits; +}