diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/locks.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/fs/locks.c b/fs/locks.c index a31648e3ec1b..f4fd1515b6e2 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1698,6 +1698,21 @@ out: | |||
1698 | return error; | 1698 | return error; |
1699 | } | 1699 | } |
1700 | 1700 | ||
1701 | /** | ||
1702 | * vfs_lock_file - file byte range lock | ||
1703 | * @filp: The file to apply the lock to | ||
1704 | * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) | ||
1705 | * @fl: The lock to be applied | ||
1706 | */ | ||
1707 | int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl) | ||
1708 | { | ||
1709 | if (filp->f_op && filp->f_op->lock) | ||
1710 | return filp->f_op->lock(filp, cmd, fl); | ||
1711 | else | ||
1712 | return posix_lock_file(filp, fl); | ||
1713 | } | ||
1714 | EXPORT_SYMBOL_GPL(vfs_lock_file); | ||
1715 | |||
1701 | /* Apply the lock described by l to an open file descriptor. | 1716 | /* Apply the lock described by l to an open file descriptor. |
1702 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 1717 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
1703 | */ | 1718 | */ |
@@ -1760,21 +1775,17 @@ again: | |||
1760 | if (error) | 1775 | if (error) |
1761 | goto out; | 1776 | goto out; |
1762 | 1777 | ||
1763 | if (filp->f_op && filp->f_op->lock != NULL) | 1778 | for (;;) { |
1764 | error = filp->f_op->lock(filp, cmd, file_lock); | 1779 | error = vfs_lock_file(filp, cmd, file_lock); |
1765 | else { | 1780 | if (error != -EAGAIN || cmd == F_SETLK) |
1766 | for (;;) { | ||
1767 | error = posix_lock_file(filp, file_lock); | ||
1768 | if (error != -EAGAIN || cmd == F_SETLK) | ||
1769 | break; | ||
1770 | error = wait_event_interruptible(file_lock->fl_wait, | ||
1771 | !file_lock->fl_next); | ||
1772 | if (!error) | ||
1773 | continue; | ||
1774 | |||
1775 | locks_delete_block(file_lock); | ||
1776 | break; | 1781 | break; |
1777 | } | 1782 | error = wait_event_interruptible(file_lock->fl_wait, |
1783 | !file_lock->fl_next); | ||
1784 | if (!error) | ||
1785 | continue; | ||
1786 | |||
1787 | locks_delete_block(file_lock); | ||
1788 | break; | ||
1778 | } | 1789 | } |
1779 | 1790 | ||
1780 | /* | 1791 | /* |
@@ -1890,21 +1901,17 @@ again: | |||
1890 | if (error) | 1901 | if (error) |
1891 | goto out; | 1902 | goto out; |
1892 | 1903 | ||
1893 | if (filp->f_op && filp->f_op->lock != NULL) | 1904 | for (;;) { |
1894 | error = filp->f_op->lock(filp, cmd, file_lock); | 1905 | error = vfs_lock_file(filp, cmd, file_lock); |
1895 | else { | 1906 | if (error != -EAGAIN || cmd == F_SETLK64) |
1896 | for (;;) { | ||
1897 | error = posix_lock_file(filp, file_lock); | ||
1898 | if (error != -EAGAIN || cmd == F_SETLK64) | ||
1899 | break; | ||
1900 | error = wait_event_interruptible(file_lock->fl_wait, | ||
1901 | !file_lock->fl_next); | ||
1902 | if (!error) | ||
1903 | continue; | ||
1904 | |||
1905 | locks_delete_block(file_lock); | ||
1906 | break; | 1907 | break; |
1907 | } | 1908 | error = wait_event_interruptible(file_lock->fl_wait, |
1909 | !file_lock->fl_next); | ||
1910 | if (!error) | ||
1911 | continue; | ||
1912 | |||
1913 | locks_delete_block(file_lock); | ||
1914 | break; | ||
1908 | } | 1915 | } |
1909 | 1916 | ||
1910 | /* | 1917 | /* |
@@ -1949,10 +1956,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) | |||
1949 | lock.fl_ops = NULL; | 1956 | lock.fl_ops = NULL; |
1950 | lock.fl_lmops = NULL; | 1957 | lock.fl_lmops = NULL; |
1951 | 1958 | ||
1952 | if (filp->f_op && filp->f_op->lock != NULL) | 1959 | vfs_lock_file(filp, F_SETLK, &lock); |
1953 | filp->f_op->lock(filp, F_SETLK, &lock); | ||
1954 | else | ||
1955 | posix_lock_file(filp, &lock); | ||
1956 | 1960 | ||
1957 | if (lock.fl_ops && lock.fl_ops->fl_release_private) | 1961 | if (lock.fl_ops && lock.fl_ops->fl_release_private) |
1958 | lock.fl_ops->fl_release_private(&lock); | 1962 | lock.fl_ops->fl_release_private(&lock); |