summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lockf.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
committerdyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
commit10f666af84d48e89e4e2960415c9b616fce4077f (patch)
tree88a944de263165091f0a18abeedbaaccec532407 /sys/kern/kern_lockf.c
parent0960d7e91af3428ffba89b42228d82d8afaa0389 (diff)
downloadFreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.zip
FreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.tar.gz
This is the kernel Lite/2 commit. There are some requisite userland
changes, so don't expect to be able to run the kernel as-is (very well) without the appropriate Lite/2 userland changes. The system boots and can mount UFS filesystems. Untested: ext2fs, msdosfs, NFS Known problems: Incorrect Berkeley ID strings in some files. Mount_std mounts will not work until the getfsent library routine is changed. Reviewed by: various people Submitted by: Jeffery Hsu <hsu@freebsd.org>
Diffstat (limited to 'sys/kern/kern_lockf.c')
-rw-r--r--sys/kern/kern_lockf.c123
1 files changed, 54 insertions, 69 deletions
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
index aea3976..3491e63 100644
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -52,16 +52,18 @@
* This variable controls the maximum number of processes that will
* be checked in doing deadlock detection.
*/
-int maxlockdepth = MAXDEPTH;
+static int maxlockdepth = MAXDEPTH;
#ifdef LOCKF_DEBUG
+#include <vm/vm.h>
+#include <sys/sysctl.h>
int lockf_debug = 0;
+SYSCTL_INT(_debug, 4, lockf_debug, CTLFLAG_RW, &lockf_debug, 0, "");
#endif
#define NOLOCKF (struct lockf *)0
#define SELF 0x1
#define OTHERS 0x2
-static void lf_addblock __P((struct lockf *, struct lockf *));
static int lf_clearlock __P((struct lockf *));
static int lf_findoverlap __P((struct lockf *,
struct lockf *, int, struct lockf ***, struct lockf **));
@@ -138,10 +140,11 @@ lf_advlock(ap, head, size)
lock->lf_start = start;
lock->lf_end = end;
lock->lf_id = ap->a_id;
- lock->lf_head = head;
+/* lock->lf_inode = ip; */ /* XXX JH */
lock->lf_type = fl->l_type;
+ lock->lf_head = head;
lock->lf_next = (struct lockf *)0;
- lock->lf_block = (struct lockf *)0;
+ TAILQ_INIT(&lock->lf_blkhd);
lock->lf_flags = ap->a_flags;
/*
* Do the requested operation.
@@ -252,7 +255,7 @@ lf_setlock(lock)
* Remember who blocked us (for deadlock detection).
*/
lock->lf_next = block;
- lf_addblock(block, lock);
+ TAILQ_INSERT_TAIL(&block->lf_blkhd, lock, lf_block);
#ifdef LOCKF_DEBUG
if (lockf_debug & 1) {
lf_print("lf_setlock: blocking on", block);
@@ -260,19 +263,19 @@ lf_setlock(lock)
}
#endif /* LOCKF_DEBUG */
if ((error = tsleep((caddr_t)lock, priority, lockstr, 0))) {
- /*
- * Delete ourselves from the waiting to lock list.
- */
- for (block = lock->lf_next;
- block != NOLOCKF;
- block = block->lf_block) {
- if (block->lf_block != lock)
- continue;
- block->lf_block = block->lf_block->lf_block;
- break;
- }
- free(lock, M_LOCKF);
- return (error);
+ /*
+ * We may have been awakened by a signal (in
+ * which case we must remove ourselves from the
+ * blocked list) and/or by another process
+ * releasing a lock (in which case we have already
+ * been removed from the blocked list and our
+ * lf_next field set to NOLOCKF).
+ */
+ if (lock->lf_next)
+ TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock,
+ lf_block);
+ free(lock, M_LOCKF);
+ return (error);
}
}
/*
@@ -347,9 +350,12 @@ lf_setlock(lock)
overlap->lf_type == F_WRLCK) {
lf_wakelock(overlap);
} else {
- ltmp = lock->lf_block;
- lock->lf_block = overlap->lf_block;
- lf_addblock(lock, ltmp);
+ while (ltmp = overlap->lf_blkhd.tqh_first) {
+ TAILQ_REMOVE(&overlap->lf_blkhd, ltmp,
+ lf_block);
+ TAILQ_INSERT_TAIL(&lock->lf_blkhd,
+ ltmp, lf_block);
+ }
}
/*
* Add the new lock if necessary and delete the overlap.
@@ -645,34 +651,6 @@ lf_findoverlap(lf, lock, type, prev, overlap)
}
/*
- * Add a lock to the end of the blocked list.
- */
-static void
-lf_addblock(blocklist, lock)
- struct lockf *blocklist;
- struct lockf *lock;
-{
- register struct lockf *lf;
-
- if (lock == NOLOCKF)
- return;
-#ifdef LOCKF_DEBUG
- if (lockf_debug & 2) {
- lf_print("addblock: adding", lock);
- lf_print("to blocked list of", blocklist);
- }
-#endif /* LOCKF_DEBUG */
- if ((lf = blocklist->lf_block) == NOLOCKF) {
- blocklist->lf_block = lock;
- return;
- }
- while (lf->lf_block != NOLOCKF)
- lf = lf->lf_block;
- lf->lf_block = lock;
- return;
-}
-
-/*
* Split a lock and a contained region into
* two or three locks as necessary.
*/
@@ -710,7 +688,7 @@ lf_split(lock1, lock2)
MALLOC(splitlock, struct lockf *, sizeof *splitlock, M_LOCKF, M_WAITOK);
bcopy((caddr_t)lock1, (caddr_t)splitlock, sizeof *splitlock);
splitlock->lf_start = lock2->lf_end + 1;
- splitlock->lf_block = NOLOCKF;
+ TAILQ_INIT(&splitlock->lf_blkhd);
lock1->lf_end = lock2->lf_start - 1;
/*
* OK, now link it in
@@ -727,28 +705,23 @@ static void
lf_wakelock(listhead)
struct lockf *listhead;
{
- register struct lockf *blocklist, *wakelock;
-
- blocklist = listhead->lf_block;
- listhead->lf_block = NOLOCKF;
- while (blocklist != NOLOCKF) {
- wakelock = blocklist;
- blocklist = blocklist->lf_block;
- wakelock->lf_block = NOLOCKF;
+ register struct lockf *wakelock;
+
+ while (wakelock = listhead->lf_blkhd.tqh_first) {
+ TAILQ_REMOVE(&listhead->lf_blkhd, wakelock, lf_block);
wakelock->lf_next = NOLOCKF;
#ifdef LOCKF_DEBUG
if (lockf_debug & 2)
lf_print("lf_wakelock: awakening", wakelock);
#endif /* LOCKF_DEBUG */
- wakeup((caddr_t)wakelock);
- }
+ wakeup((caddr_t)wakelock);
+ }
}
#ifdef LOCKF_DEBUG
/*
* Print out a lock.
*/
-void
lf_print(tag, lock)
char *tag;
register struct lockf *lock;
@@ -767,18 +740,17 @@ lf_print(tag, lock)
lock->lf_type == F_WRLCK ? "exclusive" :
lock->lf_type == F_UNLCK ? "unlock" :
"unknown", lock->lf_start, lock->lf_end);
- if (lock->lf_block)
- printf(" block 0x%x\n", lock->lf_block);
+ if (lock->lf_blkhd.tqh_first)
+ printf(" block 0x%x\n", lock->lf_blkhd.tqh_first);
else
printf("\n");
}
-void
lf_printlist(tag, lock)
char *tag;
struct lockf *lock;
{
- register struct lockf *lf;
+ register struct lockf *lf, *blk;
printf("%s: Lock list for ino %d on dev <%d, %d>:\n",
tag, lock->lf_inode->i_number,
@@ -795,10 +767,23 @@ lf_printlist(tag, lock)
lf->lf_type == F_WRLCK ? "exclusive" :
lf->lf_type == F_UNLCK ? "unlock" :
"unknown", lf->lf_start, lf->lf_end);
- if (lf->lf_block)
- printf(" block 0x%x\n", lf->lf_block);
- else
- printf("\n");
+ for (blk = lf->lf_blkhd.tqh_first; blk;
+ blk = blk->lf_block.tqe_next) {
+ printf("\n\t\tlock request 0x%lx for ", blk);
+ if (blk->lf_flags & F_POSIX)
+ printf("proc %d",
+ ((struct proc *)(blk->lf_id))->p_pid);
+ else
+ printf("id 0x%x", blk->lf_id);
+ printf(", %s, start %d, end %d",
+ blk->lf_type == F_RDLCK ? "shared" :
+ blk->lf_type == F_WRLCK ? "exclusive" :
+ blk->lf_type == F_UNLCK ? "unlock" :
+ "unknown", blk->lf_start, blk->lf_end);
+ if (blk->lf_blkhd.tqh_first)
+ panic("lf_printlist: bad list");
+ }
+ printf("\n");
}
}
#endif /* LOCKF_DEBUG */
OpenPOWER on IntegriCloud