From: Mike Halcrow Use exported posix_lock_file_wait() rather than re-implement it. Note that ecryptfs_getlk() and ecryptfs_setlk() still need work; we need to figure out how to best integrate with the existing fcntl_setlk() and fcntl_getlk() functions in fs/locks.c. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton --- fs/ecryptfs/file.c | 71 ++++++++++--------------------------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff -puN fs/ecryptfs/file.c~ecryptfs-overhaul-file-locking fs/ecryptfs/file.c --- a/fs/ecryptfs/file.c~ecryptfs-overhaul-file-locking +++ a/fs/ecryptfs/file.c @@ -340,40 +340,12 @@ ecryptfs_fsync(struct file *file, struct return rc; } -static void locks_delete_block(struct file_lock *waiter) -{ - lock_kernel(); - list_del_init(&waiter->fl_block); - list_del_init(&waiter->fl_link); - waiter->fl_next = NULL; - unlock_kernel(); -} - -static int ecryptfs_posix_lock(struct file *file, struct file_lock *fl, int cmd) -{ - int rc; - -lock_file: - rc = posix_lock_file(file, fl); - if ((rc != -EAGAIN) || (cmd == F_SETLK)) - goto out; - rc = wait_event_interruptible(fl->fl_wait, !fl->fl_next); - if (!rc) - goto lock_file; - locks_delete_block(fl); -out: - return rc; -} - static int ecryptfs_setlk(struct file *file, int cmd, struct file_lock *fl) { - int rc = -EINVAL; - struct inode *inode, *lower_inode; - struct file *lower_file = NULL; + struct file *lower_file = ecryptfs_file_to_lower(file); + struct inode *lower_inode = lower_file->f_dentry->d_inode; + int rc; - lower_file = ecryptfs_file_to_lower(file); - inode = file->f_dentry->d_inode; - lower_inode = lower_file->f_dentry->d_inode; /* Don't allow mandatory locks on files that may be memory mapped * and shared. */ if (IS_MANDLOCK(lower_inode) && @@ -382,7 +354,7 @@ static int ecryptfs_setlk(struct file *f rc = -EAGAIN; goto out; } - if (cmd == F_SETLKW) + if (IS_SETLKW(cmd)) fl->fl_flags |= FL_SLEEP; rc = -EBADF; switch (fl->fl_type) { @@ -410,29 +382,29 @@ static int ecryptfs_setlk(struct file *f goto out; goto upper_lock; } - rc = ecryptfs_posix_lock(lower_file, fl, cmd); + rc = posix_lock_file_wait(lower_file, fl); if (rc) goto out; upper_lock: fl->fl_file = file; - rc = ecryptfs_posix_lock(file, fl, cmd); + rc = posix_lock_file_wait(lower_file, fl); if (rc) { fl->fl_type = F_UNLCK; fl->fl_file = lower_file; - ecryptfs_posix_lock(lower_file, fl, cmd); + rc = posix_lock_file_wait(lower_file, fl); } out: return rc; } -static int ecryptfs_getlk(struct file *file, struct file_lock *fl) +static int ecryptfs_getlk(struct file *file, int cmd, struct file_lock *fl) { struct file_lock cfl; struct file_lock *tempfl = NULL; int rc = 0; if (file->f_op && file->f_op->lock) { - rc = file->f_op->lock(file, F_GETLK, fl); + rc = file->f_op->lock(file, cmd, fl); if (rc < 0) goto out; } else @@ -458,27 +430,20 @@ static int ecryptfs_fasync(int fd, struc static int ecryptfs_lock(struct file *file, int cmd, struct file_lock *fl) { - int rc = 0; - struct file *lower_file = NULL; + struct file *lower_file = ecryptfs_file_to_lower(file); + int rc = -EINVAL; - lower_file = ecryptfs_file_to_lower(file); - rc = -EINVAL; if (!fl) goto out; - fl->fl_file = lower_file; - switch (cmd) { - case F_GETLK: - rc = ecryptfs_getlk(lower_file, fl); - break; - case F_SETLK: - case F_SETLKW: + if (IS_GETLK(cmd)) { + fl->fl_file = lower_file; + rc = ecryptfs_getlk(lower_file, cmd, fl); + fl->fl_file = file; + } else if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { fl->fl_file = file; rc = ecryptfs_setlk(file, cmd, fl); - break; - default: - rc = -EINVAL; - } - fl->fl_file = file; + } else + fl->fl_file = file; out: return rc; } _