Re: [PATCH 2/3] CIFS: Simplify setlk error handling for mandatory locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2011/10/31 Jeff Layton <jlayton@xxxxxxxxxxxxxxx>:
> On Sat, 29 Oct 2011 17:17:58 +0400
> Pavel Shilovsky <piastry@xxxxxxxxxxx> wrote:
>
>> Now we allocate a lock structure at first, then we request to the server
>> and save the lock if server returned OK though void function - it prevents
>> the situation when we locked a file on the server and then return -ENOMEM
>> from setlk.
>>
>> Signed-off-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>
>> ---
>>  fs/cifs/file.c |   64 ++++++++++++++++++++++++++++----------------------------
>>  1 files changed, 32 insertions(+), 32 deletions(-)
>>
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index c1f063c..d9cc07f 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -672,7 +672,7 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock)
>>  }
>>
>>  static bool
>> -cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
>> +__cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
>>                       __u64 length, __u8 type, __u16 netfid,
>>                       struct cifsLockInfo **conf_lock)
>>  {
>> @@ -694,6 +694,14 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
>>       return false;
>>  }
>>
>> +static bool
>> +cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
>> +                     struct cifsLockInfo **conf_lock)
>> +{
>> +     return __cifs_find_lock_conflict(cinode, lock->offset, lock->length,
>> +                                      lock->type, lock->netfid, conf_lock);
>> +}
>> +
>>  static int
>>  cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
>>              __u8 type, __u16 netfid, struct file_lock *flock)
>> @@ -704,8 +712,8 @@ cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
>>
>>       mutex_lock(&cinode->lock_mutex);
>>
>> -     exist = cifs_find_lock_conflict(cinode, offset, length, type, netfid,
>> -                                     &conf_lock);
>> +     exist = __cifs_find_lock_conflict(cinode, offset, length, type, netfid,
>> +                                       &conf_lock);
>>       if (exist) {
>>               flock->fl_start = conf_lock->offset;
>>               flock->fl_end = conf_lock->offset + conf_lock->length - 1;
>> @@ -723,40 +731,27 @@ cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
>>       return rc;
>>  }
>>
>> -static int
>> -cifs_lock_add(struct cifsInodeInfo *cinode, __u64 len, __u64 offset,
>> -           __u8 type, __u16 netfid)
>> +static void
>> +cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock)
>>  {
>> -     struct cifsLockInfo *li;
>> -
>> -     li = cifs_lock_init(len, offset, type, netfid);
>> -     if (!li)
>> -             return -ENOMEM;
>> -
>>       mutex_lock(&cinode->lock_mutex);
>> -     list_add_tail(&li->llist, &cinode->llist);
>> +     list_add_tail(&lock->llist, &cinode->llist);
>>       mutex_unlock(&cinode->lock_mutex);
>> -     return 0;
>>  }
>>
>>  static int
>> -cifs_lock_add_if(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
>> -              __u8 type, __u16 netfid, bool wait)
>> +cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
>> +              bool wait)
>>  {
>> -     struct cifsLockInfo *lock, *conf_lock;
>> +     struct cifsLockInfo *conf_lock;
>>       bool exist;
>>       int rc = 0;
>>
>> -     lock = cifs_lock_init(length, offset, type, netfid);
>> -     if (!lock)
>> -             return -ENOMEM;
>> -
>>  try_again:
>>       exist = false;
>>       mutex_lock(&cinode->lock_mutex);
>>
>> -     exist = cifs_find_lock_conflict(cinode, offset, length, type, netfid,
>> -                                     &conf_lock);
>> +     exist = cifs_find_lock_conflict(cinode, lock, &conf_lock);
>>       if (!exist && cinode->can_cache_brlcks) {
>>               list_add_tail(&lock->llist, &cinode->llist);
>>               mutex_unlock(&cinode->lock_mutex);
>> @@ -781,7 +776,6 @@ try_again:
>>               }
>>       }
>>
>> -     kfree(lock);
>>       mutex_unlock(&cinode->lock_mutex);
>>       return rc;
>>  }
>> @@ -1254,20 +1248,26 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
>>       }
>>
>>       if (lock) {
>> -             rc = cifs_lock_add_if(cinode, flock->fl_start, length,
>> -                                   type, netfid, wait_flag);
>> +             struct cifsLockInfo *lock;
>> +
>> +             lock = cifs_lock_init(length, flock->fl_start, type, netfid);
>> +             if (!lock)
>> +                     return -ENOMEM;
>> +
>> +             rc = cifs_lock_add_if(cinode, lock, wait_flag);
>
> Here, you're adding "lock" to the list...

If we added the lock to the list cifs_lock_add_if returns 0 and we
will jump to out label.

>
>>               if (rc < 0)
>> -                     return rc;
>> -             else if (!rc)
>> +                     kfree(lock);
>> +             if (rc <= 0)
>>                       goto out;
>>
>>               rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
>>                                flock->fl_start, 0, 1, type, wait_flag, 0);
>> -             if (rc == 0) {
>> -                     /* For Windows locks we must store them. */
>> -                     rc = cifs_lock_add(cinode, length, flock->fl_start,
>> -                                        type, netfid);
>> +             if (rc) {
>> +                     kfree(lock);
>
> ...and here you're freeing "lock" without removing it from the list.
> Isn't that like to cause a problem?

So, if CIFSSMBLock returns a error we free the lock that hasn't been
added to the list. If CIFSSMBLock returns ok, we will add it to the
list with cifs_lock_add void function.

Seems no problem with it.

-- 
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux