lkml.org 
[lkml]   [2010]   [Oct]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/4] locks: prevent ENOMEM on lease unlock
    Date
    Removing a lock shouldn't require any allocations; a failure due to
    ENOMEM leaves the caller with a choice between retrying or giving up and
    leaking an unused lease.

    Next we should split the other lease calls into add and delete cases.
    I wanted to start with just the bugfix.

    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    ---
    fs/locks.c | 43 ++++++++++++++++++++++++++++++-------------
    1 files changed, 30 insertions(+), 13 deletions(-)

    diff --git a/fs/locks.c b/fs/locks.c
    index 50ec159..06c7773 100644
    --- a/fs/locks.c
    +++ b/fs/locks.c
    @@ -1441,7 +1441,8 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
    return 0;

    out:
    - locks_free_lock(lease);
    + if (arg != F_UNLCK)
    + locks_free_lock(lease);
    return error;
    }
    EXPORT_SYMBOL(generic_setlease);
    @@ -1493,17 +1494,16 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
    }
    EXPORT_SYMBOL_GPL(vfs_setlease);

    -/**
    - * fcntl_setlease - sets a lease on an open file
    - * @fd: open file descriptor
    - * @filp: file pointer
    - * @arg: type of lease to obtain
    - *
    - * Call this fcntl to establish a lease on the file.
    - * Note that you also need to call %F_SETSIG to
    - * receive a signal when the lease is broken.
    - */
    -int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
    +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)
    {
    struct file_lock *fl;
    struct fasync_struct *new;
    @@ -1521,7 +1521,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
    }
    lock_flocks();
    error = __vfs_setlease(filp, arg, &fl);
    - if (error || arg == F_UNLCK)
    + if (error)
    goto out_unlock;

    /*
    @@ -1550,6 +1550,23 @@ out_unlock:
    }

    /**
    + * fcntl_setlease - sets a lease on an open file
    + * @fd: open file descriptor
    + * @filp: file pointer
    + * @arg: type of lease to obtain
    + *
    + * Call this fcntl to establish a lease on the file.
    + * Note that you also need to call %F_SETSIG to
    + * receive a signal when the lease is broken.
    + */
    +int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
    +{
    + if (arg == F_UNLCK)
    + return do_fcntl_delete_lease(filp);
    + return do_fcntl_add_lease(fd, filp, arg);
    +}
    +
    +/**
    * flock_lock_file_wait - Apply a FLOCK-style lock to a file
    * @filp: The file to apply the lock to
    * @fl: The lock to be applied
    --
    1.7.1


    \
     
     \ /
      Last update: 2010-10-30 23:35    [W:0.030 / U:29.804 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site