FreeBSD/sys/kern/kern_lockf.c
/*
 * Split an the existing 'lock1', based on the extent of the lock
 * described by 'lock2'. The existing lock should cover 'lock2'
 * entirely.
 *
 * Any pending locks which have been been unblocked are added to
 * 'granted'
 */
Split an the existing 'lock1', based on the extent of the lock
described by 'lock2'. The existing lock should cover 'lock2'
entirely.

Any pending locks which have been been unblocked are added to
'granted'
Split an the existing ' lock1 ' based on the extent of the lock described by ' lock2 ' . The existing lock should cover ' lock2 ' entirely . Any pending locks which have been been unblocked are added to ' granted '
static void
lf_split(struct lockf *state, struct lockf_entry *lock1,
    struct lockf_entry *lock2, struct lockf_entry_list *granted)
{
	struct lockf_entry *splitlock;
#ifdef LOCKF_DEBUG
	if (lockf_debug & 2) {
		lf_print("lf_split", lock1);
		lf_print("splitting from", lock2);
	}
#endif 
	if (lock1->lf_start == lock2->lf_start) {
		lf_set_start(state, lock1, lock2->lf_end + 1, granted);
		return;
	}
	if (lock1->lf_end == lock2->lf_end) {
		lf_set_end(state, lock1, lock2->lf_start - 1, granted);
		return;
	}
	splitlock = lf_alloc_lock(lock1->lf_owner);
	memcpy(splitlock, lock1, sizeof *splitlock);
	splitlock->lf_refs = 1;
	if (splitlock->lf_flags & F_REMOTE)
		vref(splitlock->lf_vnode);
	splitlock->lf_start = lock2->lf_end + 1;
	LIST_INIT(&splitlock->lf_outedges);
	LIST_INIT(&splitlock->lf_inedges);
	sx_xlock(&lf_owner_graph_lock);
	lf_add_incoming(state, splitlock);
	sx_xunlock(&lf_owner_graph_lock);
	lf_set_end(state, lock1, lock2->lf_start - 1, granted);
	lf_insert_lock(state, splitlock);
}
static void lf_split ( struct lockf * state , struct lockf_entry * lock1 , struct lockf_entry * lock2 , struct lockf_entry_list * granted ) { struct lockf_entry * splitlock ; #ifdef LOCKF_DEBUG if ( lockf_debug & 2 ) { lf_print ( " " , lock1 ) ; lf_print ( " " , lock2 ) ; } #endif if ( lock1 -> lf_start == lock2 -> lf_start ) { lf_set_start ( state , lock1 , lock2 -> lf_end + 1 , granted ) ; return ; } if ( lock1 -> lf_end == lock2 -> lf_end ) { lf_set_end ( state , lock1 , lock2 -> lf_start - 1 , granted ) ; return ; } splitlock = lf_alloc_lock ( lock1 -> lf_owner ) ; memcpy ( splitlock , lock1 , sizeof * splitlock ) ; splitlock -> lf_refs = 1 ; if ( splitlock -> lf_flags & F_REMOTE ) vref ( splitlock -> lf_vnode ) ; splitlock -> lf_start = lock2 -> lf_end + 1 ; LIST_INIT ( & splitlock -> lf_outedges ) ; LIST_INIT ( & splitlock -> lf_inedges ) ; sx_xlock ( & lf_owner_graph_lock ) ; lf_add_incoming ( state , splitlock ) ; sx_xunlock ( & lf_owner_graph_lock ) ; lf_set_end ( state , lock1 , lock2 -> lf_start - 1 , granted ) ; lf_insert_lock ( state , splitlock ) ; }
Split an the existing 'lock1', based on the extent of the lock
 described by 'lock2'.
Split an the existing ' lock1 ' based on the extent of the lock described by ' lock2 ' .
/* LOCKF_DEBUG */ /*
	 * Check to see if we don't need to split at all.
	 */ /*
	 * Make a new lock consisting of the last part of
	 * the encompassing lock.
	 */ /*
	 * This cannot cause a deadlock since any edges we would add
	 * to splitlock already exist in lock1. We must be sure to add
	 * necessary dependencies to splitlock before we reduce lock1
	 * otherwise we may accidentally grant a pending lock that
	 * was blocked by the tail end of lock1.
	 */ /*
	 * OK, now link it in
	 */