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;
}