Define the for_each_lock macro and start replacing ugly special for loops
with it. Add IS_LEASE, IS_FLOCK & IS_POSIX macros to help. Rejig the
interface between sys_flock and flock_lock_file to always pass a struct
file_lock rather than a command. Eliminate some gotos by simplifying
the logic. Remove some redundant initialisation.
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 Mon May 13 08:05:00 2002
+++ linux-2.5.15-flock/fs/locks.c Tue May 14 07:32:42 2002
@@ -128,11 +128,18 @@
int leases_enable = 1;
int lease_break_time = 45;
static int assign_type(struct file_lock *fl, int type)
@@ -746,59 +769,45 @@
* 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, unsigned int lock_type,
+static int flock_lock_file(struct file *filp, struct file_lock *new_fl,
unsigned int wait)
{
- struct file_lock *fl;
- struct file_lock *new_fl = NULL;
struct file_lock **before;
struct inode * inode = filp->f_dentry->d_inode;
- int error, change;
- int unlock = (lock_type == F_UNLCK);
-
- /*
- * If we need a new lock, get it in advance to avoid races.
- */
- if (!unlock) {
- error = -ENOLCK;
- new_fl = flock_make_lock(filp, lock_type);
- if (!new_fl)
- return error;
- }
+ int error = 0;
+ int found = 0;
- error = 0;
-search:
- change = 0;
- before = &inode->i_flock;
- while (((fl = *before) != NULL) && (fl->fl_flags & FL_FLOCK)) {
- if (filp == fl->fl_file) {
- if (lock_type == fl->fl_type)
- goto out;
- change = 1;
+ lock_kernel();
+ for_each_lock(inode, before) {
+ struct file_lock *fl = *before;
+ if (IS_POSIX(fl))
break;
- }
- before = &fl->fl_next;
- }
- /* change means that we are changing the type of an existing lock,
- * or else unlocking it.
- */
- if (change) {
- /* N.B. What if the wait argument is false? */
+ if (IS_LEASE(fl))
+ continue;
+ if (filp != fl->fl_file)
+ continue;
+ if (new_fl->fl_type == fl->fl_type)
+ goto out;
+ found = 1;
locks_delete_lock(before);
- if (!unlock) {
- yield();
- /*
- * If we waited, another lock may have been added ...
- */
- goto search;
- }
+ break;
}
- if (unlock)
- goto out;
+ unlock_kernel();