Commit 51b78ffb authored by Henrique Carvalho's avatar Henrique Carvalho Committed by Steve French
Browse files

smb: client: add ParentLeaseKey support



According to MS-SMB2 3.2.4.3.8, when opening a file the client must
lookup its parent directory, copy that entry’s LeaseKey into
ParentLeaseKey, and set SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET.

Extend lease context functions to carry a parent_lease_key and
lease_flags and to add them to the lease context buffer accordingly in
smb3_create_lease_buf. Also add a parent_lease_key field to struct
cifs_fid and lease_flags to cifs_open_parms.

Only applies to the SMB 3.x dialect family.

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 a3e771af
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -556,7 +556,7 @@ struct smb_version_operations {
	void (*set_oplock_level)(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch,
				 bool *purge_cache);
	/* create lease context buffer for CREATE request */
	char * (*create_lease_buf)(u8 *lease_key, u8 oplock);
	char * (*create_lease_buf)(u8 *lease_key, u8 oplock, u8 *parent_lease_key, __le32 le_flags);
	/* parse lease context buffer and return oplock/epoch info */
	__u8 (*parse_lease_buf)(void *buf, __u16 *epoch, char *lkey);
	ssize_t (*copychunk_range)(const unsigned int,
@@ -1442,6 +1442,7 @@ struct cifs_open_parms {
	bool reconnect:1;
	bool replay:1; /* indicates that this open is for a replay */
	struct kvec *ea_cctx;
	__le32 lease_flags;
};

struct cifs_fid {
@@ -1449,6 +1450,7 @@ struct cifs_fid {
	__u64 persistent_fid;	/* persist file id for smb2 */
	__u64 volatile_fid;	/* volatile file id for smb2 */
	__u8 lease_key[SMB2_LEASE_KEY_SIZE];	/* lease key for smb2 */
	__u8 parent_lease_key[SMB2_LEASE_KEY_SIZE];
	__u8 create_guid[16];
	__u32 access;
	struct cifs_pending_open *pending_open;
+5 −2
Original line number Diff line number Diff line
@@ -4069,7 +4069,7 @@ map_oplock_to_lease(u8 oplock)
}

static char *
smb2_create_lease_buf(u8 *lease_key, u8 oplock)
smb2_create_lease_buf(u8 *lease_key, u8 oplock, u8 *parent_lease_key, __le32 flags)
{
	struct create_lease *buf;

@@ -4095,7 +4095,7 @@ smb2_create_lease_buf(u8 *lease_key, u8 oplock)
}

static char *
smb3_create_lease_buf(u8 *lease_key, u8 oplock)
smb3_create_lease_buf(u8 *lease_key, u8 oplock, u8 *parent_lease_key, __le32 flags)
{
	struct create_lease_v2 *buf;

@@ -4105,6 +4105,9 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock)

	memcpy(&buf->lcontext.LeaseKey, lease_key, SMB2_LEASE_KEY_SIZE);
	buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
	buf->lcontext.LeaseFlags = flags;
	if (flags & SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE)
		memcpy(&buf->lcontext.ParentLeaseKey, parent_lease_key, SMB2_LEASE_KEY_SIZE);

	buf->ccontext.DataOffset = cpu_to_le16(offsetof
					(struct create_lease_v2, lcontext));
+10 −3
Original line number Diff line number Diff line
@@ -2392,11 +2392,16 @@ static int
add_lease_context(struct TCP_Server_Info *server,
		  struct smb2_create_req *req,
		  struct kvec *iov,
		  unsigned int *num_iovec, u8 *lease_key, __u8 *oplock)
		  unsigned int *num_iovec,
		  u8 *lease_key,
		  __u8 *oplock,
		  u8 *parent_lease_key,
		  __le32 flags)
{
	unsigned int num = *num_iovec;

	iov[num].iov_base = server->ops->create_lease_buf(lease_key, *oplock);
	iov[num].iov_base = server->ops->create_lease_buf(lease_key, *oplock,
							  parent_lease_key, flags);
	if (iov[num].iov_base == NULL)
		return -ENOMEM;
	iov[num].iov_len = server->vals->create_lease_size;
@@ -3069,7 +3074,9 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
		req->RequestedOplockLevel = *oplock; /* no srv lease support */
	else {
		rc = add_lease_context(server, req, iov, &n_iov,
				       oparms->fid->lease_key, oplock);
				       oparms->fid->lease_key, oplock,
				       oparms->fid->parent_lease_key,
				       oparms->lease_flags);
		if (rc)
			return rc;
	}