@@ -519,6 +519,64 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
519519 return rc ;
520520}
521521
522+ static struct create_posix *
523+ create_posix_buf (umode_t mode )
524+ {
525+ struct create_posix * buf ;
526+
527+ buf = kzalloc (sizeof (struct create_posix ),
528+ GFP_KERNEL );
529+ if (!buf )
530+ return NULL ;
531+
532+ buf -> ccontext .DataOffset =
533+ cpu_to_le16 (offsetof(struct create_posix , Mode ));
534+ buf -> ccontext .DataLength = cpu_to_le32 (4 );
535+ buf -> ccontext .NameOffset =
536+ cpu_to_le16 (offsetof(struct create_posix , Name ));
537+ buf -> ccontext .NameLength = cpu_to_le16 (16 );
538+
539+ /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
540+ buf -> Name [0 ] = 0x93 ;
541+ buf -> Name [1 ] = 0xAD ;
542+ buf -> Name [2 ] = 0x25 ;
543+ buf -> Name [3 ] = 0x50 ;
544+ buf -> Name [4 ] = 0x9C ;
545+ buf -> Name [5 ] = 0xB4 ;
546+ buf -> Name [6 ] = 0x11 ;
547+ buf -> Name [7 ] = 0xE7 ;
548+ buf -> Name [8 ] = 0xB4 ;
549+ buf -> Name [9 ] = 0x23 ;
550+ buf -> Name [10 ] = 0x83 ;
551+ buf -> Name [11 ] = 0xDE ;
552+ buf -> Name [12 ] = 0x96 ;
553+ buf -> Name [13 ] = 0x8B ;
554+ buf -> Name [14 ] = 0xCD ;
555+ buf -> Name [15 ] = 0x7C ;
556+ buf -> Mode = cpu_to_le32 (mode );
557+ cifs_dbg (FYI , "mode on posix create 0%o" , mode );
558+ return buf ;
559+ }
560+
561+ static int
562+ add_posix_context (struct kvec * iov , unsigned int * num_iovec , umode_t mode )
563+ {
564+ struct smb2_create_req * req = iov [0 ].iov_base ;
565+ unsigned int num = * num_iovec ;
566+
567+ iov [num ].iov_base = create_posix_buf (mode );
568+ if (iov [num ].iov_base == NULL )
569+ return - ENOMEM ;
570+ iov [num ].iov_len = sizeof (struct create_posix );
571+ if (!req -> CreateContextsOffset )
572+ req -> CreateContextsOffset = cpu_to_le32 (
573+ sizeof (struct smb2_create_req ) +
574+ iov [num - 1 ].iov_len );
575+ le32_add_cpu (& req -> CreateContextsLength , sizeof (struct create_posix ));
576+ * num_iovec = num + 1 ;
577+ return 0 ;
578+ }
579+
522580#else
523581static void assemble_neg_contexts (struct smb2_negotiate_req * req ,
524582 unsigned int * total_len )
@@ -1837,7 +1895,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
18371895 struct TCP_Server_Info * server ;
18381896 struct cifs_tcon * tcon = oparms -> tcon ;
18391897 struct cifs_ses * ses = tcon -> ses ;
1840- struct kvec iov [4 ];
1898+ struct kvec iov [5 ]; /* make sure at least one for each open context */
18411899 struct kvec rsp_iov = {NULL , 0 };
18421900 int resp_buftype ;
18431901 int uni_path_len ;
@@ -1846,7 +1904,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
18461904 int rc = 0 ;
18471905 unsigned int n_iov = 2 ;
18481906 __u32 file_attributes = 0 ;
1849- char * dhc_buf = NULL , * lc_buf = NULL ;
1907+ char * dhc_buf = NULL , * lc_buf = NULL , * pc_buf = NULL ;
18501908 int flags = 0 ;
18511909 unsigned int total_len ;
18521910
@@ -1963,6 +2021,27 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
19632021 dhc_buf = iov [n_iov - 1 ].iov_base ;
19642022 }
19652023
2024+ #ifdef CONFIG_CIFS_SMB311
2025+ if (tcon -> posix_extensions ) {
2026+ if (n_iov > 2 ) {
2027+ struct create_context * ccontext =
2028+ (struct create_context * )iov [n_iov - 1 ].iov_base ;
2029+ ccontext -> Next =
2030+ cpu_to_le32 (iov [n_iov - 1 ].iov_len );
2031+ }
2032+
2033+ rc = add_posix_context (iov , & n_iov , oparms -> mode );
2034+ if (rc ) {
2035+ cifs_small_buf_release (req );
2036+ kfree (copy_path );
2037+ kfree (lc_buf );
2038+ kfree (dhc_buf );
2039+ return rc ;
2040+ }
2041+ pc_buf = iov [n_iov - 1 ].iov_base ;
2042+ }
2043+ #endif /* SMB311 */
2044+
19662045 rc = smb2_send_recv (xid , ses , iov , n_iov , & resp_buftype , flags ,
19672046 & rsp_iov );
19682047 cifs_small_buf_release (req );
@@ -2004,6 +2083,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
20042083 kfree (copy_path );
20052084 kfree (lc_buf );
20062085 kfree (dhc_buf );
2086+ kfree (pc_buf );
20072087 free_rsp_buf (resp_buftype , rsp );
20082088 return rc ;
20092089}
0 commit comments