Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+14 −20
Original line number Original line Diff line number Diff line
@@ -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)


	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)
}
}
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)
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);
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
	}
	}
}
}
+7 −7
Original line number Original line Diff line number Diff line
@@ -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",