aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/locks.c38
-rw-r--r--include/linux/fs.h1
2 files changed, 26 insertions, 13 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 749a0dc7cd4b..a31648e3ec1b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1611,6 +1611,24 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1611 return error; 1611 return error;
1612} 1612}
1613 1613
1614/**
1615 * vfs_test_lock - test file byte range lock
1616 * @filp: The file to test lock for
1617 * @fl: The lock to test
1618 * @conf: Place to return a copy of the conflicting lock, if found
1619 *
1620 * Returns -ERRNO on failure. Indicates presence of conflicting lock by
1621 * setting conf->fl_type to something other than F_UNLCK.
1622 */
1623int vfs_test_lock(struct file *filp, struct file_lock *fl)
1624{
1625 if (filp->f_op && filp->f_op->lock)
1626 return filp->f_op->lock(filp, F_GETLK, fl);
1627 posix_test_lock(filp, fl);
1628 return 0;
1629}
1630EXPORT_SYMBOL_GPL(vfs_test_lock);
1631
1614static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 1632static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
1615{ 1633{
1616 flock->l_pid = fl->fl_pid; 1634 flock->l_pid = fl->fl_pid;
@@ -1663,12 +1681,9 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
1663 if (error) 1681 if (error)
1664 goto out; 1682 goto out;
1665 1683
1666 if (filp->f_op && filp->f_op->lock) { 1684 error = vfs_test_lock(filp, &file_lock);
1667 error = filp->f_op->lock(filp, F_GETLK, &file_lock); 1685 if (error)
1668 if (error < 0) 1686 goto out;
1669 goto out;
1670 } else
1671 posix_test_lock(filp, &file_lock);
1672 1687
1673 flock.l_type = file_lock.fl_type; 1688 flock.l_type = file_lock.fl_type;
1674 if (file_lock.fl_type != F_UNLCK) { 1689 if (file_lock.fl_type != F_UNLCK) {
@@ -1797,13 +1812,10 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
1797 if (error) 1812 if (error)
1798 goto out; 1813 goto out;
1799 1814
1800 if (filp->f_op && filp->f_op->lock) { 1815 error = vfs_test_lock(filp, &file_lock);
1801 error = filp->f_op->lock(filp, F_GETLK, &file_lock); 1816 if (error)
1802 if (error < 0) 1817 goto out;
1803 goto out; 1818
1804 } else
1805 posix_test_lock(filp, &file_lock);
1806
1807 flock.l_type = file_lock.fl_type; 1819 flock.l_type = file_lock.fl_type;
1808 if (file_lock.fl_type != F_UNLCK) 1820 if (file_lock.fl_type != F_UNLCK)
1809 posix_lock_to_flock64(&flock, &file_lock); 1821 posix_lock_to_flock64(&flock, &file_lock);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9e1ddffe3884..2a2a43988f50 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -856,6 +856,7 @@ extern int posix_lock_file_conf(struct file *, struct file_lock *, struct file_l
856extern int posix_lock_file(struct file *, struct file_lock *); 856extern int posix_lock_file(struct file *, struct file_lock *);
857extern int posix_lock_file_wait(struct file *, struct file_lock *); 857extern int posix_lock_file_wait(struct file *, struct file_lock *);
858extern int posix_unblock_lock(struct file *, struct file_lock *); 858extern int posix_unblock_lock(struct file *, struct file_lock *);
859extern int vfs_test_lock(struct file *, struct file_lock *);
859extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); 860extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
860extern int __break_lease(struct inode *inode, unsigned int flags); 861extern int __break_lease(struct inode *inode, unsigned int flags);
861extern void lease_get_mtime(struct inode *, struct timespec *time); 862extern void lease_get_mtime(struct inode *, struct timespec *time);