From: Ken Preslan On Mon, Aug 30, 2004 at 07:05:29PM -0400, Trond Myklebust wrote: > ... > Firstly, it would be nice to throw out the existing wait loop in > sys_flock(), and replace it with a call to this new > flock_lock_file_wait(). I suppose that can be done in a separate cleanup > patch, though... > ... > One solution that I've already suggested to Ken & co is to use a > separate f_op->flock() call. That would be my preference, since the > filesystems have to treat flock and posix locks differently anyway. > ... Thanks for the suggestions. Below is a patch that implements both of them. Signed-off-by: Andrew Morton --- 25-akpm/fs/locks.c | 28 ++++++++-------------------- 25-akpm/include/linux/fs.h | 1 + 2 files changed, 9 insertions(+), 20 deletions(-) diff -puN fs/locks.c~allow-cluster-wide-flock-update fs/locks.c --- 25/fs/locks.c~allow-cluster-wide-flock-update 2004-09-02 21:05:16.450700032 -0700 +++ 25-akpm/fs/locks.c 2004-09-02 21:05:16.457698968 -0700 @@ -1392,24 +1392,12 @@ asmlinkage long sys_flock(unsigned int f if (error) goto out_free; - if (filp->f_op && filp->f_op->lock) { - error = filp->f_op->lock(filp, - (can_sleep) ? F_SETLKW : F_SETLK, - lock); - goto out_free; - } - - for (;;) { - error = flock_lock_file(filp, lock); - if ((error != -EAGAIN) || !can_sleep) - break; - error = wait_event_interruptible(lock->fl_wait, !lock->fl_next); - if (!error) - continue; - - locks_delete_block(lock); - break; - } + if (filp->f_op && filp->f_op->flock) + error = filp->f_op->flock(filp, + (can_sleep) ? F_SETLKW : F_SETLK, + lock); + else + error = flock_lock_file_wait(filp, lock); out_free: if (list_empty(&lock->fl_link)) { @@ -1766,10 +1754,10 @@ void locks_remove_flock(struct file *fil if (!inode->i_flock) return; - if (filp->f_op && filp->f_op->lock) { + if (filp->f_op && filp->f_op->flock) { struct file_lock fl = { .fl_flags = FL_FLOCK, .fl_type = F_UNLCK }; - filp->f_op->lock(filp, F_SETLKW, &fl); + filp->f_op->flock(filp, F_SETLKW, &fl); } lock_kernel(); diff -puN include/linux/fs.h~allow-cluster-wide-flock-update include/linux/fs.h --- 25/include/linux/fs.h~allow-cluster-wide-flock-update 2004-09-02 21:05:16.452699728 -0700 +++ 25-akpm/include/linux/fs.h 2004-09-02 21:05:16.459698664 -0700 @@ -983,6 +983,7 @@ struct file_operations { unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*dir_notify)(struct file *filp, unsigned long arg); + int (*flock) (struct file *, int, struct file_lock *); }; struct inode_operations { _