aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-08-22 18:50:48 -0400
committerJeff Layton <jlayton@primarydata.com>2014-10-07 14:06:13 -0400
commitf82b4b6780afabce9d9a91c84fae17ec3d63b9d7 (patch)
tree525f28ccf756579147d7d498734a057b859e2215
parent1c7dd2ff430fa14b45c9def54468e3a25ab8342b (diff)
locks: move i_lock acquisition into generic_*_lease handlers
Now that we have a saner internal API for managing leases, we no longer need to mandate that the inode->i_lock be held over most of the lease code. Push it down into generic_add_lease and generic_delete_lease. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--Documentation/filesystems/Locking6
-rw-r--r--Documentation/filesystems/vfs.txt5
-rw-r--r--fs/locks.c21
3 files changed, 16 insertions, 16 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 3d92049ae71d..4af288e38f13 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -472,8 +472,6 @@ locking rules:
472 All may block except for ->setlease. 472 All may block except for ->setlease.
473 No VFS locks held on entry except for ->setlease. 473 No VFS locks held on entry except for ->setlease.
474 474
475->setlease has the file_list_lock held and must not sleep.
476
477->llseek() locking has moved from llseek to the individual llseek 475->llseek() locking has moved from llseek to the individual llseek
478implementations. If your fs is not using generic_file_llseek, you 476implementations. If your fs is not using generic_file_llseek, you
479need to acquire and release the appropriate locks in your ->llseek(). 477need to acquire and release the appropriate locks in your ->llseek().
@@ -496,6 +494,10 @@ components. And there are other reasons why the current interface is a mess...
496->read on directories probably must go away - we should just enforce -EISDIR 494->read on directories probably must go away - we should just enforce -EISDIR
497in sys_read() and friends. 495in sys_read() and friends.
498 496
497->setlease operations should call generic_setlease() before or after setting
498the lease within the individual filesystem to record the result of the
499operation
500
499--------------------------- dquot_operations ------------------------------- 501--------------------------- dquot_operations -------------------------------
500prototypes: 502prototypes:
501 int (*write_dquot) (struct dquot *); 503 int (*write_dquot) (struct dquot *);
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 28ebd49f169f..8be1ea3bdd5a 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -895,8 +895,9 @@ otherwise noted.
895 splice_read: called by the VFS to splice data from file to a pipe. This 895 splice_read: called by the VFS to splice data from file to a pipe. This
896 method is used by the splice(2) system call 896 method is used by the splice(2) system call
897 897
898 setlease: called by the VFS to set or release a file lock lease. 898 setlease: called by the VFS to set or release a file lock lease. setlease
899 setlease has the file_lock_lock held and must not sleep. 899 implementations should call generic_setlease to record or remove
900 the lease in the inode after setting it.
900 901
901 fallocate: called by the VFS to preallocate blocks or punch a hole. 902 fallocate: called by the VFS to preallocate blocks or punch a hole.
902 903
diff --git a/fs/locks.c b/fs/locks.c
index a237ba632e8d..eb463257f867 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1330,6 +1330,8 @@ static void time_out_leases(struct inode *inode)
1330 struct file_lock **before; 1330 struct file_lock **before;
1331 struct file_lock *fl; 1331 struct file_lock *fl;
1332 1332
1333 lockdep_assert_held(&inode->i_lock);
1334
1333 before = &inode->i_flock; 1335 before = &inode->i_flock;
1334 while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) { 1336 while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
1335 trace_time_out_leases(inode, fl); 1337 trace_time_out_leases(inode, fl);
@@ -1590,6 +1592,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
1590 return -EINVAL; 1592 return -EINVAL;
1591 } 1593 }
1592 1594
1595 spin_lock(&inode->i_lock);
1596 time_out_leases(inode);
1593 error = check_conflicting_open(dentry, arg); 1597 error = check_conflicting_open(dentry, arg);
1594 if (error) 1598 if (error)
1595 goto out; 1599 goto out;
@@ -1655,6 +1659,7 @@ out_setup:
1655 if (lease->fl_lmops->lm_setup) 1659 if (lease->fl_lmops->lm_setup)
1656 lease->fl_lmops->lm_setup(lease, priv); 1660 lease->fl_lmops->lm_setup(lease, priv);
1657out: 1661out:
1662 spin_unlock(&inode->i_lock);
1658 if (is_deleg) 1663 if (is_deleg)
1659 mutex_unlock(&inode->i_mutex); 1664 mutex_unlock(&inode->i_mutex);
1660 if (!error && !my_before) 1665 if (!error && !my_before)
@@ -1672,6 +1677,7 @@ static int generic_delete_lease(struct file *filp)
1672 struct dentry *dentry = filp->f_path.dentry; 1677 struct dentry *dentry = filp->f_path.dentry;
1673 struct inode *inode = dentry->d_inode; 1678 struct inode *inode = dentry->d_inode;
1674 1679
1680 spin_lock(&inode->i_lock);
1675 for (before = &inode->i_flock; 1681 for (before = &inode->i_flock;
1676 ((fl = *before) != NULL) && IS_LEASE(fl); 1682 ((fl = *before) != NULL) && IS_LEASE(fl);
1677 before = &fl->fl_next) { 1683 before = &fl->fl_next) {
@@ -1681,6 +1687,7 @@ static int generic_delete_lease(struct file *filp)
1681 trace_generic_delete_lease(inode, fl); 1687 trace_generic_delete_lease(inode, fl);
1682 if (fl) 1688 if (fl)
1683 error = fl->fl_lmops->lm_change(before, F_UNLCK); 1689 error = fl->fl_lmops->lm_change(before, F_UNLCK);
1690 spin_unlock(&inode->i_lock);
1684 return error; 1691 return error;
1685} 1692}
1686 1693
@@ -1694,8 +1701,6 @@ static int generic_delete_lease(struct file *filp)
1694 * 1701 *
1695 * The (input) flp->fl_lmops->lm_break function is required 1702 * The (input) flp->fl_lmops->lm_break function is required
1696 * by break_lease(). 1703 * by break_lease().
1697 *
1698 * Called with inode->i_lock held.
1699 */ 1704 */
1700int generic_setlease(struct file *filp, long arg, struct file_lock **flp, 1705int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1701 void **priv) 1706 void **priv)
@@ -1712,8 +1717,6 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1712 if (error) 1717 if (error)
1713 return error; 1718 return error;
1714 1719
1715 time_out_leases(inode);
1716
1717 switch (arg) { 1720 switch (arg) {
1718 case F_UNLCK: 1721 case F_UNLCK:
1719 return generic_delete_lease(filp); 1722 return generic_delete_lease(filp);
@@ -1750,16 +1753,10 @@ EXPORT_SYMBOL(generic_setlease);
1750int 1753int
1751vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) 1754vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
1752{ 1755{
1753 struct inode *inode = file_inode(filp);
1754 int error;
1755
1756 spin_lock(&inode->i_lock);
1757 if (filp->f_op->setlease) 1756 if (filp->f_op->setlease)
1758 error = filp->f_op->setlease(filp, arg, lease, priv); 1757 return filp->f_op->setlease(filp, arg, lease, priv);
1759 else 1758 else
1760 error = generic_setlease(filp, arg, lease, priv); 1759 return generic_setlease(filp, arg, lease, priv);
1761 spin_unlock(&inode->i_lock);
1762 return error;
1763} 1760}
1764EXPORT_SYMBOL_GPL(vfs_setlease); 1761EXPORT_SYMBOL_GPL(vfs_setlease);
1765 1762