aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-08-22 10:18:45 -0400
committerJeff Layton <jlayton@primarydata.com>2014-10-07 14:06:12 -0400
commit0efaa7e82f02fe69c05ad28e905f31fc86e6f08e (patch)
treebf7e9d91c5800da259fa3ee9907287ba2b2d6cc1 /fs/locks.c
parent415b96c5a1fe31ed9deb0618e95ecbb1df3de54c (diff)
locks: generic_delete_lease doesn't need a file_lock at all
Ensure that it's OK to pass in a NULL file_lock double pointer on a F_UNLCK request and convert the vfs_setlease F_UNLCK callers to do just that. Finally, turn the BUG_ON in generic_setlease into a WARN_ON_ONCE with an error return. That's a problem we can handle without crashing the box if it occurs. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/fs/locks.c b/fs/locks.c
index def1ac2e87bd..f79c74ef51ef 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1637,22 +1637,23 @@ out:
1637 return error; 1637 return error;
1638} 1638}
1639 1639
1640static int generic_delete_lease(struct file *filp, struct file_lock **flp) 1640static int generic_delete_lease(struct file *filp)
1641{ 1641{
1642 int error = -EAGAIN;
1642 struct file_lock *fl, **before; 1643 struct file_lock *fl, **before;
1643 struct dentry *dentry = filp->f_path.dentry; 1644 struct dentry *dentry = filp->f_path.dentry;
1644 struct inode *inode = dentry->d_inode; 1645 struct inode *inode = dentry->d_inode;
1645 1646
1646 trace_generic_delete_lease(inode, *flp);
1647
1648 for (before = &inode->i_flock; 1647 for (before = &inode->i_flock;
1649 ((fl = *before) != NULL) && IS_LEASE(fl); 1648 ((fl = *before) != NULL) && IS_LEASE(fl);
1650 before = &fl->fl_next) { 1649 before = &fl->fl_next) {
1651 if (fl->fl_file != filp) 1650 if (fl->fl_file == filp)
1652 continue; 1651 break;
1653 return (*flp)->fl_lmops->lm_change(before, F_UNLCK);
1654 } 1652 }
1655 return -EAGAIN; 1653 trace_generic_delete_lease(inode, fl);
1654 if (fl)
1655 error = fl->fl_lmops->lm_change(before, F_UNLCK);
1656 return error;
1656} 1657}
1657 1658
1658/** 1659/**
@@ -1682,13 +1683,15 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
1682 1683
1683 time_out_leases(inode); 1684 time_out_leases(inode);
1684 1685
1685 BUG_ON(!(*flp)->fl_lmops->lm_break);
1686
1687 switch (arg) { 1686 switch (arg) {
1688 case F_UNLCK: 1687 case F_UNLCK:
1689 return generic_delete_lease(filp, flp); 1688 return generic_delete_lease(filp);
1690 case F_RDLCK: 1689 case F_RDLCK:
1691 case F_WRLCK: 1690 case F_WRLCK:
1691 if (!(*flp)->fl_lmops->lm_break) {
1692 WARN_ON_ONCE(1);
1693 return -ENOLCK;
1694 }
1692 return generic_add_lease(filp, arg, flp); 1695 return generic_add_lease(filp, arg, flp);
1693 default: 1696 default:
1694 return -EINVAL; 1697 return -EINVAL;
@@ -1744,15 +1747,6 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
1744} 1747}
1745EXPORT_SYMBOL_GPL(vfs_setlease); 1748EXPORT_SYMBOL_GPL(vfs_setlease);
1746 1749
1747static int do_fcntl_delete_lease(struct file *filp)
1748{
1749 struct file_lock fl, *flp = &fl;
1750
1751 lease_init(filp, F_UNLCK, flp);
1752
1753 return vfs_setlease(filp, F_UNLCK, &flp);
1754}
1755
1756static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) 1750static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1757{ 1751{
1758 struct file_lock *fl, *ret; 1752 struct file_lock *fl, *ret;
@@ -1809,7 +1803,7 @@ out_unlock:
1809int fcntl_setlease(unsigned int fd, struct file *filp, long arg) 1803int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
1810{ 1804{
1811 if (arg == F_UNLCK) 1805 if (arg == F_UNLCK)
1812 return do_fcntl_delete_lease(filp); 1806 return vfs_setlease(filp, F_UNLCK, NULL);
1813 return do_fcntl_add_lease(fd, filp, arg); 1807 return do_fcntl_add_lease(fd, filp, arg);
1814} 1808}
1815 1809