Re: [ 10/41] CIFS: Do not kmalloc under the flocks spinlock
From: Pavel Shilovsky
Date: Sat Mar 17 2012 - 02:14:30 EST
17 марта 2012 г. 6:37 пользователь Ben Hutchings <ben@xxxxxxxxxxxxxxx> написал:
> On Fri, Mar 16, 2012 at 04:38:20PM -0700, Greg KH wrote:
>> 3.2-stable review patch. If anyone has any objections, please let me know.
>>
>> ------------------
>>
>> From: Pavel Shilovsky <piastry@xxxxxxxxxxx>
>>
>> commit d5751469f210d2149cc2159ffff66cbeef6da3f2 upstream.
>>
>> Reorganize the code to make the memory already allocated before
>> spinlock'ed loop.
>>
>> Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>
>> Signed-off-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>
>> Signed-off-by: Steve French <sfrench@xxxxxxxxxx>
>> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
>>
>> ---
>> fs/cifs/file.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++-----------
>> 1 file changed, 56 insertions(+), 13 deletions(-)
>>
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
> [....]
>> @@ -940,29 +950,55 @@ cifs_push_posix_locks(struct cifsFileInf
>> return rc;
>> }
>>
>> + lock_flocks();
>> + cifs_for_each_lock(cfile->dentry->d_inode, before) {
>> + if ((*before)->fl_flags & FL_POSIX)
>> + count++;
>> + }
>> + unlock_flocks();
>> +
>> INIT_LIST_HEAD(&locks_to_send);
>>
>> + /*
>> + * Allocating count locks is enough because no locks can be added to
>> + * the list while we are holding cinode->lock_mutex that protects
>> + * locking operations of this inode.
>> + */
>> + for (; i < count; i++) {
>> + lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
>> + if (!lck) {
>> + rc = -ENOMEM;
>> + goto err_out;
>> + }
>> + list_add_tail(&lck->llist, &locks_to_send);
>> + }
>> +
>> + i = 0;
>> + el = locks_to_send.next;
>> lock_flocks();
>> cifs_for_each_lock(cfile->dentry->d_inode, before) {
>> + if (el == &locks_to_send) {
>> + /* something is really wrong */
>> + cERROR(1, "Can't push all brlocks!");
>> + break;
>> + }
>> flock = *before;
>> + if ((flock->fl_flags & FL_POSIX) == 0)
>> + continue;
> [...]
>
> If I understand the logic correctly, el == &locks_to_send means we
> already used all the lock_to_push structures. (It should also be
> equivalent to testing i == count. Why is i incremented but not
> otherwise used in the loop?)
>
> But we test this before flock->fl_flags & FL_POSIX, which means we
> don't know whether this lock actually needs to be assigned one of
> those structures. So it appears that we might report a spurious error
> if the lock list ends with a mandatory lock. If so, this is
> relatively harmless but does need to be fixed.
>
You are right here, thanks for the catch! I will repost the patch asap.
--
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/