X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fofd%2Fofd_dlm.c;h=f148804425cfd24966afd96ce7b73696bf12f110;hb=0b715b9a53354ace21fd8574b999b53765522176;hp=22effa043905bbc20acfe5c2861a998e46a0a58e;hpb=ae0d69437e35961c257f076da6dcc1842a55456d;p=fs%2Flustre-release.git diff --git a/lustre/ofd/ofd_dlm.c b/lustre/ofd/ofd_dlm.c index 22effa0..f148804 100644 --- a/lustre/ofd/ofd_dlm.c +++ b/lustre/ofd/ofd_dlm.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) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2014 Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -35,8 +31,13 @@ * * lustre/ofd/ofd_dlm.c * - * Author: Mike Pershin - * Author: Alex Zhuravlev + * This file contains OBD Filter Device (OFD) LDLM-related code which is just + * intent handling for glimpse lock. + * + * Author: Andreas Dilger + * Author: Jinshan Xiong + * Author: Alexey Zhuravlev + * Author: Mikhail Pershin */ #define DEBUG_SUBSYSTEM S_FILTER @@ -49,6 +50,22 @@ struct ofd_intent_args { int *liblustre; }; +/** + * OFD interval callback. + * + * The interval_callback_t is part of interval_iterate_reverse() and is called + * for each interval in tree. The OFD interval callback searches for locks + * covering extents beyond the given args->size. This is used to decide if LVB + * data is outdated. + * + * \param[in] n interval node + * \param[in] args intent arguments + * + * \retval INTERVAL_ITER_STOP if the interval is lower than + * file size, caller stops execution + * \retval INTERVAL_ITER_CONT if callback finished successfully + * and caller may continue execution + */ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args) { struct ldlm_interval *node = (struct ldlm_interval *)n; @@ -61,7 +78,7 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args) if (interval_high(n) <= size) return INTERVAL_ITER_STOP; - cfs_list_for_each_entry(lck, &node->li_group, l_sl_policy) { + list_for_each_entry(lck, &node->li_group, l_sl_policy) { /* Don't send glimpse ASTs to liblustre clients. * They aren't listening for them, and they do * entirely synchronous I/O anyways. */ @@ -87,8 +104,30 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args) return INTERVAL_ITER_CONT; } +/** + * OFD lock intent policy + * + * This defines ldlm_namespace::ns_policy interface for OFD. + * Intent policy is called when lock has an intent, for OFD that + * means glimpse lock and policy fills Lock Value Block (LVB). + * + * If already granted lock is found it will be placed in \a lockp and + * returned back to caller function. + * + * \param[in] ns namespace + * \param[in,out] lockp pointer to the lock + * \param[in] req_cookie incoming request + * \param[in] mode LDLM mode + * \param[in] flags LDLM flags + * \param[in] data opaque data, not used in OFD policy + * + * \retval ELDLM_LOCK_REPLACED if already granted lock was found + * and placed in \a lockp + * \retval ELDLM_LOCK_ABORTED in other cases except error + * \retval negative value on error + */ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, - void *req_cookie, ldlm_mode_t mode, int flags, + void *req_cookie, ldlm_mode_t mode, __u64 flags, void *data) { struct ptlrpc_request *req = req_cookie; @@ -98,8 +137,7 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, struct ost_lvb *res_lvb, *reply_lvb; struct ldlm_reply *rep; ldlm_error_t err; - int idx, rc; - int tmpflags = 0, only_liblustre = 1; + int idx, rc, only_liblustre = 1; struct ldlm_interval_tree *tree; struct ofd_intent_args arg; __u32 repsize[3] = { @@ -108,9 +146,11 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, [DLM_REPLY_REC_OFF] = sizeof(*reply_lvb) }; struct ldlm_glimpse_work gl_work; - CFS_LIST_HEAD(gl_list); + struct list_head gl_list; ENTRY; + INIT_LIST_HEAD(&gl_list); + lock->l_lvb_type = LVB_T_OST; policy = ldlm_get_processing_policy(res); LASSERT(policy != NULL); LASSERT(req != NULL); @@ -141,8 +181,17 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, LASSERT(ns == ldlm_res_to_ns(res)); lock_res(res); - rc = policy(lock, &tmpflags, 0, &err, NULL); - check_res_locked(res); + + /* Check if this is a resend case (MSG_RESENT is set on RPC) and a + * lock was found by ldlm_handle_enqueue(); if so no need to grant + * it again. */ + if (flags & LDLM_FL_RESENT) { + rc = LDLM_ITER_CONTINUE; + } else { + __u64 tmpflags = 0; + rc = policy(lock, &tmpflags, 0, &err, NULL); + check_res_locked(res); + } /* The lock met with no resistance; we're finished. */ if (rc == LDLM_ITER_CONTINUE) { @@ -215,15 +264,15 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, } /* - * This check is for lock taken in ofd_prepare_destroy() that does + * This check is for lock taken in ofd_destroy_by_fid() that does * not have l_glimpse_ast set. So the logic is: if there is a lock * with no l_glimpse_ast set, this object is being destroyed already. * Hence, if you are grabbing DLM locks on the server, always set - * non-NULL glimpse_ast (e.g., ldlm_request.c:ldlm_glimpse_ast()). + * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()). */ if (l->l_glimpse_ast == NULL) { /* We are racing with unlink(); just return -ENOENT */ - rep->lock_policy_res1 = -ENOENT; + rep->lock_policy_res1 = ptlrpc_status_hton(-ENOENT); goto out; } @@ -233,13 +282,16 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, gl_work.gl_lock = LDLM_LOCK_GET(l); /* The glimpse callback is sent to one single extent lock. As a result, * the gl_work list is just composed of one element */ - cfs_list_add_tail(&gl_work.gl_list, &gl_list); + list_add_tail(&gl_work.gl_list, &gl_list); + /* There is actually no need for a glimpse descriptor when glimpsing + * extent locks */ + gl_work.gl_desc = NULL; /* the ldlm_glimpse_work structure is allocated on the stack */ gl_work.gl_flags = LDLM_GL_WORK_NOFREE; rc = ldlm_glimpse_locks(res, &gl_list); /* this will update the LVB */ - if (!cfs_list_empty(&gl_list)) + if (!list_empty(&gl_list)) LDLM_LOCK_RELEASE(l); lock_res(res);