leases: split up generic_setlease into lock/unlock cases
Eventually we should probably do the same thing to the file operations as well. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Родитель
c856694e3d
Коммит
8335ebd94b
98
fs/locks.c
98
fs/locks.c
|
@ -1352,18 +1352,7 @@ int fcntl_getlease(struct file *filp)
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* generic_setlease - sets a lease on an open file
|
||||
* @filp: file pointer
|
||||
* @arg: type of lease to obtain
|
||||
* @flp: input - file_lock to use, output - file_lock inserted
|
||||
*
|
||||
* The (input) flp->fl_lmops->lm_break function is required
|
||||
* by break_lease().
|
||||
*
|
||||
* Called with file_lock_lock held.
|
||||
*/
|
||||
int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
||||
int generic_add_lease(struct file *filp, long arg, struct file_lock **flp)
|
||||
{
|
||||
struct file_lock *fl, **before, **my_before = NULL, *lease;
|
||||
struct dentry *dentry = filp->f_path.dentry;
|
||||
|
@ -1372,29 +1361,13 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
|||
|
||||
lease = *flp;
|
||||
|
||||
error = -EACCES;
|
||||
if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
|
||||
error = -EAGAIN;
|
||||
if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
|
||||
goto out;
|
||||
error = -EINVAL;
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
if ((arg == F_WRLCK)
|
||||
&& ((dentry->d_count > 1)
|
||||
|| (atomic_read(&inode->i_count) > 1)))
|
||||
goto out;
|
||||
error = security_file_lock(filp, arg);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
time_out_leases(inode);
|
||||
|
||||
BUG_ON(!(*flp)->fl_lmops->lm_break);
|
||||
|
||||
if (arg != F_UNLCK) {
|
||||
error = -EAGAIN;
|
||||
if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
|
||||
goto out;
|
||||
if ((arg == F_WRLCK)
|
||||
&& ((dentry->d_count > 1)
|
||||
|| (atomic_read(&inode->i_count) > 1)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we know that if there is an exclusive
|
||||
|
@ -1433,9 +1406,6 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (arg == F_UNLCK)
|
||||
goto out;
|
||||
|
||||
error = -EINVAL;
|
||||
if (!leases_enable)
|
||||
goto out;
|
||||
|
@ -1446,6 +1416,62 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
|||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
int generic_delete_lease(struct file *filp, struct file_lock **flp)
|
||||
{
|
||||
struct file_lock *fl, **before;
|
||||
struct dentry *dentry = filp->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
for (before = &inode->i_flock;
|
||||
((fl = *before) != NULL) && IS_LEASE(fl);
|
||||
before = &fl->fl_next) {
|
||||
if (fl->fl_file != filp)
|
||||
continue;
|
||||
return (*flp)->fl_lmops->lm_change(before, F_UNLCK);
|
||||
}
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* generic_setlease - sets a lease on an open file
|
||||
* @filp: file pointer
|
||||
* @arg: type of lease to obtain
|
||||
* @flp: input - file_lock to use, output - file_lock inserted
|
||||
*
|
||||
* The (input) flp->fl_lmops->lm_break function is required
|
||||
* by break_lease().
|
||||
*
|
||||
* Called with file_lock_lock held.
|
||||
*/
|
||||
int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
||||
{
|
||||
struct dentry *dentry = filp->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
|
||||
if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
|
||||
return -EACCES;
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
error = security_file_lock(filp, arg);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
time_out_leases(inode);
|
||||
|
||||
BUG_ON(!(*flp)->fl_lmops->lm_break);
|
||||
|
||||
switch (arg) {
|
||||
case F_UNLCK:
|
||||
return generic_delete_lease(filp, flp);
|
||||
case F_RDLCK:
|
||||
case F_WRLCK:
|
||||
return generic_add_lease(filp, arg, flp);
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(generic_setlease);
|
||||
|
||||
static int __vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
|
||||
|
|
Загрузка…
Ссылка в новой задаче