diff options
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 16 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 18 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 4 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 6 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 659 | ||||
| -rw-r--r-- | fs/cifs/file.c | 27 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 11 | ||||
| -rw-r--r-- | fs/cifs/sess.c | 3 |
9 files changed, 370 insertions, 376 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 259991bd2112..e76bfeb68267 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -87,9 +87,15 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, | |||
| 87 | if ((cifs_pdu == NULL) || (server == NULL)) | 87 | if ((cifs_pdu == NULL) || (server == NULL)) |
| 88 | return -EINVAL; | 88 | return -EINVAL; |
| 89 | 89 | ||
| 90 | if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) | 90 | if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) || |
| 91 | server->tcpStatus == CifsNeedNegotiate) | ||
| 91 | return rc; | 92 | return rc; |
| 92 | 93 | ||
| 94 | if (!server->session_estab) { | ||
| 95 | strncpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8); | ||
| 96 | return rc; | ||
| 97 | } | ||
| 98 | |||
| 93 | cifs_pdu->Signature.Sequence.SequenceNumber = | 99 | cifs_pdu->Signature.Sequence.SequenceNumber = |
| 94 | cpu_to_le32(server->sequence_number); | 100 | cpu_to_le32(server->sequence_number); |
| 95 | cifs_pdu->Signature.Sequence.Reserved = 0; | 101 | cifs_pdu->Signature.Sequence.Reserved = 0; |
| @@ -178,9 +184,15 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, | |||
| 178 | if ((cifs_pdu == NULL) || (server == NULL)) | 184 | if ((cifs_pdu == NULL) || (server == NULL)) |
| 179 | return -EINVAL; | 185 | return -EINVAL; |
| 180 | 186 | ||
| 181 | if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) | 187 | if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) || |
| 188 | server->tcpStatus == CifsNeedNegotiate) | ||
| 182 | return rc; | 189 | return rc; |
| 183 | 190 | ||
| 191 | if (!server->session_estab) { | ||
| 192 | strncpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8); | ||
| 193 | return rc; | ||
| 194 | } | ||
| 195 | |||
| 184 | cifs_pdu->Signature.Sequence.SequenceNumber = | 196 | cifs_pdu->Signature.Sequence.SequenceNumber = |
| 185 | cpu_to_le32(server->sequence_number); | 197 | cpu_to_le32(server->sequence_number); |
| 186 | cifs_pdu->Signature.Sequence.Reserved = 0; | 198 | cifs_pdu->Signature.Sequence.Reserved = 0; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 865517470967..212e5629cc1d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -86,24 +86,6 @@ extern mempool_t *cifs_sm_req_poolp; | |||
| 86 | extern mempool_t *cifs_req_poolp; | 86 | extern mempool_t *cifs_req_poolp; |
| 87 | extern mempool_t *cifs_mid_poolp; | 87 | extern mempool_t *cifs_mid_poolp; |
| 88 | 88 | ||
| 89 | void | ||
| 90 | cifs_sb_active(struct super_block *sb) | ||
| 91 | { | ||
| 92 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 93 | |||
| 94 | if (atomic_inc_return(&server->active) == 1) | ||
| 95 | atomic_inc(&sb->s_active); | ||
| 96 | } | ||
| 97 | |||
| 98 | void | ||
| 99 | cifs_sb_deactive(struct super_block *sb) | ||
| 100 | { | ||
| 101 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 102 | |||
| 103 | if (atomic_dec_and_test(&server->active)) | ||
| 104 | deactivate_super(sb); | ||
| 105 | } | ||
| 106 | |||
| 107 | static int | 89 | static int |
| 108 | cifs_read_super(struct super_block *sb) | 90 | cifs_read_super(struct super_block *sb) |
| 109 | { | 91 | { |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index fbd050c8d52a..cb71dc1f94d1 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -41,10 +41,6 @@ extern struct file_system_type cifs_fs_type; | |||
| 41 | extern const struct address_space_operations cifs_addr_ops; | 41 | extern const struct address_space_operations cifs_addr_ops; |
| 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; | 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; |
| 43 | 43 | ||
| 44 | /* Functions related to super block operations */ | ||
| 45 | extern void cifs_sb_active(struct super_block *sb); | ||
| 46 | extern void cifs_sb_deactive(struct super_block *sb); | ||
| 47 | |||
| 48 | /* Functions related to inodes */ | 44 | /* Functions related to inodes */ |
| 49 | extern const struct inode_operations cifs_dir_inode_ops; | 45 | extern const struct inode_operations cifs_dir_inode_ops; |
| 50 | extern struct inode *cifs_root_iget(struct super_block *); | 46 | extern struct inode *cifs_root_iget(struct super_block *); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1fcf4e5b3112..38ce6d44b145 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -942,8 +942,6 @@ GLOBAL_EXTERN spinlock_t siduidlock; | |||
| 942 | GLOBAL_EXTERN spinlock_t sidgidlock; | 942 | GLOBAL_EXTERN spinlock_t sidgidlock; |
| 943 | 943 | ||
| 944 | void cifs_oplock_break(struct work_struct *work); | 944 | void cifs_oplock_break(struct work_struct *work); |
| 945 | void cifs_oplock_break_get(struct cifsFileInfo *cfile); | ||
| 946 | void cifs_oplock_break_put(struct cifsFileInfo *cfile); | ||
| 947 | 945 | ||
| 948 | extern const struct slow_work_ops cifs_oplock_break_ops; | 946 | extern const struct slow_work_ops cifs_oplock_break_ops; |
| 949 | 947 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1a9fe7f816d1..aac37d99a487 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -107,7 +107,7 @@ static void mark_open_files_invalid(struct cifs_tcon *pTcon) | |||
| 107 | static int | 107 | static int |
| 108 | cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) | 108 | cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) |
| 109 | { | 109 | { |
| 110 | int rc = 0; | 110 | int rc; |
| 111 | struct cifs_ses *ses; | 111 | struct cifs_ses *ses; |
| 112 | struct TCP_Server_Info *server; | 112 | struct TCP_Server_Info *server; |
| 113 | struct nls_table *nls_codepage; | 113 | struct nls_table *nls_codepage; |
| @@ -5720,6 +5720,7 @@ CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon, | |||
| 5720 | char *temp_ptr; | 5720 | char *temp_ptr; |
| 5721 | char *end_of_smb; | 5721 | char *end_of_smb; |
| 5722 | __u16 params, byte_count, data_offset; | 5722 | __u16 params, byte_count, data_offset; |
| 5723 | unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; | ||
| 5723 | 5724 | ||
| 5724 | cFYI(1, "In Query All EAs path %s", searchName); | 5725 | cFYI(1, "In Query All EAs path %s", searchName); |
| 5725 | QAllEAsRetry: | 5726 | QAllEAsRetry: |
| @@ -5837,7 +5838,8 @@ QAllEAsRetry: | |||
| 5837 | } | 5838 | } |
| 5838 | 5839 | ||
| 5839 | if (ea_name) { | 5840 | if (ea_name) { |
| 5840 | if (strncmp(ea_name, temp_ptr, name_len) == 0) { | 5841 | if (ea_name_len == name_len && |
| 5842 | strncmp(ea_name, temp_ptr, name_len) == 0) { | ||
| 5841 | temp_ptr += name_len + 1; | 5843 | temp_ptr += name_len + 1; |
| 5842 | rc = value_len; | 5844 | rc = value_len; |
| 5843 | if (buf_size == 0) | 5845 | if (buf_size == 0) |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e66297bad412..80c2e3add3a2 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -319,25 +319,328 @@ requeue_echo: | |||
| 319 | queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); | 319 | queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | static bool | ||
| 323 | allocate_buffers(char **bigbuf, char **smallbuf, unsigned int size, | ||
| 324 | bool is_large_buf) | ||
| 325 | { | ||
| 326 | char *bbuf = *bigbuf, *sbuf = *smallbuf; | ||
| 327 | |||
| 328 | if (bbuf == NULL) { | ||
| 329 | bbuf = (char *)cifs_buf_get(); | ||
| 330 | if (!bbuf) { | ||
| 331 | cERROR(1, "No memory for large SMB response"); | ||
| 332 | msleep(3000); | ||
| 333 | /* retry will check if exiting */ | ||
| 334 | return false; | ||
| 335 | } | ||
| 336 | } else if (is_large_buf) { | ||
| 337 | /* we are reusing a dirty large buf, clear its start */ | ||
| 338 | memset(bbuf, 0, size); | ||
| 339 | } | ||
| 340 | |||
| 341 | if (sbuf == NULL) { | ||
| 342 | sbuf = (char *)cifs_small_buf_get(); | ||
| 343 | if (!sbuf) { | ||
| 344 | cERROR(1, "No memory for SMB response"); | ||
| 345 | msleep(1000); | ||
| 346 | /* retry will check if exiting */ | ||
| 347 | return false; | ||
| 348 | } | ||
| 349 | /* beginning of smb buffer is cleared in our buf_get */ | ||
| 350 | } else { | ||
| 351 | /* if existing small buf clear beginning */ | ||
| 352 | memset(sbuf, 0, size); | ||
| 353 | } | ||
| 354 | |||
| 355 | *bigbuf = bbuf; | ||
| 356 | *smallbuf = sbuf; | ||
| 357 | |||
| 358 | return true; | ||
| 359 | } | ||
| 360 | |||
| 361 | static int | ||
| 362 | read_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg, | ||
| 363 | struct kvec *iov, unsigned int to_read, | ||
| 364 | unsigned int *ptotal_read, bool is_header_read) | ||
| 365 | { | ||
| 366 | int length, rc = 0; | ||
| 367 | unsigned int total_read; | ||
| 368 | char *buf = iov->iov_base; | ||
| 369 | |||
| 370 | for (total_read = 0; total_read < to_read; total_read += length) { | ||
| 371 | length = kernel_recvmsg(server->ssocket, smb_msg, iov, 1, | ||
| 372 | to_read - total_read, 0); | ||
| 373 | if (server->tcpStatus == CifsExiting) { | ||
