fs/lock: Don't allocate file_lock in flock_make_lock().

Bugzilla: https://bugzilla.redhat.com/2172087

commit 4149be7bda7e1b922896599dd9cee7a3ed8cf38b
Author: Kuniyuki Iwashima <kuniyu@amazon.com>
Date:   Sat Jul 16 21:35:31 2022 -0700

    fs/lock: Don't allocate file_lock in flock_make_lock().

    Two functions, flock syscall and locks_remove_flock(), call
    flock_make_lock().  It allocates struct file_lock from slab
    cache if its argument fl is NULL.

    When we call flock syscall, we pass NULL to allocate memory
    for struct file_lock.  However, we always free it at the end
    by locks_free_lock().  We need not allocate it and instead
    should use a local variable as locks_remove_flock() does.

    Also, the validation for flock_translate_cmd() is not necessary
    for locks_remove_flock().  So we move the part to flock syscall
    and make flock_make_lock() return nothing.

    Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
    Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
    Signed-off-by: Jeff Layton <jlayton@kernel.org>

Signed-off-by: Jeffrey Layton <jlayton@redhat.com>
This commit is contained in:
Jeffrey Layton 2023-02-21 09:06:14 -05:00
parent 6f597cadf4
commit 308465efa3
1 changed files with 16 additions and 32 deletions

View File

@ -395,21 +395,9 @@ static inline int flock_translate_cmd(int cmd) {
}
/* Fill in a file_lock structure with an appropriate FLOCK lock. */
static struct file_lock *
flock_make_lock(struct file *filp, unsigned int cmd, struct file_lock *fl)
static void flock_make_lock(struct file *filp, struct file_lock *fl, int type)
{
int type = flock_translate_cmd(cmd);
if (type < 0)
return ERR_PTR(type);
if (fl == NULL) {
fl = locks_alloc_lock();
if (fl == NULL)
return ERR_PTR(-ENOMEM);
} else {
locks_init_lock(fl);
}
locks_init_lock(fl);
fl->fl_file = filp;
fl->fl_owner = filp;
@ -417,8 +405,6 @@ flock_make_lock(struct file *filp, unsigned int cmd, struct file_lock *fl)
fl->fl_flags = FL_FLOCK;
fl->fl_type = type;
fl->fl_end = OFFSET_MAX;
return fl;
}
static int assign_type(struct file_lock *fl, long type)
@ -2069,10 +2055,9 @@ EXPORT_SYMBOL(locks_lock_inode_wait);
*/
SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{
int can_sleep, error, unlock, type;
struct fd f = fdget(fd);
struct file_lock *lock;
int can_sleep, unlock;
int error;
struct file_lock fl;
error = -EBADF;
if (!f.file)
@ -2099,28 +2084,27 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
goto out_putf;
}
lock = flock_make_lock(f.file, cmd, NULL);
if (IS_ERR(lock)) {
error = PTR_ERR(lock);
type = flock_translate_cmd(cmd);
if (type < 0) {
error = type;
goto out_putf;
}
if (can_sleep)
lock->fl_flags |= FL_SLEEP;
flock_make_lock(f.file, &fl, type);
error = security_file_lock(f.file, lock->fl_type);
if (can_sleep)
fl.fl_flags |= FL_SLEEP;
error = security_file_lock(f.file, fl.fl_type);
if (error)
goto out_free;
goto out_putf;
if (f.file->f_op->flock)
error = f.file->f_op->flock(f.file,
(can_sleep) ? F_SETLKW : F_SETLK,
lock);
&fl);
else
error = locks_lock_file_wait(f.file, lock);
out_free:
locks_free_lock(lock);
error = locks_lock_file_wait(f.file, &fl);
out_putf:
fdput(f);
@ -2586,7 +2570,7 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
if (list_empty(&flctx->flc_flock))
return;
flock_make_lock(filp, LOCK_UN, &fl);
flock_make_lock(filp, &fl, F_UNLCK);
fl.fl_flags |= FL_CLOSE;
if (filp->f_op->flock)