diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-08-22 18:50:48 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@primarydata.com> | 2014-10-07 14:06:13 -0400 |
commit | f82b4b6780afabce9d9a91c84fae17ec3d63b9d7 (patch) | |
tree | 525f28ccf756579147d7d498734a057b859e2215 /fs/locks.c | |
parent | 1c7dd2ff430fa14b45c9def54468e3a25ab8342b (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>
Diffstat (limited to 'fs/locks.c')
-rw-r--r-- | fs/locks.c | 21 |
1 files changed, 9 insertions, 12 deletions
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); |
1657 | out: | 1661 | out: |
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 | */ |
1700 | int generic_setlease(struct file *filp, long arg, struct file_lock **flp, | 1705 | int 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); | |||
1750 | int | 1753 | int |
1751 | vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) | 1754 | vfs_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 | } |
1764 | EXPORT_SYMBOL_GPL(vfs_setlease); | 1761 | EXPORT_SYMBOL_GPL(vfs_setlease); |
1765 | 1762 | ||