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