Re: [PATCH 2/4] CIFS: Invalidate inode pages on the last close

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

 



2010/10/26 Jeff Layton <jlayton@xxxxxxxxxx>:
> On Tue, 26 Oct 2010 17:01:26 +0400
> Pavel Shilovsky <piastryyy@xxxxxxxxx> wrote:
>
>> When we close the last file handle of the inode we should invalidate it
>> to prevent data coherency problem when we open it again but it has been
>> modified by other clients.
>>
>> Signed-off-by: Pavel Shilovsky <piastryyy@xxxxxxxxx>
>> ---
>>  fs/cifs/file.c |   14 ++++++++++++--
>>  1 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index d7c212a..02a045e 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -150,8 +150,14 @@ client_can_cache:
>>               pCifsInode->clientCanCacheAll = true;
>>               pCifsInode->clientCanCacheRead = true;
>>               cFYI(1, "Exclusive Oplock granted on inode %p", inode);
>> -     } else if ((oplock & 0xF) == OPLOCK_READ)
>> +     } else if ((oplock & 0xF) == OPLOCK_READ) {
>> +             pCifsInode->clientCanCacheAll = false;
>>               pCifsInode->clientCanCacheRead = true;
>> +             cFYI(1, "Level II Oplock franted on inode %p", inode);
>> +     } else {
>> +             pCifsInode->clientCanCacheAll = false;
>> +             pCifsInode->clientCanCacheRead = false;
>> +     }
>>
>
> The oplock handling in cifs is rather ad-hoc. There's a lot of
> cut-and-pasted code that sets that clientCanCache flags. The flags
> themselves are also sort of hard to understand -- i.e. why is is "All"
> and not "Write"?
>
> This would be good opportunity to consolidate that code into helper
> functions and just call them from the appropriate places.

Good idea. I will try to do it.

>
> Perhaps a helper function that takes an oplock value and sets the
> clientCanCache flags appropriately? Or...maybe consider doing away with
> the canCache flags and just store the oplock value in the inode and
> have helper macros or something that read that value and tell you what
> can be done with it.
>
>   i.e.: CLIENT_CAN_CACHE_READ(inode), CLIENT_CAN_CACHE_WRITE(inode)
>
>
>
>>       return rc;
>>  }
>> @@ -271,8 +277,10 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
>>   */
>>  void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
>>  {
>> +     struct inode *inode = cifs_file->dentry->d_inode;
>>       struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
>> -     struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode);
>> +     struct cifsInodeInfo *cifsi = CIFS_I(inode);
>> +     struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
>>       struct cifsLockInfo *li, *tmp;
>>
>>       spin_lock(&cifs_file_list_lock);
>> @@ -290,6 +298,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
>>                       cifs_file->dentry->d_inode);
>>               cifsi->clientCanCacheRead = false;
>>               cifsi->clientCanCacheAll  = false;
>> +             if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
>> +                     invalidate_remote_inode(inode);
>                                ^^^^^^^^
>                I don't think it's safe to call this under a spinlock.
>                It would probably be better instead to flag the inode
>                as needing invalidation by setting the
>                invalidate_mapping flag to true.
>

At first I was going not to do it under a spinlock, but Wine
application suddently crashes in this case. So, I didn't understand
the reason of so strange behavior and leave it under the spinlock - it
works well.

>>       }
>>       spin_unlock(&cifs_file_list_lock);
>>

-- 
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