diff options
| -rw-r--r-- | fs/locks.c | 71 |
1 files changed, 31 insertions, 40 deletions
diff --git a/fs/locks.c b/fs/locks.c index 1ce57b4b362c..6222e4b580e2 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -1738,6 +1738,35 @@ int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, str | |||
| 1738 | } | 1738 | } |
| 1739 | EXPORT_SYMBOL_GPL(vfs_lock_file); | 1739 | EXPORT_SYMBOL_GPL(vfs_lock_file); |
| 1740 | 1740 | ||
| 1741 | static int do_lock_file_wait(struct file *filp, unsigned int cmd, | ||
| 1742 | struct file_lock *fl) | ||
| 1743 | { | ||
| 1744 | int error; | ||
| 1745 | |||
| 1746 | error = security_file_lock(filp, fl->fl_type); | ||
| 1747 | if (error) | ||
| 1748 | return error; | ||
| 1749 | |||
| 1750 | if (filp->f_op && filp->f_op->lock != NULL) | ||
| 1751 | error = filp->f_op->lock(filp, cmd, fl); | ||
| 1752 | else { | ||
| 1753 | for (;;) { | ||
| 1754 | error = posix_lock_file(filp, fl, NULL); | ||
| 1755 | if (error != FILE_LOCK_DEFERRED) | ||
| 1756 | break; | ||
| 1757 | error = wait_event_interruptible(fl->fl_wait, | ||
| 1758 | !fl->fl_next); | ||
| 1759 | if (!error) | ||
| 1760 | continue; | ||
| 1761 | |||
| 1762 | locks_delete_block(fl); | ||
| 1763 | break; | ||
| 1764 | } | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | return error; | ||
| 1768 | } | ||
| 1769 | |||
| 1741 | /* Apply the lock described by l to an open file descriptor. | 1770 | /* Apply the lock described by l to an open file descriptor. |
| 1742 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 1771 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
| 1743 | */ | 1772 | */ |
| @@ -1795,26 +1824,7 @@ again: | |||
| 1795 | goto out; | 1824 | goto out; |
| 1796 | } | 1825 | } |
| 1797 | 1826 | ||
| 1798 | error = security_file_lock(filp, file_lock->fl_type); | 1827 | error = do_lock_file_wait(filp, cmd, file_lock); |
| 1799 | if (error) | ||
| 1800 | goto out; | ||
| 1801 | |||
| 1802 | if (filp->f_op && filp->f_op->lock != NULL) | ||
| 1803 | error = filp->f_op->lock(filp, cmd, file_lock); | ||
| 1804 | else { | ||
| 1805 | for (;;) { | ||
| 1806 | error = posix_lock_file(filp, file_lock, NULL); | ||
| 1807 | if (error != FILE_LOCK_DEFERRED) | ||
| 1808 | break; | ||
| 1809 | error = wait_event_interruptible(file_lock->fl_wait, | ||
| 1810 | !file_lock->fl_next); | ||
| 1811 | if (!error) | ||
| 1812 | continue; | ||
| 1813 | |||
| 1814 | locks_delete_block(file_lock); | ||
| 1815 | break; | ||
| 1816 | } | ||
| 1817 | } | ||
| 1818 | 1828 | ||
| 1819 | /* | 1829 | /* |
| 1820 | * Attempt to detect a close/fcntl race and recover by | 1830 | * Attempt to detect a close/fcntl race and recover by |
| @@ -1932,26 +1942,7 @@ again: | |||
| 1932 | goto out; | 1942 | goto out; |
| 1933 | } | 1943 | } |
| 1934 | 1944 | ||
| 1935 | error = security_file_lock(filp, file_lock->fl_type); | 1945 | error = do_lock_file_wait(filp, cmd, file_lock); |
| 1936 | if (error) | ||
| 1937 | goto out; | ||
| 1938 | |||
| 1939 | if (filp->f_op && filp->f_op->lock != NULL) | ||
| 1940 | error = filp->f_op->lock(filp, cmd, file_lock); | ||
| 1941 | else { | ||
| 1942 | for (;;) { | ||
| 1943 | error = posix_lock_file(filp, file_lock, NULL); | ||
| 1944 | if (error != FILE_LOCK_DEFERRED) | ||
| 1945 | break; | ||
| 1946 | error = wait_event_interruptible(file_lock->fl_wait, | ||
| 1947 | !file_lock->fl_next); | ||
| 1948 | if (!error) | ||
| 1949 | continue; | ||
| 1950 | |||
| 1951 | locks_delete_block(file_lock); | ||
| 1952 | break; | ||
| 1953 | } | ||
| 1954 | } | ||
| 1955 | 1946 | ||
| 1956 | /* | 1947 | /* |
| 1957 | * Attempt to detect a close/fcntl race and recover by | 1948 | * Attempt to detect a close/fcntl race and recover by |
