Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18cceb6a authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French
Browse files

CIFS: Replace clientCanCache* bools with an integer



that prepare the code to handle different types of SMB2 leases.

Signed-off-by: default avatarPavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 77993be3
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -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;
+8 −2
Original line number Diff line number Diff line
@@ -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 */
+14 −14
Original line number Diff line number Diff line
@@ -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);
+4 −4
Original line number Diff line number Diff line
@@ -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) {
+4 −8
Original line number Diff line number Diff line
@@ -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
Loading