diff options
-rw-r--r-- | fs/locks.c | 32 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 25 insertions, 8 deletions
diff --git a/fs/locks.c b/fs/locks.c index 4badf6a0e7b6..4d9e71d43e7e 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -792,9 +792,7 @@ out: | |||
792 | return error; | 792 | return error; |
793 | } | 793 | } |
794 | 794 | ||
795 | EXPORT_SYMBOL(posix_lock_file); | 795 | static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock) |
796 | |||
797 | static int __posix_lock_file(struct inode *inode, struct file_lock *request) | ||
798 | { | 796 | { |
799 | struct file_lock *fl; | 797 | struct file_lock *fl; |
800 | struct file_lock *new_fl, *new_fl2; | 798 | struct file_lock *new_fl, *new_fl2; |
@@ -818,6 +816,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request) | |||
818 | continue; | 816 | continue; |
819 | if (!posix_locks_conflict(request, fl)) | 817 | if (!posix_locks_conflict(request, fl)) |
820 | continue; | 818 | continue; |
819 | if (conflock) | ||
820 | locks_copy_lock(conflock, fl); | ||
821 | error = -EAGAIN; | 821 | error = -EAGAIN; |
822 | if (!(request->fl_flags & FL_SLEEP)) | 822 | if (!(request->fl_flags & FL_SLEEP)) |
823 | goto out; | 823 | goto out; |
@@ -987,8 +987,24 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request) | |||
987 | */ | 987 | */ |
988 | int posix_lock_file(struct file *filp, struct file_lock *fl) | 988 | int posix_lock_file(struct file *filp, struct file_lock *fl) |
989 | { | 989 | { |
990 | return __posix_lock_file(filp->f_dentry->d_inode, fl); | 990 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL); |
991 | } | ||
992 | EXPORT_SYMBOL(posix_lock_file); | ||
993 | |||
994 | /** | ||
995 | * posix_lock_file_conf - Apply a POSIX-style lock to a file | ||
996 | * @filp: The file to apply the lock to | ||
997 | * @fl: The lock to be applied | ||
998 | * @conflock: Place to return a copy of the conflicting lock, if found. | ||
999 | * | ||
1000 | * Except for the conflock parameter, acts just like posix_lock_file. | ||
1001 | */ | ||
1002 | int posix_lock_file_conf(struct file *filp, struct file_lock *fl, | ||
1003 | struct file_lock *conflock) | ||
1004 | { | ||
1005 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock); | ||
991 | } | 1006 | } |
1007 | EXPORT_SYMBOL(posix_lock_file_conf); | ||
992 | 1008 | ||
993 | /** | 1009 | /** |
994 | * posix_lock_file_wait - Apply a POSIX-style lock to a file | 1010 | * posix_lock_file_wait - Apply a POSIX-style lock to a file |
@@ -1004,7 +1020,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl) | |||
1004 | int error; | 1020 | int error; |
1005 | might_sleep (); | 1021 | might_sleep (); |
1006 | for (;;) { | 1022 | for (;;) { |
1007 | error = __posix_lock_file(filp->f_dentry->d_inode, fl); | 1023 | error = posix_lock_file(filp, fl); |
1008 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) | 1024 | if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) |
1009 | break; | 1025 | break; |
1010 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); | 1026 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); |
@@ -1076,7 +1092,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
1076 | fl.fl_end = offset + count - 1; | 1092 | fl.fl_end = offset + count - 1; |
1077 | 1093 | ||
1078 | for (;;) { | 1094 | for (;;) { |
1079 | error = __posix_lock_file(inode, &fl); | 1095 | error = __posix_lock_file_conf(inode, &fl, NULL); |
1080 | if (error != -EAGAIN) | 1096 | if (error != -EAGAIN) |
1081 | break; | 1097 | break; |
1082 | if (!(fl.fl_flags & FL_SLEEP)) | 1098 | if (!(fl.fl_flags & FL_SLEEP)) |
@@ -1689,7 +1705,7 @@ again: | |||
1689 | error = filp->f_op->lock(filp, cmd, file_lock); | 1705 | error = filp->f_op->lock(filp, cmd, file_lock); |
1690 | else { | 1706 | else { |
1691 | for (;;) { | 1707 | for (;;) { |
1692 | error = __posix_lock_file(inode, file_lock); | 1708 | error = posix_lock_file(filp, file_lock); |
1693 | if ((error != -EAGAIN) || (cmd == F_SETLK)) | 1709 | if ((error != -EAGAIN) || (cmd == F_SETLK)) |
1694 | break; | 1710 | break; |
1695 | error = wait_event_interruptible(file_lock->fl_wait, | 1711 | error = wait_event_interruptible(file_lock->fl_wait, |
@@ -1832,7 +1848,7 @@ again: | |||
1832 | error = filp->f_op->lock(filp, cmd, file_lock); | 1848 | error = filp->f_op->lock(filp, cmd, file_lock); |
1833 | else { | 1849 | else { |
1834 | for (;;) { | 1850 | for (;;) { |
1835 | error = __posix_lock_file(inode, file_lock); | 1851 | error = posix_lock_file(filp, file_lock); |
1836 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) | 1852 | if ((error != -EAGAIN) || (cmd == F_SETLK64)) |
1837 | break; | 1853 | break; |
1838 | error = wait_event_interruptible(file_lock->fl_wait, | 1854 | error = wait_event_interruptible(file_lock->fl_wait, |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 9674679525f9..ab67181a5a55 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -763,6 +763,7 @@ extern void locks_copy_lock(struct file_lock *, struct file_lock *); | |||
763 | extern void locks_remove_posix(struct file *, fl_owner_t); | 763 | extern void locks_remove_posix(struct file *, fl_owner_t); |
764 | extern void locks_remove_flock(struct file *); | 764 | extern void locks_remove_flock(struct file *); |
765 | extern int posix_test_lock(struct file *, struct file_lock *, struct file_lock *); | 765 | extern int posix_test_lock(struct file *, struct file_lock *, struct file_lock *); |
766 | extern int posix_lock_file_conf(struct file *, struct file_lock *, struct file_lock *); | ||
766 | extern int posix_lock_file(struct file *, struct file_lock *); | 767 | extern int posix_lock_file(struct file *, struct file_lock *); |
767 | extern int posix_lock_file_wait(struct file *, struct file_lock *); | 768 | extern int posix_lock_file_wait(struct file *, struct file_lock *); |
768 | extern int posix_unblock_lock(struct file *, struct file_lock *); | 769 | extern int posix_unblock_lock(struct file *, struct file_lock *); |