Home | History | Annotate | Line # | Download | only in kern
vfs_lockf.c revision 1.36
      1 /*	$NetBSD: vfs_lockf.c,v 1.36 2004/11/19 14:18:53 peter Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1982, 1986, 1989, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Scooter Morris at Genentech Inc.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  *
     34  *	@(#)ufs_lockf.c	8.4 (Berkeley) 10/26/94
     35  */
     36 
     37 #include <sys/cdefs.h>
     38 __KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.36 2004/11/19 14:18:53 peter Exp $");
     39 
     40 #include <sys/param.h>
     41 #include <sys/systm.h>
     42 #include <sys/kernel.h>
     43 #include <sys/file.h>
     44 #include <sys/proc.h>
     45 #include <sys/vnode.h>
     46 #include <sys/pool.h>
     47 #include <sys/fcntl.h>
     48 #include <sys/lockf.h>
     49 
     50 POOL_INIT(lockfpool, sizeof(struct lockf), 0, 0, 0, "lockfpl",
     51     &pool_allocator_nointr);
     52 
     53 /*
     54  * This variable controls the maximum number of processes that will
     55  * be checked in doing deadlock detection.
     56  */
     57 int maxlockdepth = MAXDEPTH;
     58 
     59 #ifdef LOCKF_DEBUG
     60 int	lockf_debug = 0;
     61 #endif
     62 
     63 #define NOLOCKF (struct lockf *)0
     64 #define SELF	0x1
     65 #define OTHERS	0x2
     66 
     67 static int lf_clearlock(struct lockf *, struct lockf **);
     68 static int lf_findoverlap(struct lockf *,
     69 	    struct lockf *, int, struct lockf ***, struct lockf **);
     70 static struct lockf *lf_getblock(struct lockf *);
     71 static int lf_getlock(struct lockf *, struct flock *);
     72 static int lf_setlock(struct lockf *, struct lockf **, struct simplelock *);
     73 static void lf_split(struct lockf *, struct lockf *, struct lockf **);
     74 static void lf_wakelock(struct lockf *);
     75 
     76 #ifdef LOCKF_DEBUG
     77 static void lf_print(char *, struct lockf *);
     78 static void lf_printlist(char *, struct lockf *);
     79 #endif
     80 
     81 /*
     82  * XXX TODO
     83  * Misc cleanups: "caddr_t id" should be visible in the API as a
     84  * "struct proc *".
     85  * (This requires rototilling all VFS's which support advisory locking).
     86  */
     87 
     88 /*
     89  * If there's a lot of lock contention on a single vnode, locking
     90  * schemes which allow for more paralleism would be needed.  Given how
     91  * infrequently byte-range locks are actually used in typical BSD
     92  * code, a more complex approach probably isn't worth it.
     93  */
     94 
     95 /*
     96  * Do an advisory lock operation.
     97  */
     98 int
     99 lf_advlock(struct vop_advlock_args *ap, struct lockf **head, off_t size)
    100 {
    101 	struct flock *fl = ap->a_fl;
    102 	struct lockf *lock = NULL;
    103 	struct lockf *sparelock;
    104 	struct simplelock *interlock = &ap->a_vp->v_interlock;
    105 	off_t start, end;
    106 	int error = 0;
    107 
    108 	/*
    109 	 * Convert the flock structure into a start and end.
    110 	 */
    111 	switch (fl->l_whence) {
    112 	case SEEK_SET:
    113 	case SEEK_CUR:
    114 		/*
    115 		 * Caller is responsible for adding any necessary offset
    116 		 * when SEEK_CUR is used.
    117 		 */
    118 		start = fl->l_start;
    119 		break;
    120 
    121 	case SEEK_END:
    122 		start = size + fl->l_start;
    123 		break;
    124 
    125 	default:
    126 		return EINVAL;
    127 	}
    128 	if (start < 0)
    129 		return EINVAL;
    130 
    131 	/*
    132 	 * allocate locks before acquire simple lock.
    133 	 * we need two locks in the worst case.
    134 	 */
    135 	switch (ap->a_op) {
    136 	case F_SETLK:
    137 	case F_UNLCK:
    138 		/*
    139 		 * XXX for F_UNLCK case, we can re-use lock.
    140 		 */
    141 		if ((fl->l_type & F_FLOCK) == 0) {
    142 			/*
    143 			 * byte-range lock might need one more lock.
    144 			 */
    145 			sparelock = pool_get(&lockfpool, PR_WAITOK);
    146 			if (sparelock == NULL) {
    147 				error = ENOMEM;
    148 				goto quit;
    149 			}
    150 			break;
    151 		}
    152 		/* FALLTHROUGH */
    153 
    154 	case F_GETLK:
    155 		sparelock = NULL;
    156 		break;
    157 
    158 	default:
    159 		return EINVAL;
    160 	}
    161 
    162 	lock = pool_get(&lockfpool, PR_WAITOK);
    163 	if (lock == NULL) {
    164 		error = ENOMEM;
    165 		goto quit;
    166 	}
    167 
    168 	simple_lock(interlock);
    169 
    170 	/*
    171 	 * Avoid the common case of unlocking when inode has no locks.
    172 	 */
    173 	if (*head == (struct lockf *)0) {
    174 		if (ap->a_op != F_SETLK) {
    175 			fl->l_type = F_UNLCK;
    176 			error = 0;
    177 			goto quit_unlock;
    178 		}
    179 	}
    180 
    181 	if (fl->l_len == 0)
    182 		end = -1;
    183 	else
    184 		end = start + fl->l_len - 1;
    185 	/*
    186 	 * Create the lockf structure.
    187 	 */
    188 	lock->lf_start = start;
    189 	lock->lf_end = end;
    190 	/* XXX NJWLWP
    191 	 * I don't want to make the entire VFS universe use LWPs, because
    192 	 * they don't need them, for the most part. This is an exception,
    193 	 * and a kluge.
    194 	 */
    195 
    196 	lock->lf_head = head;
    197 	lock->lf_type = fl->l_type;
    198 	lock->lf_next = (struct lockf *)0;
    199 	TAILQ_INIT(&lock->lf_blkhd);
    200 	lock->lf_flags = ap->a_flags;
    201 	if (lock->lf_flags & F_POSIX) {
    202 		KASSERT(curproc == (struct proc *)ap->a_id);
    203 	}
    204 	lock->lf_id = (struct proc *)ap->a_id;
    205 	lock->lf_lwp = curlwp;
    206 
    207 	/*
    208 	 * Do the requested operation.
    209 	 */
    210 	switch (ap->a_op) {
    211 
    212 	case F_SETLK:
    213 		error = lf_setlock(lock, &sparelock, interlock);
    214 		lock = NULL; /* lf_setlock freed it */
    215 		break;
    216 
    217 	case F_UNLCK:
    218 		error = lf_clearlock(lock, &sparelock);
    219 		break;
    220 
    221 	case F_GETLK:
    222 		error = lf_getlock(lock, fl);
    223 		break;
    224 
    225 	default:
    226 		break;
    227 		/* NOTREACHED */
    228 	}
    229 
    230 quit_unlock:
    231 	simple_unlock(interlock);
    232 quit:
    233 	if (lock)
    234 		pool_put(&lockfpool, lock);
    235 	if (sparelock)
    236 		pool_put(&lockfpool, sparelock);
    237 
    238 	return error;
    239 }
    240 
    241 /*
    242  * Set a byte-range lock.
    243  */
    244 static int
    245 lf_setlock(struct lockf *lock, struct lockf **sparelock,
    246     struct simplelock *interlock)
    247 {
    248 	struct lockf *block;
    249 	struct lockf **head = lock->lf_head;
    250 	struct lockf **prev, *overlap, *ltmp;
    251 	static char lockstr[] = "lockf";
    252 	int ovcase, priority, needtolink, error;
    253 
    254 #ifdef LOCKF_DEBUG
    255 	if (lockf_debug & 1)
    256 		lf_print("lf_setlock", lock);
    257 #endif /* LOCKF_DEBUG */
    258 
    259 	/*
    260 	 * Set the priority
    261 	 */
    262 	priority = PLOCK;
    263 	if (lock->lf_type == F_WRLCK)
    264 		priority += 4;
    265 	priority |= PCATCH;
    266 	/*
    267 	 * Scan lock list for this file looking for locks that would block us.
    268 	 */
    269 	while ((block = lf_getblock(lock)) != NULL) {
    270 		/*
    271 		 * Free the structure and return if nonblocking.
    272 		 */
    273 		if ((lock->lf_flags & F_WAIT) == 0) {
    274 			pool_put(&lockfpool, lock);
    275 			return EAGAIN;
    276 		}
    277 		/*
    278 		 * We are blocked. Since flock style locks cover
    279 		 * the whole file, there is no chance for deadlock.
    280 		 * For byte-range locks we must check for deadlock.
    281 		 *
    282 		 * Deadlock detection is done by looking through the
    283 		 * wait channels to see if there are any cycles that
    284 		 * involve us. MAXDEPTH is set just to make sure we
    285 		 * do not go off into neverneverland.
    286 		 */
    287 		if ((lock->lf_flags & F_POSIX) &&
    288 		    (block->lf_flags & F_POSIX)) {
    289 			struct lwp *wlwp;
    290 			struct lockf *waitblock;
    291 			int i = 0;
    292 
    293 			/*
    294 			 * The block is waiting on something.  if_lwp will be
    295 			 * 0 once the lock is granted, so we terminate the
    296 			 * loop if we find this.
    297 			 */
    298 			wlwp = block->lf_lwp;
    299 			while (wlwp && (i++ < maxlockdepth)) {
    300 				waitblock = (struct lockf *)wlwp->l_wchan;
    301 				/* Get the owner of the blocking lock */
    302 				waitblock = waitblock->lf_next;
    303 				if ((waitblock->lf_flags & F_POSIX) == 0)
    304 					break;
    305 				wlwp = waitblock->lf_lwp;
    306 				if (wlwp == lock->lf_lwp) {
    307 					pool_put(&lockfpool, lock);
    308 					return EDEADLK;
    309 				}
    310 			}
    311 			/*
    312 			 * If we're still following a dependency chain
    313 			 * after maxlockdepth iterations, assume we're in
    314 			 * a cycle to be safe.
    315 			 */
    316 			if (i >= maxlockdepth) {
    317 				pool_put(&lockfpool, lock);
    318 				return EDEADLK;
    319 			}
    320 		}
    321 		/*
    322 		 * For flock type locks, we must first remove
    323 		 * any shared locks that we hold before we sleep
    324 		 * waiting for an exclusive lock.
    325 		 */
    326 		if ((lock->lf_flags & F_FLOCK) &&
    327 		    lock->lf_type == F_WRLCK) {
    328 			lock->lf_type = F_UNLCK;
    329 			(void) lf_clearlock(lock, NULL);
    330 			lock->lf_type = F_WRLCK;
    331 		}
    332 		/*
    333 		 * Add our lock to the blocked list and sleep until we're free.
    334 		 * Remember who blocked us (for deadlock detection).
    335 		 */
    336 		lock->lf_next = block;
    337 		TAILQ_INSERT_TAIL(&block->lf_blkhd, lock, lf_block);
    338 #ifdef LOCKF_DEBUG
    339 		if (lockf_debug & 1) {
    340 			lf_print("lf_setlock: blocking on", block);
    341 			lf_printlist("lf_setlock", block);
    342 		}
    343 #endif /* LOCKF_DEBUG */
    344 		error = ltsleep(lock, priority, lockstr, 0, interlock);
    345 
    346 		/*
    347 		 * We may have been awakened by a signal (in
    348 		 * which case we must remove ourselves from the
    349 		 * blocked list) and/or by another process
    350 		 * releasing a lock (in which case we have already
    351 		 * been removed from the blocked list and our
    352 		 * lf_next field set to NOLOCKF).
    353 		 */
    354 		if (lock->lf_next != NOLOCKF) {
    355 			TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block);
    356 			lock->lf_next = NOLOCKF;
    357 		}
    358 		if (error) {
    359 			pool_put(&lockfpool, lock);
    360 			return error;
    361 		}
    362 	}
    363 	/*
    364 	 * No blocks!!  Add the lock.  Note that we will
    365 	 * downgrade or upgrade any overlapping locks this
    366 	 * process already owns.
    367 	 *
    368 	 * Skip over locks owned by other processes.
    369 	 * Handle any locks that overlap and are owned by ourselves.
    370 	 */
    371 	lock->lf_lwp = 0;
    372 	prev = head;
    373 	block = *head;
    374 	needtolink = 1;
    375 	for (;;) {
    376 		ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap);
    377 		if (ovcase)
    378 			block = overlap->lf_next;
    379 		/*
    380 		 * Six cases:
    381 		 *	0) no overlap
    382 		 *	1) overlap == lock
    383 		 *	2) overlap contains lock
    384 		 *	3) lock contains overlap
    385 		 *	4) overlap starts before lock
    386 		 *	5) overlap ends after lock
    387 		 */
    388 		switch (ovcase) {
    389 		case 0: /* no overlap */
    390 			if (needtolink) {
    391 				*prev = lock;
    392 				lock->lf_next = overlap;
    393 			}
    394 			break;
    395 
    396 		case 1: /* overlap == lock */
    397 			/*
    398 			 * If downgrading lock, others may be
    399 			 * able to acquire it.
    400 			 */
    401 			if (lock->lf_type == F_RDLCK &&
    402 			    overlap->lf_type == F_WRLCK)
    403 				lf_wakelock(overlap);
    404 			overlap->lf_type = lock->lf_type;
    405 			pool_put(&lockfpool, lock);
    406 			lock = overlap; /* for debug output below */
    407 			break;
    408 
    409 		case 2: /* overlap contains lock */
    410 			/*
    411 			 * Check for common starting point and different types.
    412 			 */
    413 			if (overlap->lf_type == lock->lf_type) {
    414 				pool_put(&lockfpool, lock);
    415 				lock = overlap; /* for debug output below */
    416 				break;
    417 			}
    418 			if (overlap->lf_start == lock->lf_start) {
    419 				*prev = lock;
    420 				lock->lf_next = overlap;
    421 				overlap->lf_start = lock->lf_end + 1;
    422 			} else
    423 				lf_split(overlap, lock, sparelock);
    424 			lf_wakelock(overlap);
    425 			break;
    426 
    427 		case 3: /* lock contains overlap */
    428 			/*
    429 			 * If downgrading lock, others may be able to
    430 			 * acquire it, otherwise take the list.
    431 			 */
    432 			if (lock->lf_type == F_RDLCK &&
    433 			    overlap->lf_type == F_WRLCK) {
    434 				lf_wakelock(overlap);
    435 			} else {
    436 				while ((ltmp = TAILQ_FIRST(&overlap->lf_blkhd))) {
    437 					KASSERT(ltmp->lf_next == overlap);
    438 					TAILQ_REMOVE(&overlap->lf_blkhd, ltmp,
    439 					    lf_block);
    440 					ltmp->lf_next = lock;
    441 					TAILQ_INSERT_TAIL(&lock->lf_blkhd,
    442 					    ltmp, lf_block);
    443 				}
    444 			}
    445 			/*
    446 			 * Add the new lock if necessary and delete the overlap.
    447 			 */
    448 			if (needtolink) {
    449 				*prev = lock;
    450 				lock->lf_next = overlap->lf_next;
    451 				prev = &lock->lf_next;
    452 				needtolink = 0;
    453 			} else
    454 				*prev = overlap->lf_next;
    455 			pool_put(&lockfpool, overlap);
    456 			continue;
    457 
    458 		case 4: /* overlap starts before lock */
    459 			/*
    460 			 * Add lock after overlap on the list.
    461 			 */
    462 			lock->lf_next = overlap->lf_next;
    463 			overlap->lf_next = lock;
    464 			overlap->lf_end = lock->lf_start - 1;
    465 			prev = &lock->lf_next;
    466 			lf_wakelock(overlap);
    467 			needtolink = 0;
    468 			continue;
    469 
    470 		case 5: /* overlap ends after lock */
    471 			/*
    472 			 * Add the new lock before overlap.
    473 			 */
    474 			if (needtolink) {
    475 				*prev = lock;
    476 				lock->lf_next = overlap;
    477 			}
    478 			overlap->lf_start = lock->lf_end + 1;
    479 			lf_wakelock(overlap);
    480 			break;
    481 		}
    482 		break;
    483 	}
    484 #ifdef LOCKF_DEBUG
    485 	if (lockf_debug & 1) {
    486 		lf_print("lf_setlock: got the lock", lock);
    487 		lf_printlist("lf_setlock", lock);
    488 	}
    489 #endif /* LOCKF_DEBUG */
    490 	return 0;
    491 }
    492 
    493 /*
    494  * Remove a byte-range lock on an inode.
    495  *
    496  * Generally, find the lock (or an overlap to that lock)
    497  * and remove it (or shrink it), then wakeup anyone we can.
    498  */
    499 static int
    500 lf_clearlock(struct lockf *unlock, struct lockf **sparelock)
    501 {
    502 	struct lockf **head = unlock->lf_head;
    503 	struct lockf *lf = *head;
    504 	struct lockf *overlap, **prev;
    505 	int ovcase;
    506 
    507 	if (lf == NOLOCKF)
    508 		return 0;
    509 #ifdef LOCKF_DEBUG
    510 	if (unlock->lf_type != F_UNLCK)
    511 		panic("lf_clearlock: bad type");
    512 	if (lockf_debug & 1)
    513 		lf_print("lf_clearlock", unlock);
    514 #endif /* LOCKF_DEBUG */
    515 	prev = head;
    516 	while ((ovcase = lf_findoverlap(lf, unlock, SELF,
    517 					&prev, &overlap)) != 0) {
    518 		/*
    519 		 * Wakeup the list of locks to be retried.
    520 		 */
    521 		lf_wakelock(overlap);
    522 
    523 		switch (ovcase) {
    524 
    525 		case 1: /* overlap == lock */
    526 			*prev = overlap->lf_next;
    527 			pool_put(&lockfpool, overlap);
    528 			break;
    529 
    530 		case 2: /* overlap contains lock: split it */
    531 			if (overlap->lf_start == unlock->lf_start) {
    532 				overlap->lf_start = unlock->lf_end + 1;
    533 				break;
    534 			}
    535 			lf_split(overlap, unlock, sparelock);
    536 			overlap->lf_next = unlock->lf_next;
    537 			break;
    538 
    539 		case 3: /* lock contains overlap */
    540 			*prev = overlap->lf_next;
    541 			lf = overlap->lf_next;
    542 			pool_put(&lockfpool, overlap);
    543 			continue;
    544 
    545 		case 4: /* overlap starts before lock */
    546 			overlap->lf_end = unlock->lf_start - 1;
    547 			prev = &overlap->lf_next;
    548 			lf = overlap->lf_next;
    549 			continue;
    550 
    551 		case 5: /* overlap ends after lock */
    552 			overlap->lf_start = unlock->lf_end + 1;
    553 			break;
    554 		}
    555 		break;
    556 	}
    557 #ifdef LOCKF_DEBUG
    558 	if (lockf_debug & 1)
    559 		lf_printlist("lf_clearlock", unlock);
    560 #endif /* LOCKF_DEBUG */
    561 	return 0;
    562 }
    563 
    564 /*
    565  * Check whether there is a blocking lock,
    566  * and if so return its process identifier.
    567  */
    568 static int
    569 lf_getlock(struct lockf *lock, struct flock *fl)
    570 {
    571 	struct lockf *block;
    572 
    573 #ifdef LOCKF_DEBUG
    574 	if (lockf_debug & 1)
    575 		lf_print("lf_getlock", lock);
    576 #endif /* LOCKF_DEBUG */
    577 
    578 	if ((block = lf_getblock(lock)) != NULL) {
    579 		fl->l_type = block->lf_type;
    580 		fl->l_whence = SEEK_SET;
    581 		fl->l_start = block->lf_start;
    582 		if (block->lf_end == -1)
    583 			fl->l_len = 0;
    584 		else
    585 			fl->l_len = block->lf_end - block->lf_start + 1;
    586 		if (block->lf_flags & F_POSIX)
    587 			fl->l_pid = ((struct proc *)block->lf_id)->p_pid;
    588 		else
    589 			fl->l_pid = -1;
    590 	} else {
    591 		fl->l_type = F_UNLCK;
    592 	}
    593 	return 0;
    594 }
    595 
    596 /*
    597  * Walk the list of locks for an inode and
    598  * return the first blocking lock.
    599  */
    600 static struct lockf *
    601 lf_getblock(struct lockf *lock)
    602 {
    603 	struct lockf **prev, *overlap, *lf = *(lock->lf_head);
    604 
    605 	prev = lock->lf_head;
    606 	while (lf_findoverlap(lf, lock, OTHERS, &prev, &overlap) != 0) {
    607 		/*
    608 		 * We've found an overlap, see if it blocks us
    609 		 */
    610 		if ((lock->lf_type == F_WRLCK || overlap->lf_type == F_WRLCK))
    611 			return overlap;
    612 		/*
    613 		 * Nope, point to the next one on the list and
    614 		 * see if it blocks us
    615 		 */
    616 		lf = overlap->lf_next;
    617 	}
    618 	return NOLOCKF;
    619 }
    620 
    621 /*
    622  * Walk the list of locks for an inode to
    623  * find an overlapping lock (if any).
    624  *
    625  * NOTE: this returns only the FIRST overlapping lock.  There
    626  *	 may be more than one.
    627  */
    628 static int
    629 lf_findoverlap(struct lockf *lf, struct lockf *lock, int type,
    630     struct lockf ***prev, struct lockf **overlap)
    631 {
    632 	off_t start, end;
    633 
    634 	*overlap = lf;
    635 	if (lf == NOLOCKF)
    636 		return 0;
    637 #ifdef LOCKF_DEBUG
    638 	if (lockf_debug & 2)
    639 		lf_print("lf_findoverlap: looking for overlap in", lock);
    640 #endif /* LOCKF_DEBUG */
    641 	start = lock->lf_start;
    642 	end = lock->lf_end;
    643 	while (lf != NOLOCKF) {
    644 		if (((type == SELF) && lf->lf_id != lock->lf_id) ||
    645 		    ((type == OTHERS) && lf->lf_id == lock->lf_id)) {
    646 			*prev = &lf->lf_next;
    647 			*overlap = lf = lf->lf_next;
    648 			continue;
    649 		}
    650 #ifdef LOCKF_DEBUG
    651 		if (lockf_debug & 2)
    652 			lf_print("\tchecking", lf);
    653 #endif /* LOCKF_DEBUG */
    654 		/*
    655 		 * OK, check for overlap
    656 		 *
    657 		 * Six cases:
    658 		 *	0) no overlap
    659 		 *	1) overlap == lock
    660 		 *	2) overlap contains lock
    661 		 *	3) lock contains overlap
    662 		 *	4) overlap starts before lock
    663 		 *	5) overlap ends after lock
    664 		 */
    665 		if ((lf->lf_end != -1 && start > lf->lf_end) ||
    666 		    (end != -1 && lf->lf_start > end)) {
    667 			/* Case 0 */
    668 #ifdef LOCKF_DEBUG
    669 			if (lockf_debug & 2)
    670 				printf("no overlap\n");
    671 #endif /* LOCKF_DEBUG */
    672 			if ((type & SELF) && end != -1 && lf->lf_start > end)
    673 				return 0;
    674 			*prev = &lf->lf_next;
    675 			*overlap = lf = lf->lf_next;
    676 			continue;
    677 		}
    678 		if ((lf->lf_start == start) && (lf->lf_end == end)) {
    679 			/* Case 1 */
    680 #ifdef LOCKF_DEBUG
    681 			if (lockf_debug & 2)
    682 				printf("overlap == lock\n");
    683 #endif /* LOCKF_DEBUG */
    684 			return 1;
    685 		}
    686 		if ((lf->lf_start <= start) &&
    687 		    (end != -1) &&
    688 		    ((lf->lf_end >= end) || (lf->lf_end == -1))) {
    689 			/* Case 2 */
    690 #ifdef LOCKF_DEBUG
    691 			if (lockf_debug & 2)
    692 				printf("overlap contains lock\n");
    693 #endif /* LOCKF_DEBUG */
    694 			return 2;
    695 		}
    696 		if (start <= lf->lf_start &&
    697 		           (end == -1 ||
    698 			   (lf->lf_end != -1 && end >= lf->lf_end))) {
    699 			/* Case 3 */
    700 #ifdef LOCKF_DEBUG
    701 			if (lockf_debug & 2)
    702 				printf("lock contains overlap\n");
    703 #endif /* LOCKF_DEBUG */
    704 			return 3;
    705 		}
    706 		if ((lf->lf_start < start) &&
    707 			((lf->lf_end >= start) || (lf->lf_end == -1))) {
    708 			/* Case 4 */
    709 #ifdef LOCKF_DEBUG
    710 			if (lockf_debug & 2)
    711 				printf("overlap starts before lock\n");
    712 #endif /* LOCKF_DEBUG */
    713 			return 4;
    714 		}
    715 		if ((lf->lf_start > start) &&
    716 			(end != -1) &&
    717 			((lf->lf_end > end) || (lf->lf_end == -1))) {
    718 			/* Case 5 */
    719 #ifdef LOCKF_DEBUG
    720 			if (lockf_debug & 2)
    721 				printf("overlap ends after lock\n");
    722 #endif /* LOCKF_DEBUG */
    723 			return 5;
    724 		}
    725 		panic("lf_findoverlap: default");
    726 	}
    727 	return 0;
    728 }
    729 
    730 /*
    731  * Split a lock and a contained region into
    732  * two or three locks as necessary.
    733  */
    734 static void
    735 lf_split(struct lockf *lock1, struct lockf *lock2, struct lockf **sparelock)
    736 {
    737 	struct lockf *splitlock;
    738 
    739 #ifdef LOCKF_DEBUG
    740 	if (lockf_debug & 2) {
    741 		lf_print("lf_split", lock1);
    742 		lf_print("splitting from", lock2);
    743 	}
    744 #endif /* LOCKF_DEBUG */
    745 	/*
    746 	 * Check to see if spliting into only two pieces.
    747 	 */
    748 	if (lock1->lf_start == lock2->lf_start) {
    749 		lock1->lf_start = lock2->lf_end + 1;
    750 		lock2->lf_next = lock1;
    751 		return;
    752 	}
    753 	if (lock1->lf_end == lock2->lf_end) {
    754 		lock1->lf_end = lock2->lf_start - 1;
    755 		lock2->lf_next = lock1->lf_next;
    756 		lock1->lf_next = lock2;
    757 		return;
    758 	}
    759 	/*
    760 	 * Make a new lock consisting of the last part of
    761 	 * the encompassing lock
    762 	 */
    763 	splitlock = *sparelock;
    764 	*sparelock = NULL;
    765 	memcpy(splitlock, lock1, sizeof(*splitlock));
    766 	splitlock->lf_start = lock2->lf_end + 1;
    767 	TAILQ_INIT(&splitlock->lf_blkhd);
    768 	lock1->lf_end = lock2->lf_start - 1;
    769 	/*
    770 	 * OK, now link it in
    771 	 */
    772 	splitlock->lf_next = lock1->lf_next;
    773 	lock2->lf_next = splitlock;
    774 	lock1->lf_next = lock2;
    775 }
    776 
    777 /*
    778  * Wakeup a blocklist
    779  */
    780 static void
    781 lf_wakelock(struct lockf *listhead)
    782 {
    783 	struct lockf *wakelock;
    784 
    785 	while ((wakelock = TAILQ_FIRST(&listhead->lf_blkhd))) {
    786 		KASSERT(wakelock->lf_next == listhead);
    787 		TAILQ_REMOVE(&listhead->lf_blkhd, wakelock, lf_block);
    788 		wakelock->lf_next = NOLOCKF;
    789 #ifdef LOCKF_DEBUG
    790 		if (lockf_debug & 2)
    791 			lf_print("lf_wakelock: awakening", wakelock);
    792 #endif
    793 		wakeup(wakelock);
    794 	}
    795 }
    796 
    797 #ifdef LOCKF_DEBUG
    798 /*
    799  * Print out a lock.
    800  */
    801 static void
    802 lf_print(char *tag, struct lockf *lock)
    803 {
    804 
    805 	printf("%s: lock %p for ", tag, lock);
    806 	if (lock->lf_flags & F_POSIX)
    807 		printf("proc %d", ((struct proc *)lock->lf_id)->p_pid);
    808 	else
    809 		printf("file 0x%p", (struct file *)lock->lf_id);
    810 	printf(" %s, start %qx, end %qx",
    811 		lock->lf_type == F_RDLCK ? "shared" :
    812 		lock->lf_type == F_WRLCK ? "exclusive" :
    813 		lock->lf_type == F_UNLCK ? "unlock" :
    814 		"unknown", lock->lf_start, lock->lf_end);
    815 	if (TAILQ_FIRST(&lock->lf_blkhd))
    816 		printf(" block %p\n", TAILQ_FIRST(&lock->lf_blkhd));
    817 	else
    818 		printf("\n");
    819 }
    820 
    821 static void
    822 lf_printlist(char *tag, struct lockf *lock)
    823 {
    824 	struct lockf *lf, *blk;
    825 
    826 	printf("%s: Lock list:\n", tag);
    827 	for (lf = *lock->lf_head; lf; lf = lf->lf_next) {
    828 		printf("\tlock %p for ", lf);
    829 		if (lf->lf_flags & F_POSIX)
    830 			printf("proc %d", ((struct proc *)lf->lf_id)->p_pid);
    831 		else
    832 			printf("file 0x%p", (struct file *)lf->lf_id);
    833 		printf(", %s, start %qx, end %qx",
    834 			lf->lf_type == F_RDLCK ? "shared" :
    835 			lf->lf_type == F_WRLCK ? "exclusive" :
    836 			lf->lf_type == F_UNLCK ? "unlock" :
    837 			"unknown", lf->lf_start, lf->lf_end);
    838 		TAILQ_FOREACH(blk, &lf->lf_blkhd, lf_block) {
    839 			if (blk->lf_flags & F_POSIX)
    840 				printf("proc %d",
    841 				    ((struct proc *)blk->lf_id)->p_pid);
    842 			else
    843 				printf("file 0x%p", (struct file *)blk->lf_id);
    844 			printf(", %s, start %qx, end %qx",
    845 				blk->lf_type == F_RDLCK ? "shared" :
    846 				blk->lf_type == F_WRLCK ? "exclusive" :
    847 				blk->lf_type == F_UNLCK ? "unlock" :
    848 				"unknown", blk->lf_start, blk->lf_end);
    849 			if (TAILQ_FIRST(&blk->lf_blkhd))
    850 				 panic("lf_printlist: bad list");
    851 		}
    852 		printf("\n");
    853 	}
    854 }
    855 #endif /* LOCKF_DEBUG */
    856