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