CIFS: Add cifs_set_oplock_level

Simplify many places when we need to set oplock level on an inode.

Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Pavel Shilovsky 2010-11-02 12:00:42 +03:00 committed by Steve French
parent ce2f6fb8bd
commit e66673e39a
3 changed files with 30 additions and 32 deletions

View File

@ -104,6 +104,7 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
extern u64 cifs_UnixTimeToNT(struct timespec); extern u64 cifs_UnixTimeToNT(struct timespec);
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
int offset); int offset);
extern void cifs_set_oplock_level(struct inode *inode, __u32 oplock);
extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle,
struct file *file, struct tcon_link *tlink, struct file *file, struct tcon_link *tlink,

View File

@ -146,12 +146,7 @@ client_can_cache:
rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
xid, NULL); xid, NULL);
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { cifs_set_oplock_level(inode, oplock);
pCifsInode->clientCanCacheAll = true;
pCifsInode->clientCanCacheRead = true;
cFYI(1, "Exclusive Oplock granted on inode %p", inode);
} else if ((oplock & 0xF) == OPLOCK_READ)
pCifsInode->clientCanCacheRead = true;
return rc; return rc;
} }
@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList);
spin_unlock(&cifs_file_list_lock); spin_unlock(&cifs_file_list_lock);
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { cifs_set_oplock_level(inode, oplock);
pCifsInode->clientCanCacheAll = true;
pCifsInode->clientCanCacheRead = true;
cFYI(1, "Exclusive Oplock inode %p", inode);
} else if ((oplock & 0xF) == OPLOCK_READ)
pCifsInode->clientCanCacheRead = true;
file->private_data = pCifsFile; file->private_data = pCifsFile;
return pCifsFile; return pCifsFile;
@ -271,8 +261,10 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
*/ */
void cifsFileInfo_put(struct cifsFileInfo *cifs_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 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; struct cifsLockInfo *li, *tmp;
spin_lock(&cifs_file_list_lock); spin_lock(&cifs_file_list_lock);
@ -288,8 +280,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
if (list_empty(&cifsi->openFileList)) { if (list_empty(&cifsi->openFileList)) {
cFYI(1, "closing last open instance for inode %p", cFYI(1, "closing last open instance for inode %p",
cifs_file->dentry->d_inode); cifs_file->dentry->d_inode);
cifsi->clientCanCacheRead = false; cifs_set_oplock_level(inode, 0);
cifsi->clientCanCacheAll = false;
} }
spin_unlock(&cifs_file_list_lock); spin_unlock(&cifs_file_list_lock);
@ -607,8 +598,6 @@ reopen_success:
rc = filemap_write_and_wait(inode->i_mapping); rc = filemap_write_and_wait(inode->i_mapping);
mapping_set_error(inode->i_mapping, rc); mapping_set_error(inode->i_mapping, rc);
pCifsInode->clientCanCacheAll = false;
pCifsInode->clientCanCacheRead = false;
if (tcon->unix_ext) if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&inode, rc = cifs_get_inode_info_unix(&inode,
full_path, inode->i_sb, xid); full_path, inode->i_sb, xid);
@ -622,18 +611,9 @@ reopen_success:
invalidate the current end of file on the server invalidate the current end of file on the server
we can not go to the server to get the new inod we can not go to the server to get the new inod
info */ info */
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
pCifsInode->clientCanCacheAll = true; cifs_set_oplock_level(inode, oplock);
pCifsInode->clientCanCacheRead = true;
cFYI(1, "Exclusive Oplock granted on inode %p",
pCifsFile->dentry->d_inode);
} else if ((oplock & 0xF) == OPLOCK_READ) {
pCifsInode->clientCanCacheRead = true;
pCifsInode->clientCanCacheAll = false;
} else {
pCifsInode->clientCanCacheRead = false;
pCifsInode->clientCanCacheAll = false;
}
cifs_relock_file(pCifsFile); cifs_relock_file(pCifsFile);
reopen_error_exit: reopen_error_exit:

View File

@ -569,10 +569,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
cFYI(1, "file id match, oplock break"); cFYI(1, "file id match, oplock break");
pCifsInode = CIFS_I(netfile->dentry->d_inode); pCifsInode = CIFS_I(netfile->dentry->d_inode);
pCifsInode->clientCanCacheAll = false;
if (pSMB->OplockLevel == 0)
pCifsInode->clientCanCacheRead = false;
cifs_set_oplock_level(netfile->dentry->d_inode,
pSMB->OplockLevel);
/* /*
* cifs_oplock_break_put() can't be called * cifs_oplock_break_put() can't be called
* from here. Get reference after queueing * from here. Get reference after queueing
@ -722,3 +721,21 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
cifs_sb_master_tcon(cifs_sb)->treeName); cifs_sb_master_tcon(cifs_sb)->treeName);
} }
} }
void cifs_set_oplock_level(struct inode *inode, __u32 oplock)
{
struct cifsInodeInfo *cinode = CIFS_I(inode);
if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
cinode->clientCanCacheAll = true;
cinode->clientCanCacheRead = true;
cFYI(1, "Exclusive Oplock granted on inode %p", inode);
} else if ((oplock & 0xF) == OPLOCK_READ) {
cinode->clientCanCacheAll = false;
cinode->clientCanCacheRead = true;
cFYI(1, "Level II Oplock granted on inode %p", inode);
} else {
cinode->clientCanCacheAll = false;
cinode->clientCanCacheRead = false;
}
}