diff options
Diffstat (limited to 'fs/cifs/file.c')
| -rw-r--r-- | fs/cifs/file.c | 72 | 
1 files changed, 22 insertions, 50 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..06c3e83fa387 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -146,12 +146,7 @@ client_can_cache:  		rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,  					 xid, NULL); -	if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { -		pCifsInode->clientCanCacheAll = true; -		pCifsInode->clientCanCacheRead = true; -		cFYI(1, "Exclusive Oplock granted on inode %p", inode); -	} else if ((oplock & 0xF) == OPLOCK_READ) -		pCifsInode->clientCanCacheRead = true; +	cifs_set_oplock_level(pCifsInode, oplock);  	return rc;  } @@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,  		list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList);  	spin_unlock(&cifs_file_list_lock); -	if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { -		pCifsInode->clientCanCacheAll = true; -		pCifsInode->clientCanCacheRead = true; -		cFYI(1, "Exclusive Oplock inode %p", inode); -	} else if ((oplock & 0xF) == OPLOCK_READ) -		pCifsInode->clientCanCacheRead = true; +	cifs_set_oplock_level(pCifsInode, oplock);  	file->private_data = pCifsFile;  	return pCifsFile; @@ -271,8 +261,9 @@ 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 cifsLockInfo *li, *tmp;  	spin_lock(&cifs_file_list_lock); @@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)  	if (list_empty(&cifsi->openFileList)) {  		cFYI(1, "closing last open instance for inode %p",  			cifs_file->dentry->d_inode); -		cifsi->clientCanCacheRead = false; -		cifsi->clientCanCacheAll  = false; +		cifs_set_oplock_level(cifsi, 0);  	}  	spin_unlock(&cifs_file_list_lock); @@ -607,8 +597,6 @@ reopen_success:  		rc = filemap_write_and_wait(inode->i_mapping);  		mapping_set_error(inode->i_mapping, rc); -		pCifsInode->clientCanCacheAll = false; -		pCifsInode->clientCanCacheRead = false;  		if (tcon->unix_ext)  			rc = cifs_get_inode_info_unix(&inode,  				full_path, inode->i_sb, xid); @@ -622,18 +610,9 @@ reopen_success:  	     invalidate the current end of file on the server  	     we can not go to the server to get the new inod  	     info */ -	if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { -		pCifsInode->clientCanCacheAll = true; -		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_set_oplock_level(pCifsInode, oplock); +  	cifs_relock_file(pCifsFile);  reopen_error_exit: @@ -775,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)  	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);  	tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); - -	if (file->private_data == NULL) { -		rc = -EBADF; -		FreeXid(xid); -		return rc; -	}  	netfid = ((struct cifsFileInfo *)file->private_data)->netfid;  	if ((tcon->ses->capabilities & CAP_UNIX) && @@ -956,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,  ssize_t cifs_user_write(struct file *file, const char __user *write_data,  	size_t write_size, loff_t *poffset)  { +	struct inode *inode = file->f_path.dentry->d_inode;  	int rc = 0;  	unsigned int bytes_written = 0;  	unsigned int total_written; @@ -963,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,  	struct cifsTconInfo *pTcon;  	int xid, long_op;  	struct cifsFileInfo *open_file; -	struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); +	struct cifsInodeInfo *cifsi = CIFS_I(inode);  	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); @@ -1029,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,  	cifs_stats_bytes_written(pTcon, total_written); -	/* since the write may have blocked check these pointers again */ -	if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { -		struct inode *inode = file->f_path.dentry->d_inode;  /* Do not update local mtime - server will set its actual value on write - *		inode->i_ctime = inode->i_mtime = - * 			current_fs_time(inode->i_sb);*/ -		if (total_written > 0) { -			spin_lock(&inode->i_lock); -			if (*poffset > file->f_path.dentry->d_inode->i_size) -				i_size_write(file->f_path.dentry->d_inode, -					*poffset); -			spin_unlock(&inode->i_lock); -		} -		mark_inode_dirty_sync(file->f_path.dentry->d_inode); + *	inode->i_ctime = inode->i_mtime = + * 		current_fs_time(inode->i_sb);*/ +	if (total_written > 0) { +		spin_lock(&inode->i_lock); +		if (*poffset > inode->i_size) +			i_size_write(inode, *poffset); +		spin_unlock(&inode->i_lock);  	} +	mark_inode_dirty_sync(inode); +  	FreeXid(xid);  	return total_written;  } @@ -1178,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,  					bool fsuid_only)  {  	struct cifsFileInfo *open_file; -	struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); +	struct cifs_sb_info *cifs_sb;  	bool any_available = false;  	int rc; @@ -1192,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,  		return NULL;  	} +	cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); +  	/* only filter by fsuid on multiuser mounts */  	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))  		fsuid_only = false;  |