Commit 0efaa7e8 authored by Jeff Layton's avatar Jeff Layton

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: default avatarJeff Layton <jlayton@primarydata.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 415b96c5
...@@ -1637,22 +1637,23 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp ...@@ -1637,22 +1637,23 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
return error; return error;
} }
static int generic_delete_lease(struct file *filp, struct file_lock **flp) static int generic_delete_lease(struct file *filp)
{ {
int error = -EAGAIN;
struct file_lock *fl, **before; struct file_lock *fl, **before;
struct dentry *dentry = filp->f_path.dentry; struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
trace_generic_delete_lease(inode, *flp);
for (before = &inode->i_flock; for (before = &inode->i_flock;
((fl = *before) != NULL) && IS_LEASE(fl); ((fl = *before) != NULL) && IS_LEASE(fl);
before = &fl->fl_next) { before = &fl->fl_next) {
if (fl->fl_file != filp) if (fl->fl_file == filp)
continue; break;
return (*flp)->fl_lmops->lm_change(before, F_UNLCK);
} }
return -EAGAIN; trace_generic_delete_lease(inode, fl);
if (fl)
error = fl->fl_lmops->lm_change(before, F_UNLCK);
return error;
} }
/** /**
...@@ -1682,13 +1683,15 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) ...@@ -1682,13 +1683,15 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
time_out_leases(inode); time_out_leases(inode);
BUG_ON(!(*flp)->fl_lmops->lm_break);
switch (arg) { switch (arg) {
case F_UNLCK: case F_UNLCK:
return generic_delete_lease(filp, flp); return generic_delete_lease(filp);
case F_RDLCK: case F_RDLCK:
case F_WRLCK: case F_WRLCK:
if (!(*flp)->fl_lmops->lm_break) {
WARN_ON_ONCE(1);
return -ENOLCK;
}
return generic_add_lease(filp, arg, flp); return generic_add_lease(filp, arg, flp);
default: default:
return -EINVAL; return -EINVAL;
...@@ -1744,15 +1747,6 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease) ...@@ -1744,15 +1747,6 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
} }
EXPORT_SYMBOL_GPL(vfs_setlease); EXPORT_SYMBOL_GPL(vfs_setlease);
static int do_fcntl_delete_lease(struct file *filp)
{
struct file_lock fl, *flp = &fl;
lease_init(filp, F_UNLCK, flp);
return vfs_setlease(filp, F_UNLCK, &flp);
}
static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
{ {
struct file_lock *fl, *ret; struct file_lock *fl, *ret;
...@@ -1809,7 +1803,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) ...@@ -1809,7 +1803,7 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
int fcntl_setlease(unsigned int fd, struct file *filp, long arg) int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
{ {
if (arg == F_UNLCK) if (arg == F_UNLCK)
return do_fcntl_delete_lease(filp); return vfs_setlease(filp, F_UNLCK, NULL);
return do_fcntl_add_lease(fd, filp, arg); return do_fcntl_add_lease(fd, filp, arg);
} }
......
...@@ -690,7 +690,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp) ...@@ -690,7 +690,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
spin_unlock(&fp->fi_lock); spin_unlock(&fp->fi_lock);
if (filp) { if (filp) {
vfs_setlease(filp, F_UNLCK, &fl); vfs_setlease(filp, F_UNLCK, NULL);
fput(filp); fput(filp);
} }
} }
......
...@@ -53,15 +53,15 @@ DECLARE_EVENT_CLASS(filelock_lease, ...@@ -53,15 +53,15 @@ DECLARE_EVENT_CLASS(filelock_lease,
), ),
TP_fast_assign( TP_fast_assign(
__entry->fl = fl; __entry->fl = fl ? fl : NULL;
__entry->s_dev = inode->i_sb->s_dev; __entry->s_dev = inode->i_sb->s_dev;
__entry->i_ino = inode->i_ino; __entry->i_ino = inode->i_ino;
__entry->fl_next = fl->fl_next; __entry->fl_next = fl ? fl->fl_next : NULL;
__entry->fl_owner = fl->fl_owner; __entry->fl_owner = fl ? fl->fl_owner : NULL;
__entry->fl_flags = fl->fl_flags; __entry->fl_flags = fl ? fl->fl_flags : 0;
__entry->fl_type = fl->fl_type; __entry->fl_type = fl ? fl->fl_type : 0;
__entry->fl_break_time = fl->fl_break_time; __entry->fl_break_time = fl ? fl->fl_break_time : 0;
__entry->fl_downgrade_time = fl->fl_downgrade_time; __entry->fl_downgrade_time = fl ? fl->fl_downgrade_time : 0;
), ),
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", 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",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment