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 |