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