Introduces FL_SLEEP and removes FL_BROKEN.  Removes locks_block_on
from the flock() path.

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 14 07:32:42 2002
+++ linux-2.5.15-flock/fs/locks.c       Tue May 14 13:49:45 2002
@@ -255,7 +255,10 @@
       fl->fl_flags = FL_FLOCK;
       fl->fl_type = type;
       fl->fl_end = OFFSET_MAX;
-
+
+       if ((cmd & LOCK_NB) == 0)
+               fl->fl_type |= FL_SLEEP;
+
       *lock = fl;
       return 0;
}
@@ -769,8 +772,7 @@
 * at the head of the list, but that's secret knowledge known only to
 * flock_lock_file and posix_lock_file.
 */
-static int flock_lock_file(struct file *filp, struct file_lock *new_fl,
-                          unsigned int wait)
+static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
{
       struct file_lock **before;
       struct inode * inode = filp->f_dentry->d_inode;
@@ -801,7 +803,6 @@
               return 0;

       lock_kernel();
-repeat:
       for_each_lock(inode, before) {
               struct file_lock *fl = *before;
               if (IS_POSIX(fl))
@@ -811,12 +812,10 @@
               if (!flock_locks_conflict(new_fl, fl))
                       continue;
               error = -EAGAIN;
-               if (!wait)
-                       goto out;
-               error = locks_block_on(fl, new_fl);
-               if (error != 0)
-                       goto out;
-               goto repeat;
+               if (new_fl->fl_flags & FL_SLEEP) {
+                       locks_insert_block(fl, new_fl);
+               }
+               goto out;
       }
       locks_insert_lock(&inode->i_flock, new_fl);
       error = 0;
@@ -1305,11 +1304,23 @@
       if (error < 0)
               goto out_putf;

-       error = flock_lock_file(filp, lock,
-                               (cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1);
+       for (;;) {
+               error = flock_lock_file(filp, lock);
+               if (!error)
+                       goto out_putf;
+               if (cmd & LOCK_NB)
+                       break;
+               error = wait_event_interruptible(lock->fl_wait, !lock->fl_next);
+               if (!error)
+                       continue;
+
+               lock_kernel();
+               locks_delete_block(lock);
+               unlock_kernel();
+               break;
+       }

-       if (error)
-               locks_free_lock(lock);
+       locks_free_lock(lock);

out_putf:
       fput(filp);
diff -u linux-2.5.15-flock/include/linux/fs.h linux-2.5.15-flock/include/linux/fs.h
--- linux-2.5.15-flock/include/linux/fs.h       Mon May 13 07:46:48 2002
+++ linux-2.5.15-flock/include/linux/fs.h       Tue May 14 08:31:58 2002
@@ -484,10 +484,10 @@

#define FL_POSIX       1
#define FL_FLOCK       2
-#define FL_BROKEN      4       /* broken flock() emulation */
-#define FL_ACCESS      8       /* for processes suspended by mandatory locking */
+#define FL_ACCESS      8       /* not trying to lock, just looking */
#define FL_LOCKD       16      /* lock held by rpc.lockd */
#define FL_LEASE       32      /* lease held on this file */
+#define FL_SLEEP       128     /* A blocking lock */

/*
 * The POSIX file lock owner is determined by
only in patch2:
--- linux-2.5.15/fs/nfs/file.c  Thu May  9 16:25:16 2002
+++ linux-2.5.15-flock/fs/nfs/file.c    Tue May 14 12:28:08 2002
@@ -272,7 +272,7 @@
        * Not sure whether that would be unique, though, or whether
        * that would break in other places.
        */
-       if (!fl->fl_owner || (fl->fl_flags & (FL_POSIX|FL_BROKEN)) != FL_POSIX)
+       if (!fl->fl_owner || (fl->fl_flags & FL_POSIX) != FL_POSIX)
               return -ENOLCK;

       /*