CIFS: Replace clientCanCache* bools with an integer
that prepare the code to handle different types of SMB2 leases. Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
		
							parent
							
								
									77993be3f3
								
							
						
					
					
						commit
						18cceb6a78
					
				| @ -733,7 +733,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||||
| 
 | ||||
| 	written = generic_file_aio_write(iocb, iov, nr_segs, pos); | ||||
| 
 | ||||
| 	if (CIFS_I(inode)->clientCanCacheAll) | ||||
| 	if (CIFS_CACHE_WRITE(CIFS_I(inode))) | ||||
| 		return written; | ||||
| 
 | ||||
| 	rc = filemap_fdatawrite(inode->i_mapping); | ||||
| @ -758,7 +758,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | ||||
| 		 * We need to be sure that all dirty pages are written and the | ||||
| 		 * server has the newest file length. | ||||
| 		 */ | ||||
| 		if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && | ||||
| 		if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && | ||||
| 		    inode->i_mapping->nrpages != 0) { | ||||
| 			rc = filemap_fdatawait(inode->i_mapping); | ||||
| 			if (rc) { | ||||
| @ -782,8 +782,10 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | ||||
| 
 | ||||
| static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | ||||
| { | ||||
| 	/* note that this is called by vfs setlease with i_lock held
 | ||||
| 	   to protect *lease from going away */ | ||||
| 	/*
 | ||||
| 	 * Note that this is called by vfs setlease with i_lock held to | ||||
| 	 * protect *lease from going away. | ||||
| 	 */ | ||||
| 	struct inode *inode = file_inode(file); | ||||
| 	struct cifsFileInfo *cfile = file->private_data; | ||||
| 
 | ||||
| @ -791,20 +793,19 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	/* check if file is oplocked */ | ||||
| 	if (((arg == F_RDLCK) && | ||||
| 		(CIFS_I(inode)->clientCanCacheRead)) || | ||||
| 	    ((arg == F_WRLCK) && | ||||
| 		(CIFS_I(inode)->clientCanCacheAll))) | ||||
| 	if (((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || | ||||
| 	    ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) | ||||
| 		return generic_setlease(file, arg, lease); | ||||
| 	else if (tlink_tcon(cfile->tlink)->local_lease && | ||||
| 		 !CIFS_I(inode)->clientCanCacheRead) | ||||
| 		/* If the server claims to support oplock on this
 | ||||
| 		   file, then we still need to check oplock even | ||||
| 		   if the local_lease mount option is set, but there | ||||
| 		   are servers which do not support oplock for which | ||||
| 		   this mount option may be useful if the user | ||||
| 		   knows that the file won't be changed on the server | ||||
| 		   by anyone else */ | ||||
| 		 !CIFS_CACHE_READ(CIFS_I(inode))) | ||||
| 		/*
 | ||||
| 		 * If the server claims to support oplock on this file, then we | ||||
| 		 * still need to check oplock even if the local_lease mount | ||||
| 		 * option is set, but there are servers which do not support | ||||
| 		 * oplock for which this mount option may be useful if the user | ||||
| 		 * knows that the file won't be changed on the server by anyone | ||||
| 		 * else. | ||||
| 		 */ | ||||
| 		return generic_setlease(file, arg, lease); | ||||
| 	else | ||||
| 		return -EAGAIN; | ||||
|  | ||||
| @ -1031,6 +1031,13 @@ cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file) | ||||
| struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file); | ||||
| void cifsFileInfo_put(struct cifsFileInfo *cifs_file); | ||||
| 
 | ||||
| #define CIFS_CACHE_READ_FLG	1 | ||||
| #define CIFS_CACHE_HANDLE_FLG	2 | ||||
| #define CIFS_CACHE_WRITE_FLG	4 | ||||
| 
 | ||||
| #define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) | ||||
| #define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) | ||||
| 
 | ||||
| /*
 | ||||
|  * One of these for each file inode | ||||
|  */ | ||||
| @ -1042,8 +1049,7 @@ struct cifsInodeInfo { | ||||
| 	/* BB add in lists for dirty pages i.e. write caching info for oplock */ | ||||
| 	struct list_head openFileList; | ||||
| 	__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ | ||||
| 	bool clientCanCacheRead;	/* read oplock */ | ||||
| 	bool clientCanCacheAll;		/* read and writebehind oplock */ | ||||
| 	unsigned int oplock;		/* oplock/lease level we have */ | ||||
| 	bool delete_pending;		/* DELETE_ON_CLOSE is set */ | ||||
| 	bool invalid_mapping;		/* pagecache is invalid */ | ||||
| 	unsigned long time;		/* jiffies of last update of inode */ | ||||
|  | ||||
| @ -1524,12 +1524,12 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, | ||||
| 		 * read won't conflict with non-overlapted locks due to | ||||
| 		 * pagereading. | ||||
| 		 */ | ||||
| 		if (!CIFS_I(inode)->clientCanCacheAll && | ||||
| 					CIFS_I(inode)->clientCanCacheRead) { | ||||
| 		if (!CIFS_CACHE_WRITE(CIFS_I(inode)) && | ||||
| 					CIFS_CACHE_READ(CIFS_I(inode))) { | ||||
| 			cifs_invalidate_mapping(inode); | ||||
| 			cifs_dbg(FYI, "Set no oplock for inode=%p due to mand locks\n", | ||||
| 				 inode); | ||||
| 			CIFS_I(inode)->clientCanCacheRead = false; | ||||
| 			CIFS_I(inode)->oplock = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, | ||||
| @ -2213,7 +2213,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, | ||||
| 	cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", | ||||
| 		 file->f_path.dentry->d_name.name, datasync); | ||||
| 
 | ||||
| 	if (!CIFS_I(inode)->clientCanCacheRead) { | ||||
| 	if (!CIFS_CACHE_READ(CIFS_I(inode))) { | ||||
| 		rc = cifs_invalidate_mapping(inode); | ||||
| 		if (rc) { | ||||
| 			cifs_dbg(FYI, "rc: %d during invalidate phase\n", rc); | ||||
| @ -2577,7 +2577,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | ||||
| 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||||
| 	ssize_t written; | ||||
| 
 | ||||
| 	if (cinode->clientCanCacheAll) { | ||||
| 	if (CIFS_CACHE_WRITE(cinode)) { | ||||
| 		if (cap_unix(tcon->ses) && | ||||
| 		(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) | ||||
| 		    && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | ||||
| @ -2591,7 +2591,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | ||||
| 	 * these pages but not on the region from pos to ppos+len-1. | ||||
| 	 */ | ||||
| 	written = cifs_user_writev(iocb, iov, nr_segs, pos); | ||||
| 	if (written > 0 && cinode->clientCanCacheRead) { | ||||
| 	if (written > 0 && CIFS_CACHE_READ(cinode)) { | ||||
| 		/*
 | ||||
| 		 * Windows 7 server can delay breaking level2 oplock if a write | ||||
| 		 * request comes - break it on the client to prevent reading | ||||
| @ -2600,7 +2600,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | ||||
| 		cifs_invalidate_mapping(inode); | ||||
| 		cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", | ||||
| 			 inode); | ||||
| 		cinode->clientCanCacheRead = false; | ||||
| 		cinode->oplock = 0; | ||||
| 	} | ||||
| 	return written; | ||||
| } | ||||
| @ -2957,7 +2957,7 @@ cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov, | ||||
| 	 * on pages affected by this read but not on the region from pos to | ||||
| 	 * pos+len-1. | ||||
| 	 */ | ||||
| 	if (!cinode->clientCanCacheRead) | ||||
| 	if (!CIFS_CACHE_READ(cinode)) | ||||
| 		return cifs_user_readv(iocb, iov, nr_segs, pos); | ||||
| 
 | ||||
| 	if (cap_unix(tcon->ses) && | ||||
| @ -3093,7 +3093,7 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) | ||||
| 
 | ||||
| 	xid = get_xid(); | ||||
| 
 | ||||
| 	if (!CIFS_I(inode)->clientCanCacheRead) { | ||||
| 	if (!CIFS_CACHE_READ(CIFS_I(inode))) { | ||||
| 		rc = cifs_invalidate_mapping(inode); | ||||
| 		if (rc) | ||||
| 			return rc; | ||||
| @ -3526,7 +3526,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping, | ||||
| 	 * is, when the page lies beyond the EOF, or straddles the EOF | ||||
| 	 * and the write will cover all of the existing data. | ||||
| 	 */ | ||||
| 	if (CIFS_I(mapping->host)->clientCanCacheRead) { | ||||
| 	if (CIFS_CACHE_READ(CIFS_I(mapping->host))) { | ||||
| 		i_size = i_size_read(mapping->host); | ||||
| 		if (page_start >= i_size || | ||||
| 		    (offset == 0 && (pos + len) >= i_size)) { | ||||
| @ -3609,20 +3609,20 @@ void cifs_oplock_break(struct work_struct *work) | ||||
| 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | ||||
| 	int rc = 0; | ||||
| 
 | ||||
| 	if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead && | ||||
| 	if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && | ||||
| 						cifs_has_mand_locks(cinode)) { | ||||
| 		cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", | ||||
| 			 inode); | ||||
| 		cinode->clientCanCacheRead = false; | ||||
| 		cinode->oplock = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (inode && S_ISREG(inode->i_mode)) { | ||||
| 		if (cinode->clientCanCacheRead) | ||||
| 		if (CIFS_CACHE_READ(cinode)) | ||||
| 			break_lease(inode, O_RDONLY); | ||||
| 		else | ||||
| 			break_lease(inode, O_WRONLY); | ||||
| 		rc = filemap_fdatawrite(inode->i_mapping); | ||||
| 		if (cinode->clientCanCacheRead == 0) { | ||||
| 		if (!CIFS_CACHE_READ(cinode)) { | ||||
| 			rc = filemap_fdatawait(inode->i_mapping); | ||||
| 			mapping_set_error(inode->i_mapping, rc); | ||||
| 			cifs_invalidate_mapping(inode); | ||||
|  | ||||
| @ -101,7 +101,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) | ||||
| 	} | ||||
| 
 | ||||
| 	/* don't bother with revalidation if we have an oplock */ | ||||
| 	if (cifs_i->clientCanCacheRead) { | ||||
| 	if (CIFS_CACHE_READ(cifs_i)) { | ||||
| 		cifs_dbg(FYI, "%s: inode %llu is oplocked\n", | ||||
| 			 __func__, cifs_i->uniqueid); | ||||
| 		return; | ||||
| @ -650,7 +650,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | ||||
| 	cifs_dbg(FYI, "Getting info on %s\n", full_path); | ||||
| 
 | ||||
| 	if ((data == NULL) && (*inode != NULL)) { | ||||
| 		if (CIFS_I(*inode)->clientCanCacheRead) { | ||||
| 		if (CIFS_CACHE_READ(CIFS_I(*inode))) { | ||||
| 			cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); | ||||
| 			goto cgii_exit; | ||||
| 		} | ||||
| @ -1661,7 +1661,7 @@ cifs_inode_needs_reval(struct inode *inode) | ||||
| 	struct cifsInodeInfo *cifs_i = CIFS_I(inode); | ||||
| 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||||
| 
 | ||||
| 	if (cifs_i->clientCanCacheRead) | ||||
| 	if (CIFS_CACHE_READ(cifs_i)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (!lookupCacheEnabled) | ||||
| @ -1804,7 +1804,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||||
| 	 * We need to be sure that all dirty pages are written and the server | ||||
| 	 * has actual ctime, mtime and file length. | ||||
| 	 */ | ||||
| 	if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && | ||||
| 	if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && | ||||
| 	    inode->i_mapping->nrpages != 0) { | ||||
| 		rc = filemap_fdatawait(inode->i_mapping); | ||||
| 		if (rc) { | ||||
|  | ||||
| @ -546,19 +546,15 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | ||||
| 	oplock &= 0xF; | ||||
| 
 | ||||
| 	if (oplock == OPLOCK_EXCLUSIVE) { | ||||
| 		cinode->clientCanCacheAll = true; | ||||
| 		cinode->clientCanCacheRead = true; | ||||
| 		cinode->oplock = CIFS_CACHE_WRITE_FLG | CIFS_CACHE_READ_FLG; | ||||
| 		cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", | ||||
| 			 &cinode->vfs_inode); | ||||
| 	} else if (oplock == OPLOCK_READ) { | ||||
| 		cinode->clientCanCacheAll = false; | ||||
| 		cinode->clientCanCacheRead = true; | ||||
| 		cinode->oplock = CIFS_CACHE_READ_FLG; | ||||
| 		cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", | ||||
| 			 &cinode->vfs_inode); | ||||
| 	} else { | ||||
| 		cinode->clientCanCacheAll = false; | ||||
| 		cinode->clientCanCacheRead = false; | ||||
| 	} | ||||
| 	} else | ||||
| 		cinode->oplock = 0; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
|  | ||||
| @ -700,7 +700,7 @@ cifs_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) | ||||
| 	struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); | ||||
| 	cfile->fid.netfid = fid->netfid; | ||||
| 	cifs_set_oplock_level(cinode, oplock); | ||||
| 	cinode->can_cache_brlcks = cinode->clientCanCacheAll; | ||||
| 	cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -837,7 +837,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, | ||||
| { | ||||
| 	return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0, | ||||
| 			   LOCKING_ANDX_OPLOCK_RELEASE, false, | ||||
| 			   cinode->clientCanCacheRead ? 1 : 0); | ||||
| 			   CIFS_CACHE_READ(cinode) ? 1 : 0); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | ||||
| @ -40,21 +40,21 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | ||||
| 	oplock &= 0xFF; | ||||
| 	if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) | ||||
| 		return; | ||||
| 	if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE || | ||||
| 	    oplock == SMB2_OPLOCK_LEVEL_BATCH) { | ||||
| 		cinode->clientCanCacheAll = true; | ||||
| 		cinode->clientCanCacheRead = true; | ||||
| 	if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { | ||||
| 		cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG | | ||||
| 				 CIFS_CACHE_HANDLE_FLG; | ||||
| 		cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", | ||||
| 			 &cinode->vfs_inode); | ||||
| 	} else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { | ||||
| 		cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG; | ||||
| 		cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", | ||||
| 			 &cinode->vfs_inode); | ||||
| 	} else if (oplock == SMB2_OPLOCK_LEVEL_II) { | ||||
| 		cinode->clientCanCacheAll = false; | ||||
| 		cinode->clientCanCacheRead = true; | ||||
| 		cinode->oplock = CIFS_CACHE_READ_FLG; | ||||
| 		cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", | ||||
| 			 &cinode->vfs_inode); | ||||
| 	} else { | ||||
| 		cinode->clientCanCacheAll = false; | ||||
| 		cinode->clientCanCacheRead = false; | ||||
| 	} | ||||
| 	} else | ||||
| 		cinode->oplock = 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | ||||
| @ -380,9 +380,9 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) | ||||
| __le32 | ||||
| smb2_get_lease_state(struct cifsInodeInfo *cinode) | ||||
| { | ||||
| 	if (cinode->clientCanCacheAll) | ||||
| 	if (CIFS_CACHE_WRITE(cinode)) | ||||
| 		return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING; | ||||
| 	else if (cinode->clientCanCacheRead) | ||||
| 	else if (CIFS_CACHE_READ(cinode)) | ||||
| 		return SMB2_LEASE_READ_CACHING; | ||||
| 	return 0; | ||||
| } | ||||
| @ -576,7 +576,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) | ||||
| 				cifs_dbg(FYI, "file id match, oplock break\n"); | ||||
| 				cinode = CIFS_I(cfile->dentry->d_inode); | ||||
| 
 | ||||
| 				if (!cinode->clientCanCacheAll && | ||||
| 				if (!CIFS_CACHE_WRITE(cinode) && | ||||
| 				    rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE) | ||||
| 					cfile->oplock_break_cancelled = true; | ||||
| 				else | ||||
|  | ||||
| @ -380,7 +380,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) | ||||
| 	cfile->fid.persistent_fid = fid->persistent_fid; | ||||
| 	cfile->fid.volatile_fid = fid->volatile_fid; | ||||
| 	smb2_set_oplock_level(cinode, oplock); | ||||
| 	cinode->can_cache_brlcks = cinode->clientCanCacheAll; | ||||
| 	cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -531,7 +531,7 @@ smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, | ||||
| 
 | ||||
| 	return SMB2_oplock_break(0, tcon, fid->persistent_fid, | ||||
| 				 fid->volatile_fid, | ||||
| 				 cinode->clientCanCacheRead ? 1 : 0); | ||||
| 				 CIFS_CACHE_READ(cinode) ? 1 : 0); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user