Commit 0f220d30 authored by Henrique Carvalho's avatar Henrique Carvalho Committed by Steve French
Browse files

smb: client: use ParentLeaseKey in open_cached_dir



Implement ParentLeaseKey logic in open_cached_dir() by looking up the
parent cfid, copying its lease key into the fid struct, and setting
the appropriate lease flag.

Fixes: f047390a ("CIFS: Add create lease v2 context for SMB3")
Signed-off-by: default avatarHenrique Carvalho <henrique.carvalho@suse.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 51b78ffb
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
	struct cached_fids *cfids;
	const char *npath;
	int retries = 0, cur_sleep = 1;
	__le32 lease_flags = 0;

	if (cifs_sb->root == NULL)
		return -ENOENT;
@@ -200,6 +201,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
	}
	spin_unlock(&cfids->cfid_list_lock);

	pfid = &cfid->fid;

	/*
	 * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
	 * calling ->lookup() which already adds those through
@@ -221,6 +224,25 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
			rc = -ENOENT;
			goto out;
		}
		if (dentry->d_parent && server->dialect >= SMB30_PROT_ID) {
			struct cached_fid *parent_cfid;

			spin_lock(&cfids->cfid_list_lock);
			list_for_each_entry(parent_cfid, &cfids->entries, entry) {
				if (parent_cfid->dentry == dentry->d_parent) {
					cifs_dbg(FYI, "found a parent cached file handle\n");
					if (parent_cfid->has_lease && parent_cfid->time) {
						lease_flags
							|= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE;
						memcpy(pfid->parent_lease_key,
						       parent_cfid->fid.lease_key,
						       SMB2_LEASE_KEY_SIZE);
					}
					break;
				}
			}
			spin_unlock(&cfids->cfid_list_lock);
		}
	}
	cfid->dentry = dentry;
	cfid->tcon = tcon;
@@ -235,7 +257,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
	if (smb3_encryption_required(tcon))
		flags |= CIFS_TRANSFORM_REQ;

	pfid = &cfid->fid;
	server->ops->new_lease_key(pfid);

	memset(rqst, 0, sizeof(rqst));
@@ -255,6 +276,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
				   FILE_READ_EA,
		.disposition = FILE_OPEN,
		.fid = pfid,
		.lease_flags = lease_flags,
		.replay = !!(retries),
	};