Send durable handle v2 contexts when use of persistent handles required
Subsystems (2)
PATCH 1/1 Send durable handle v2 contexts when use of persistent handles required
--- fs/cifs/cifsglob.h | 1 + fs/cifs/smb2pdu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/cifs/smb2pdu.h | 30 ++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-)
fs/cifs/cifsglob.h +1 -0
@@ -1022,6 +1022,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 create_guid[16 ];#endif struct cifs_pending_open *pending_open;unsigned int epoch;
fs/cifs/smb2pdu.c +113 -1
132 lines not on this page · raw message
fs/cifs/smb2pdu.h +30 -0
@@ -590,6 +590,36 @@ struct create_durable { } Data; } __packed; +/* Flags */ +#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002 +struct durable_context_v2 { +__le32 Timeout; +__le32 Flags; +__u64 Reserved; +__u8 CreateGuid[16 ]; +} __packed; + +struct create_durable_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_context_v2 dcontext; +} __packed; + +struct durable_reconnect_context_v2 { +struct { +__u64 PersistentFileId; +__u64 VolatileFileId; + } Fid; +__u8 CreateGuid[16 ]; +__le32 Flags;/* see above DHANDLE_FLAG_PERSISTENT */ +} __packed; + +struct create_durable_handle_reconnect_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_reconnect_context_v2 dcontext; +} __packed; +#define COPY_CHUNK_RES_KEY_SIZE 24struct resume_key_req {char ResumeKey[COPY_CHUNK_RES_KEY_SIZE ];
Signature · 1 line
1.9.1
A message that is not in the archive (sent off-list or not yet received): 1443723435-32484-1-git-send-email-smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2015-10-01 21:17 GMT+03:00 Steve French <[email protected]>:
Quoted 145 lines
--- fs/cifs/cifsglob.h | 1 + fs/cifs/smb2pdu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/cifs/smb2pdu.h | 30 ++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-)fs/cifs/cifsglob.h +1
-0@@ -1022,6 +1022,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 create_guid[16 ];#endif struct cifs_pending_open *pending_open;unsigned int epoch;fs/cifs/smb2pdu.c +104
-0@@ -1100,6 +1100,68 @@ create_reconnect_durable_buf(struct cifs_fid *fid)return buf; } +static struct create_durable_v2 * +create_durable_v2_buf (struct cifs_fid *pfid) +{ +struct create_durable_v2 *buf; + + buf =kzalloc (sizeof (struct create_durable ),GFP_KERNEL ); +if (!buf) +return NULL ; + + buf->ccontext.DataOffset =cpu_to_le16 (offsetof + (struct create_durable_v2 , dcontext)); + buf->ccontext.DataLength =cpu_to_le32 (sizeof (struct durable_context_v2 )); + buf->ccontext.NameOffset =cpu_to_le16 (offsetof + (struct create_durable_v2 , Name)); + buf->ccontext.NameLength =cpu_to_le16 (4 ); + + buf->dcontext.Timeout =0 ;/* Should this be configurable by workload */ + buf->dcontext.Flags =cpu_to_le32 (SMB2_DHANDLE_FLAG_PERSISTENT ); +get_random_bytes (buf->dcontext.CreateGuid,16 ); +memcpy (pfid->create_guid, buf->dcontext.CreateGuid,16 ); + +/* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */ + buf->Name[0 ] ='D' ; + buf->Name[1 ] ='H' ; + buf->Name[2 ] ='2' ; + buf->Name[3 ] ='Q' ; +return buf; +} + +static struct create_durable_handle_reconnect_v2 * +create_reconnect_durable_v2_buf (struct cifs_fid *fid) +{ +struct create_durable_handle_reconnect_v2 *buf; + + buf =kzalloc (sizeof (struct create_durable_handle_reconnect_v2 ), +GFP_KERNEL ); +if (!buf) +return NULL ; + + buf->ccontext.DataOffset = +cpu_to_le16 (offsetof(struct create_durable_handle_reconnect_v2 , + dcontext)); + buf->ccontext.DataLength = +cpu_to_le32 (sizeof (struct durable_reconnect_context_v2 )); + buf->ccontext.NameOffset = +cpu_to_le16 (offsetof(struct create_durable_handle_reconnect_v2 , + Name)); + buf->ccontext.NameLength =cpu_to_le16 (4 ); + + buf->dcontext.Fid.PersistentFileId = fid->persistent_fid; + buf->dcontext.Fid.VolatileFileId = fid->volatile_fid; + buf->dcontext.Flags =cpu_to_le32 (SMB2_DHANDLE_FLAG_PERSISTENT ); +memcpy (buf->dcontext.CreateGuid, fid->create_guid,16 ); + +/* SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is "DH2C" */ + buf->Name[0 ] ='D' ; + buf->Name[1 ] ='H' ; + buf->Name[2 ] ='2' ; + buf->Name[3 ] ='C' ; +return buf; +} +static __u8 parse_lease_state (struct TCP_Server_Info *server,struct smb2_create_rsp *rsp,unsigned int *epoch)@@ -1174,6 +1236,48 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec,return 0 ; } +static int +add_durable_v2_context (struct kvec *iov,unsigned int *num_iovec, +struct cifs_open_parms *oparms) +{ +struct smb2_create_req *req = iov[0 ].iov_base; +unsigned int num = *num_iovec; + + iov[num].iov_base =create_durable_v2_buf (oparms->fid); +if (iov[num].iov_base ==NULL ) +return -ENOMEM ; + iov[num].iov_len =sizeof (struct create_durable_v2 ); +if (!req->CreateContextsOffset) + req->CreateContextsOffset = +cpu_to_le32 (sizeof (struct smb2_create_req ) -4 + + iov[1 ].iov_len); +le32_add_cpu (&req->CreateContextsLength,sizeof (struct create_durable_v2 )); +inc_rfc1001_len (&req->hdr,sizeof (struct create_durable_v2 )); + *num_iovec = num +1 ; +return 0 ; +} + +static int +add_durable_reconnect_v2_context (struct kvec *iov,unsigned int *num_iovec, +struct cifs_open_parms *oparms) +{ +struct smb2_create_req *req = iov[0 ].iov_base; +unsigned int num = *num_iovec; + + iov[num].iov_base =create_reconnect_durable_v2_buf (oparms->fid); +if (iov[num].iov_base ==NULL ) +return -ENOMEM ; + iov[num].iov_len =sizeof (struct create_durable_handle_reconnect_v2 ); +if (!req->CreateContextsOffset) + req->CreateContextsOffset = +cpu_to_le32 (sizeof (struct smb2_create_req ) -4 + + iov[1 ].iov_len); +le32_add_cpu (&req->CreateContextsLength,sizeof (struct create_durable_handle_reconnect_v2 )); +inc_rfc1001_len (&req->hdr,sizeof (struct create_durable_handle_reconnect_v2 )); + *num_iovec = num +1 ; +return 0 ; +} + int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, __u8 *oplock, struct smb2_file_all_info *buf,@@ -1272,7 +1376,15 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, ccontext->Next =cpu_to_le32 (server->vals->create_lease_size); }
fs/cifs/smb2pdu.c SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, · line 1387
Quoted 10 lines
fs/cifs/smb2pdu.c +9
-1- rc =add_durable_context (iov, &num_iovecs, oparms); +if (tcon->use_persistent) { +if (oparms->reconnect) + rc =add_durable_reconnect_v2_context (iov, + &num_iovecs, oparms); +else + rc =add_durable_v2_context (iov, &num_iovecs, + oparms); + }else + rc =add_durable_context (iov, &num_iovecs, oparms);
I think it will be better to incapsulate this if statements into add_durable_context() function to leave SMB2_open() code more generic.
Quoted 47 lines
fs/cifs/smb2pdu.c +0
-0if (rc) {cifs_small_buf_release (req);kfree (copy_path);fs/cifs/smb2pdu.h +30
-1@@ -590,6 +590,36 @@ struct create_durable { } Data; } __packed; +/* Flags */ +#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002 +struct durable_context_v2 { +__le32 Timeout; +__le32 Flags; +__u64 Reserved; +__u8 CreateGuid[16 ]; +} __packed; + +struct create_durable_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_context_v2 dcontext; +} __packed; + +struct durable_reconnect_context_v2 { +struct { +__u64 PersistentFileId; +__u64 VolatileFileId; + } Fid; +__u8 CreateGuid[16 ]; +__le32 Flags;/* see above DHANDLE_FLAG_PERSISTENT */ +} __packed; + +struct create_durable_handle_reconnect_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_reconnect_context_v2 dcontext; +} __packed; +#define COPY_CHUNK_RES_KEY_SIZE 24struct resume_key_req {char ResumeKey[COPY_CHUNK_RES_KEY_SIZE ]; --1.9.1
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Other than the note above the patch looks good.
Signature · 2 lines
Best regards, Pavel Shilovsky.
A message that is not in the archive (sent off-list or not yet received): CAKywueTcLJ0__8mSaD5LGG6rVp2PiNnJhC0br1NcyHc6rTQrwQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Updated and resent the 4 patch series onto linux-cifs and also pushed to cifs-2.6.git experimental branch.
I don't know if channel sequence number in the SMB3 request would also need to be incremented on disconnect though (the documentation is confusing on that in MS-SMB2) in the case where we only have one channel.
Also wondering if I should add a mount option for resilient handles to allow us to force better reliability of connections to non-clustered servers (and presumably could work even to Windows 8 and 8.1 and Windows 10 servers) when the application would prefer that (to the less strict guarantees of durable handles)
Quoted 217 lines · Pavel Shilovsky
2015-10-01 21:17 GMT+03:00 Steve French <[email protected]>:
Quoted 145 lines
--- fs/cifs/cifsglob.h | 1 + fs/cifs/smb2pdu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/cifs/smb2pdu.h | 30 ++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-)fs/cifs/cifsglob.h +1
-0@@ -1022,6 +1022,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 create_guid[16 ];#endif struct cifs_pending_open *pending_open;unsigned int epoch;fs/cifs/smb2pdu.c +104
-0@@ -1100,6 +1100,68 @@ create_reconnect_durable_buf(struct cifs_fid *fid)return buf; } +static struct create_durable_v2 * +create_durable_v2_buf (struct cifs_fid *pfid) +{ +struct create_durable_v2 *buf; + + buf =kzalloc (sizeof (struct create_durable ),GFP_KERNEL ); +if (!buf) +return NULL ; + + buf->ccontext.DataOffset =cpu_to_le16 (offsetof + (struct create_durable_v2 , dcontext)); + buf->ccontext.DataLength =cpu_to_le32 (sizeof (struct durable_context_v2 )); + buf->ccontext.NameOffset =cpu_to_le16 (offsetof + (struct create_durable_v2 , Name)); + buf->ccontext.NameLength =cpu_to_le16 (4 ); + + buf->dcontext.Timeout =0 ;/* Should this be configurable by workload */ + buf->dcontext.Flags =cpu_to_le32 (SMB2_DHANDLE_FLAG_PERSISTENT ); +get_random_bytes (buf->dcontext.CreateGuid,16 ); +memcpy (pfid->create_guid, buf->dcontext.CreateGuid,16 ); + +/* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */ + buf->Name[0 ] ='D' ; + buf->Name[1 ] ='H' ; + buf->Name[2 ] ='2' ; + buf->Name[3 ] ='Q' ; +return buf; +} + +static struct create_durable_handle_reconnect_v2 * +create_reconnect_durable_v2_buf (struct cifs_fid *fid) +{ +struct create_durable_handle_reconnect_v2 *buf; + + buf =kzalloc (sizeof (struct create_durable_handle_reconnect_v2 ), +GFP_KERNEL ); +if (!buf) +return NULL ; + + buf->ccontext.DataOffset = +cpu_to_le16 (offsetof(struct create_durable_handle_reconnect_v2 , + dcontext)); + buf->ccontext.DataLength = +cpu_to_le32 (sizeof (struct durable_reconnect_context_v2 )); + buf->ccontext.NameOffset = +cpu_to_le16 (offsetof(struct create_durable_handle_reconnect_v2 , + Name)); + buf->ccontext.NameLength =cpu_to_le16 (4 ); + + buf->dcontext.Fid.PersistentFileId = fid->persistent_fid; + buf->dcontext.Fid.VolatileFileId = fid->volatile_fid; + buf->dcontext.Flags =cpu_to_le32 (SMB2_DHANDLE_FLAG_PERSISTENT ); +memcpy (buf->dcontext.CreateGuid, fid->create_guid,16 ); + +/* SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is "DH2C" */ + buf->Name[0 ] ='D' ; + buf->Name[1 ] ='H' ; + buf->Name[2 ] ='2' ; + buf->Name[3 ] ='C' ; +return buf; +} +static __u8 parse_lease_state (struct TCP_Server_Info *server,struct smb2_create_rsp *rsp,unsigned int *epoch)@@ -1174,6 +1236,48 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec,return 0 ; } +static int +add_durable_v2_context (struct kvec *iov,unsigned int *num_iovec, +struct cifs_open_parms *oparms) +{ +struct smb2_create_req *req = iov[0 ].iov_base; +unsigned int num = *num_iovec; + + iov[num].iov_base =create_durable_v2_buf (oparms->fid); +if (iov[num].iov_base ==NULL ) +return -ENOMEM ; + iov[num].iov_len =sizeof (struct create_durable_v2 ); +if (!req->CreateContextsOffset) + req->CreateContextsOffset = +cpu_to_le32 (sizeof (struct smb2_create_req ) -4 + + iov[1 ].iov_len); +le32_add_cpu (&req->CreateContextsLength,sizeof (struct create_durable_v2 )); +inc_rfc1001_len (&req->hdr,sizeof (struct create_durable_v2 )); + *num_iovec = num +1 ; +return 0 ; +} + +static int +add_durable_reconnect_v2_context (struct kvec *iov,unsigned int *num_iovec, +struct cifs_open_parms *oparms) +{ +struct smb2_create_req *req = iov[0 ].iov_base; +unsigned int num = *num_iovec; + + iov[num].iov_base =create_reconnect_durable_v2_buf (oparms->fid); +if (iov[num].iov_base ==NULL ) +return -ENOMEM ; + iov[num].iov_len =sizeof (struct create_durable_handle_reconnect_v2 ); +if (!req->CreateContextsOffset) + req->CreateContextsOffset = +cpu_to_le32 (sizeof (struct smb2_create_req ) -4 + + iov[1 ].iov_len); +le32_add_cpu (&req->CreateContextsLength,sizeof (struct create_durable_handle_reconnect_v2 )); +inc_rfc1001_len (&req->hdr,sizeof (struct create_durable_handle_reconnect_v2 )); + *num_iovec = num +1 ; +return 0 ; +} + int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, __u8 *oplock, struct smb2_file_all_info *buf,@@ -1272,7 +1376,15 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, ccontext->Next =cpu_to_le32 (server->vals->create_lease_size); }fs/cifs/smb2pdu.c SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, · line 1387
Quoted 10 lines
fs/cifs/smb2pdu.c +9
-1- rc =add_durable_context (iov, &num_iovecs, oparms); +if (tcon->use_persistent) { +if (oparms->reconnect) + rc =add_durable_reconnect_v2_context (iov, + &num_iovecs, oparms); +else + rc =add_durable_v2_context (iov, &num_iovecs, + oparms); + }else + rc =add_durable_context (iov, &num_iovecs, oparms);I think it will be better to incapsulate this if statements into
add_durable_context()function to leaveSMB2_open()code more generic.Quoted 47 lines
fs/cifs/smb2pdu.c +0
-0if (rc) {cifs_small_buf_release (req);kfree (copy_path);fs/cifs/smb2pdu.h +30
-1@@ -590,6 +590,36 @@ struct create_durable { } Data; } __packed; +/* Flags */ +#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002 +struct durable_context_v2 { +__le32 Timeout; +__le32 Flags; +__u64 Reserved; +__u8 CreateGuid[16 ]; +} __packed; + +struct create_durable_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_context_v2 dcontext; +} __packed; + +struct durable_reconnect_context_v2 { +struct { +__u64 PersistentFileId; +__u64 VolatileFileId; + } Fid; +__u8 CreateGuid[16 ]; +__le32 Flags;/* see above DHANDLE_FLAG_PERSISTENT */ +} __packed; + +struct create_durable_handle_reconnect_v2 { +struct create_context ccontext; +__u8 Name[8 ]; +struct durable_reconnect_context_v2 dcontext; +} __packed; +#define COPY_CHUNK_RES_KEY_SIZE 24struct resume_key_req {char ResumeKey[COPY_CHUNK_RES_KEY_SIZE ]; --1.9.1
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.htmlOther than the note above the patch looks good.
--
Best regards,
Pavel Shilovsky.
Signature · 3 lines
Thanks, Steve