Commit 22141f05 authored by Ken Preslan's avatar Ken Preslan Committed by Linus Torvalds

[PATCH] Allow cluster-wide flock

Below is a patch that lets a cluster filesystem (such as GFS) implement
flock across the cluster.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c1b76a2b
......@@ -1317,6 +1317,33 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
return error;
}
/**
* flock_lock_file_wait - Apply a FLOCK-style lock to a file
* @filp: The file to apply the lock to
* @fl: The lock to be applied
*
* Add a FLOCK style lock to a file.
*/
int flock_lock_file_wait(struct file *filp, struct file_lock *fl)
{
int error;
might_sleep();
for (;;) {
error = flock_lock_file(filp, fl);
if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP))
break;
error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
if (!error)
continue;
locks_delete_block(fl);
break;
}
return error;
}
EXPORT_SYMBOL(flock_lock_file_wait);
/**
* sys_flock: - flock() system call.
* @fd: the file descriptor to lock.
......@@ -1365,17 +1392,12 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
if (error)
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)) {
......@@ -1732,6 +1754,12 @@ void locks_remove_flock(struct file *filp)
if (!inode->i_flock)
return;
if (filp->f_op && filp->f_op->flock) {
struct file_lock fl = { .fl_flags = FL_FLOCK,
.fl_type = F_UNLCK };
filp->f_op->flock(filp, F_SETLKW, &fl);
}
lock_kernel();
before = &inode->i_flock;
......
......@@ -695,6 +695,7 @@ extern int posix_lock_file_wait(struct file *, struct file_lock *);
extern void posix_block_lock(struct file_lock *, struct file_lock *);
extern void posix_unblock_lock(struct file *, struct file_lock *);
extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
extern int __break_lease(struct inode *inode, unsigned int flags);
extern void lease_get_mtime(struct inode *, struct timespec *time);
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
......@@ -912,6 +913,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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment