diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-08-22 10:18:45 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@primarydata.com> | 2014-10-07 14:06:12 -0400 |
commit | 0efaa7e82f02fe69c05ad28e905f31fc86e6f08e (patch) | |
tree | bf7e9d91c5800da259fa3ee9907287ba2b2d6cc1 | |
parent | 415b96c5a1fe31ed9deb0618e95ecbb1df3de54c (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>
-rw-r--r-- | fs/locks.c | 34 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 2 | ||||
-rw-r--r-- | include/trace/events/filelock.h | 14 |
3 files changed, 22 insertions, 28 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 | ||
1640 | static int generic_delete_lease(struct file *filp, struct file_lock **flp) | 1640 | static 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 | } |
1745 | EXPORT_SYMBOL_GPL(vfs_setlease); | 1748 | EXPORT_SYMBOL_GPL(vfs_setlease); |
1746 | 1749 | ||
1747 | static 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 | |||
1756 | static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) | 1750 | static 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: | |||
1809 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | 1803 | int 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 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5bb4952faf5b..89d54e505155 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -690,7 +690,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp) | |||
690 | spin_unlock(&fp->fi_lock); | 690 | spin_unlock(&fp->fi_lock); |
691 | 691 | ||
692 | if (filp) { | 692 | if (filp) { |
693 | vfs_setlease(filp, F_UNLCK, &fl); | 693 | vfs_setlease(filp, F_UNLCK, NULL); |
694 | fput(filp); | 694 | fput(filp); |
695 | } | 695 | } |
696 | } | 696 | } |
diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h index 59d11c22f076..a0d008070962 100644 --- a/include/trace/events/filelock.h +++ b/include/trace/events/filelock.h | |||
@@ -53,15 +53,15 @@ DECLARE_EVENT_CLASS(filelock_lease, | |||
53 | ), | 53 | ), |
54 | 54 | ||
55 | TP_fast_assign( | 55 | TP_fast_assign( |
56 | __entry->fl = fl; | 56 | __entry->fl = fl ? fl : NULL; |
57 | __entry->s_dev = inode->i_sb->s_dev; | 57 | __entry->s_dev = inode->i_sb->s_dev; |
58 | __entry->i_ino = inode->i_ino; | 58 | __entry->i_ino = inode->i_ino; |
59 | __entry->fl_next = fl->fl_next; | 59 | __entry->fl_next = fl ? fl->fl_next : NULL; |
60 | __entry->fl_owner = fl->fl_owner; | 60 | __entry->fl_owner = fl ? fl->fl_owner : NULL; |
61 | __entry->fl_flags = fl->fl_flags; | 61 | __entry->fl_flags = fl ? fl->fl_flags : 0; |
62 | __entry->fl_type = fl->fl_type; | 62 | __entry->fl_type = fl ? fl->fl_type : 0; |
63 | __entry->fl_break_time = fl->fl_break_time; | 63 | __entry->fl_break_time = fl ? fl->fl_break_time : 0; |
64 | __entry->fl_downgrade_time = fl->fl_downgrade_time; | 64 | __entry->fl_downgrade_time = fl ? fl->fl_downgrade_time : 0; |
65 | ), | 65 | ), |
66 | 66 | ||
67 | TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", | 67 | TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", |