diff -u linux-2.5.15-flock/fs/locks.c linux-2.5.15-flock/fs/locks.c
--- linux-2.5.15-flock/fs/locks.c	Tue May 21 00:17:14 2002
+++ linux-2.5.15-flock/fs/locks.c	Tue May 21 20:54:35 2002
@@ -139,6 +139,8 @@
 LIST_HEAD(file_lock_list);
 static LIST_HEAD(blocked_list);
 
+static spinlock_t file_lock_lock = SPIN_LOCK_UNLOCKED;
+
 static kmem_cache_t *filelock_cache;
 
 #define IS_LEASE(fl) ((fl->fl_flags & FL_LEASE) > 0)
@@ -577,12 +579,17 @@
 
 	current->state = TASK_INTERRUPTIBLE;
 	add_wait_queue(fl_wait, &wait);
+	spin_unlock(&file_lock_lock);
+
+	/* I have no lock and I must scream */
 	if (timeout == 0)
 		schedule();
 	else
 		result = schedule_timeout(timeout);
 	if (signal_pending(current))
 		result = -ERESTARTSYS;
+
+	spin_lock(&file_lock_lock);
 	remove_wait_queue(fl_wait, &wait);
 	current->state = TASK_RUNNING;
 	return result;
@@ -606,12 +613,13 @@
 	return result;
 }
 
+/* Takes file_lock_lock */
 struct file_lock *
 posix_test_lock(struct file *filp, struct file_lock *fl)
 {
 	struct file_lock **lockp, *cfl = NULL;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for_each_lock(filp->f_dentry->d_inode, lockp) {
 		cfl = *lockp;
 		if (!IS_POSIX(cfl))
@@ -619,7 +627,7 @@
 		if (posix_locks_conflict(cfl, fl))
 			break;
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 
 	return cfl;
 }
@@ -674,14 +682,14 @@
 	/*
 	 * Search the lock list for this inode for any POSIX locks.
 	 */
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
 		if (!(fl->fl_flags & FL_POSIX))
 			continue;
 		if (fl->fl_owner != owner)
 			break;
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	return fl ? -EAGAIN : 0;
 }
 
@@ -705,7 +713,7 @@
 	new_fl->fl_end = offset + count - 1;
 
 	error = 0;
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 
 repeat:
 	/* Search the lock list for this inode for locks that conflict with
@@ -737,7 +745,7 @@
 			goto repeat;
 		}
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	locks_free_lock(new_fl);
 	return error;
 }
@@ -753,7 +761,7 @@
 	int error = 0;
 	int found = 0;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for_each_lock(inode, before) {
 		struct file_lock *fl = *before;
 		if (IS_POSIX(fl))
@@ -768,7 +776,7 @@
 		locks_delete_lock(before);
 		break;
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 
 	if (found)
 		yield();
@@ -776,7 +784,7 @@
 	if (new_fl->fl_type == F_UNLCK)
 		return 0;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for_each_lock(inode, before) {
 		struct file_lock *fl = *before;
 		if (IS_POSIX(fl))
@@ -795,7 +803,7 @@
 	error = 0;
 
 out:
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	return error;
 }
 
@@ -880,7 +888,7 @@
 {
 	struct file_lock *extra, **before;
 	struct inode *inode = filp->f_dentry->d_inode;
-	int error, found = 0, result = 0;
+	int error, found = 0;
 
 	/*
 	 * We may need an extra file_lock structure for this operation,
@@ -891,7 +899,7 @@
 	if (!extra)
 		goto out_nolock;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	if (caller->fl_type != F_UNLCK) {
 		for_each_lock(inode, before) {
 			struct file_lock *fl = *before;
@@ -912,6 +920,7 @@
   	}
 
 	for_each_lock(inode, before) {
+		int result;
 		struct file_lock *fl;
  deleted:
 		fl = *before;
@@ -937,7 +946,7 @@
 	error = 0;
 
 out:
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 out_nolock:
 	/*
 	 * Free any unused locks.
@@ -966,7 +975,7 @@
 
 	alloc_err = lease_alloc(NULL, 0, &new_fl);
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	flock = inode->i_flock;
 	if (flock->fl_type & F_INPROGRESS) {
 		if ((mode & O_NONBLOCK)
@@ -1035,7 +1044,7 @@
 	}
 
 out:
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	if (!alloc_err)
 		locks_free_lock(new_fl);
 	return error;
@@ -1136,7 +1145,7 @@
 		|| (atomic_read(&inode->i_count) > 1)))
 		return -EAGAIN;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 
 	for_each_lock(inode, before) {
 		struct file_lock *fl = *before;
@@ -1187,7 +1196,7 @@
 	filp->f_owner.uid = current->uid;
 	filp->f_owner.euid = current->euid;
 out_unlock:
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	return error;
 }
 
@@ -1236,9 +1245,9 @@
 		if (!error)
 			continue;
 
-		lock_kernel();
+		spin_lock(&file_lock_lock);
 		locks_delete_block(lock);
-		unlock_kernel();
+		spin_unlock(&file_lock_lock);
 		break;
 	}
 
@@ -1387,9 +1396,9 @@
 		if (!error)
 			continue;
 
-		lock_kernel();
+		spin_lock(&file_lock_lock);
 		locks_delete_block(lock);
-		unlock_kernel();
+		spin_unlock(&file_lock_lock);
 		break;
 	}
 
@@ -1684,7 +1693,7 @@
 	off_t pos = 0;
 	int i = 0;
 
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	list_for_each(tmp, &file_lock_list) {
 		struct list_head *btmp;
 		struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
@@ -1705,7 +1714,7 @@
 		}
 	}
 done:
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	*start = buffer;
 	if(q-buffer < length)
 		return (q-buffer);
@@ -1729,7 +1738,7 @@
 {
 	struct file_lock *fl;
 	int result = 1;
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
 		if (fl->fl_flags == FL_POSIX) {
 			if (fl->fl_type == F_RDLCK)
@@ -1746,7 +1755,7 @@
 		result = 0;
 		break;
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	return result;
 }
 
@@ -1767,7 +1776,7 @@
 {
 	struct file_lock *fl;
 	int result = 1;
-	lock_kernel();
+	spin_lock(&file_lock_lock);
 	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
 		if (fl->fl_flags == FL_POSIX) {
 			if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
@@ -1782,7 +1791,7 @@
 		result = 0;
 		break;
 	}
-	unlock_kernel();
+	spin_unlock(&file_lock_lock);
 	return result;
 }
 
