*
* 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
*/
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2010, 2014, Intel Corporation.
+ * Copyright (c) 2010, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* This function looks for any conflicts for \a lock in the granted or
* waiting queues. The lock is granted if no conflicts are found in
* either queue.
- *
- * It is also responsible for splitting a lock if a portion of the lock
- * is released.
- *
- * If \a first_enq is 0 (ie, called from ldlm_reprocess_queue):
- * - blocking ASTs have already been sent
- *
- * If \a first_enq is 1 (ie, called from ldlm_lock_enqueue):
- * - blocking ASTs have not been sent yet, so list of conflicting locks
- * would be collected and ASTs sent.
*/
int
-ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq,
+ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags,
+ enum ldlm_process_intention intention,
enum ldlm_error *err, struct list_head *work_list)
{
struct ldlm_resource *res = req->l_resource;
int overlaps = 0;
int splitted = 0;
const struct ldlm_callback_suite null_cbs = { NULL };
+ struct list_head *grant_work = intention == LDLM_PROCESS_ENQUEUE ?
+ NULL : work_list;
ENTRY;
CDEBUG(D_DLMTRACE, "flags %#llx owner %llu pid %u mode %u start "
if (!ldlm_flocks_overlap(lock, req))
continue;
- if (!first_enq) {
+ if (intention != LDLM_PROCESS_ENQUEUE) {
reprocess_failed = 1;
if (ldlm_flock_deadlock(req, lock)) {
ldlm_flock_cancel_on_deadlock(req,
- work_list);
+ grant_work);
RETURN(LDLM_ITER_CONTINUE);
}
continue;
if (*flags != LDLM_FL_WAIT_NOREPROC) {
#ifdef HAVE_SERVER_SUPPORT
- if (first_enq) {
+ if (intention == LDLM_PROCESS_ENQUEUE) {
/* If this is an unlock, reprocess the waitq and
* send completions ASTs for locks that can now be
* granted. The only problem with doing this
* newly granted locks will be sent before the unlock
* completion is sent. It shouldn't be an issue. Also
* note that ldlm_process_flock_lock() will recurse,
- * but only once because first_enq will be false from
- * ldlm_reprocess_queue. */
+ * but only once because 'intention' won't be
+ * LDLM_PROCESS_ENQUEUE from ldlm_reprocess_queue. */
if ((mode == LCK_NL) && overlaps) {
struct list_head rpc_list;
int rc;
INIT_LIST_HEAD(&rpc_list);
restart:
- ldlm_reprocess_queue(res, &res->lr_waiting,
- &rpc_list);
+ ldlm_reprocess_queue(res, &res->lr_waiting,
+ &rpc_list,
+ LDLM_PROCESS_RESCAN, NULL);
unlock_res_and_lock(req);
rc = ldlm_run_ast_work(ns, &rpc_list,
}
} else {
LASSERT(req->l_completion_ast);
- ldlm_add_ast_work_item(req, NULL, work_list);
+ ldlm_add_ast_work_item(req, NULL, grant_work);
}
#else /* !HAVE_SERVER_SUPPORT */
/* The only one possible case for client-side calls flock
RETURN(-EIO);
}
- /* ldlm_lock_enqueue() has already placed lock on the granted list. */
+ /* ldlm_lock_enqueue() has already placed lock on the granted list. */
ldlm_resource_unlink_lock(lock);
/* Import invalidation. We need to actually release the lock
LASSERT(ldlm_is_test_lock(lock));
if (ldlm_is_test_lock(lock) || ldlm_is_flock_deadlock(lock))
- mode = flock_type(getlk);
+ mode = getlk->fl_type;
else
mode = lock->l_granted_mode;
LDLM_DEBUG(lock, "client-side enqueue granted");
if (flags & LDLM_FL_TEST_LOCK) {
- /* fcntl(F_GETLK) request */
- /* The old mode was saved in getlk->fl_type so that if the mode
- * in the lock changes we can decref the appropriate refcount.*/
+ /*
+ * fcntl(F_GETLK) request
+ * The old mode was saved in getlk->fl_type so that if the mode
+ * in the lock changes we can decref the appropriate refcount.
+ */
LASSERT(ldlm_is_test_lock(lock));
- ldlm_flock_destroy(lock, flock_type(getlk),
- LDLM_FL_WAIT_NOREPROC);
+ ldlm_flock_destroy(lock, getlk->fl_type, LDLM_FL_WAIT_NOREPROC);
switch (lock->l_granted_mode) {
case LCK_PR:
- flock_set_type(getlk, F_RDLCK);
+ getlk->fl_type = F_RDLCK;
break;
case LCK_PW:
- flock_set_type(getlk, F_WRLCK);
+ getlk->fl_type = F_WRLCK;
break;
default:
- flock_set_type(getlk, F_UNLCK);
+ getlk->fl_type = F_UNLCK;
}
- flock_set_pid(getlk, (pid_t)lock->l_policy_data.l_flock.pid);
- flock_set_start(getlk,
- (loff_t)lock->l_policy_data.l_flock.start);
- flock_set_end(getlk,
- (loff_t)lock->l_policy_data.l_flock.end);
+ getlk->fl_pid = (pid_t)lock->l_policy_data.l_flock.pid;
+ getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start;
+ getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end;
} else {
__u64 noreproc = LDLM_FL_WAIT_NOREPROC;