aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r--fs/cifs/smb2pdu.c179
1 files changed, 116 insertions, 63 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 77b3aaa39b35..60fbe306f604 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -107,13 +107,13 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
107 struct TCP_Server_Info *server = tcon->ses->server; 107 struct TCP_Server_Info *server = tcon->ses->server;
108 108
109 spin_lock(&server->req_lock); 109 spin_lock(&server->req_lock);
110 /* Request up to 2 credits but don't go over the limit. */ 110 /* Request up to 10 credits but don't go over the limit. */
111 if (server->credits >= server->max_credits) 111 if (server->credits >= server->max_credits)
112 shdr->CreditRequest = cpu_to_le16(0); 112 shdr->CreditRequest = cpu_to_le16(0);
113 else 113 else
114 shdr->CreditRequest = cpu_to_le16( 114 shdr->CreditRequest = cpu_to_le16(
115 min_t(int, server->max_credits - 115 min_t(int, server->max_credits -
116 server->credits, 2)); 116 server->credits, 10));
117 spin_unlock(&server->req_lock); 117 spin_unlock(&server->req_lock);
118 } else { 118 } else {
119 shdr->CreditRequest = cpu_to_le16(2); 119 shdr->CreditRequest = cpu_to_le16(2);
@@ -173,8 +173,8 @@ static int __smb2_reconnect(const struct nls_table *nlsc,
173 return -ENOMEM; 173 return -ENOMEM;
174 174
175 if (tcon->ipc) { 175 if (tcon->ipc) {
176 snprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", 176 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
177 tcon->ses->server->hostname); 177 tcon->ses->server->hostname);
178 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); 178 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
179 goto out; 179 goto out;
180 } 180 }
@@ -206,7 +206,7 @@ static int __smb2_reconnect(const struct nls_table *nlsc,
206 continue; 206 continue;
207 } 207 }
208 208
209 snprintf(tree, MAX_TREE_SIZE, "\\%s", tgt); 209 scnprintf(tree, MAX_TREE_SIZE, "\\%s", tgt);
210 210
211 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc); 211 rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
212 if (!rc) 212 if (!rc)
@@ -490,6 +490,23 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
490{ 490{
491 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE; 491 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
492 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN); 492 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
493 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
494 pneg_ctxt->Name[0] = 0x93;
495 pneg_ctxt->Name[1] = 0xAD;
496 pneg_ctxt->Name[2] = 0x25;
497 pneg_ctxt->Name[3] = 0x50;
498 pneg_ctxt->Name[4] = 0x9C;
499 pneg_ctxt->Name[5] = 0xB4;
500 pneg_ctxt->Name[6] = 0x11;
501 pneg_ctxt->Name[7] = 0xE7;
502 pneg_ctxt->Name[8] = 0xB4;
503 pneg_ctxt->Name[9] = 0x23;
504 pneg_ctxt->Name[10] = 0x83;
505 pneg_ctxt->Name[11] = 0xDE;
506 pneg_ctxt->Name[12] = 0x96;
507 pneg_ctxt->Name[13] = 0x8B;
508 pneg_ctxt->Name[14] = 0xCD;
509 pneg_ctxt->Name[15] = 0x7C;
493} 510}
494 511
495static void 512static void
@@ -986,8 +1003,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
986 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 1003 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
987 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, 1004 FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
988 (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen); 1005 (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen);
989 1006 if (rc == -EOPNOTSUPP) {
990 if (rc != 0) { 1007 /*
1008 * Old Windows versions or Netapp SMB server can return
1009 * not supported error. Client should accept it.
1010 */
1011 cifs_dbg(VFS, "Server does not support validate negotiate\n");
1012 return 0;
1013 } else if (rc != 0) {
991 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); 1014 cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
992 rc = -EIO; 1015 rc = -EIO;
993 goto out_free_inbuf; 1016 goto out_free_inbuf;
@@ -1614,6 +1637,9 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1614 rqst.rq_iov = iov; 1637 rqst.rq_iov = iov;
1615 rqst.rq_nvec = 2; 1638 rqst.rq_nvec = 2;
1616 1639
1640 /* Need 64 for max size write so ask for more in case not there yet */
1641 req->sync_hdr.CreditRequest = cpu_to_le16(64);
1642
1617 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 1643 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
1618 cifs_small_buf_release(req); 1644 cifs_small_buf_release(req);
1619 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; 1645 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
@@ -2170,6 +2196,8 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
2170 rqst.rq_iov = iov; 2196 rqst.rq_iov = iov;
2171 rqst.rq_nvec = n_iov; 2197 rqst.rq_nvec = n_iov;
2172 2198
2199 trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
2200 FILE_WRITE_ATTRIBUTES);
2173 /* resource #4: response buffer */ 2201 /* resource #4: response buffer */
2174 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2202 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
2175 if (rc) { 2203 if (rc) {
@@ -2388,6 +2416,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2388 if (rc) 2416 if (rc)
2389 goto creat_exit; 2417 goto creat_exit;
2390 2418
2419 trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
2420 oparms->create_options, oparms->desired_access);
2421
2391 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, 2422 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
2392 &rsp_iov); 2423 &rsp_iov);
2393 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; 2424 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
@@ -2837,6 +2868,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
2837 if (rc) 2868 if (rc)
2838 goto qinf_exit; 2869 goto qinf_exit;
2839 2870
2871 trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid,
2872 ses->Suid, info_class, (__u32)info_type);
2873
2840 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2874 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
2841 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; 2875 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
2842 2876
@@ -2847,6 +2881,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
2847 goto qinf_exit; 2881 goto qinf_exit;
2848 } 2882 }
2849 2883
2884 trace_smb3_query_info_done(xid, persistent_fid, tcon->tid,
2885 ses->Suid, info_class, (__u32)info_type);
2886
2850 if (dlen) { 2887 if (dlen) {
2851 *dlen = le32_to_cpu(rsp->OutputBufferLength); 2888 *dlen = le32_to_cpu(rsp->OutputBufferLength);
2852 if (!*data) { 2889 if (!*data) {
@@ -2924,14 +2961,16 @@ smb2_echo_callback(struct mid_q_entry *mid)
2924{ 2961{
2925 struct TCP_Server_Info *server = mid->callback_data; 2962 struct TCP_Server_Info *server = mid->callback_data;
2926 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf; 2963 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
2927 unsigned int credits_received = 0; 2964 struct cifs_credits credits = { .value = 0, .instance = 0 };
2928 2965
2929 if (mid->mid_state == MID_RESPONSE_RECEIVED 2966 if (mid->mid_state == MID_RESPONSE_RECEIVED
2930 || mid->mid_state == MID_RESPONSE_MALFORMED) 2967 || mid->mid_state == MID_RESPONSE_MALFORMED) {
2931 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 2968 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
2969 credits.instance = server->reconnect_instance;
2970 }
2932 2971
2933 DeleteMidQEntry(mid); 2972 DeleteMidQEntry(mid);
2934 add_credits(server, credits_received, CIFS_ECHO_OP); 2973 add_credits(server, &credits, CIFS_ECHO_OP);
2935} 2974}
2936 2975
2937void smb2_reconnect_server(struct work_struct *work) 2976void smb2_reconnect_server(struct work_struct *work)
@@ -3023,7 +3062,7 @@ SMB2_echo(struct TCP_Server_Info *server)
3023 iov[0].iov_base = (char *)req; 3062 iov[0].iov_base = (char *)req;
3024 3063
3025 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL, 3064 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL,
3026 server, CIFS_ECHO_OP); 3065 server, CIFS_ECHO_OP, NULL);
3027 if (rc) 3066 if (rc)
3028 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 3067 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
3029 3068
@@ -3114,6 +3153,11 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
3114 req->MinimumCount = 0; 3153 req->MinimumCount = 0;
3115 req->Length = cpu_to_le32(io_parms->length); 3154 req->Length = cpu_to_le32(io_parms->length);
3116 req->Offset = cpu_to_le64(io_parms->offset); 3155 req->Offset = cpu_to_le64(io_parms->offset);
3156
3157 trace_smb3_read_enter(0 /* xid */,
3158 io_parms->persistent_fid,
3159 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
3160 io_parms->offset, io_parms->length);
3117#ifdef CONFIG_CIFS_SMB_DIRECT 3161#ifdef CONFIG_CIFS_SMB_DIRECT
3118 /* 3162 /*
3119 * If we want to do a RDMA write, fill in and append 3163 * If we want to do a RDMA write, fill in and append
@@ -3184,7 +3228,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
3184 struct TCP_Server_Info *server = tcon->ses->server; 3228 struct TCP_Server_Info *server = tcon->ses->server;
3185 struct smb2_sync_hdr *shdr = 3229 struct smb2_sync_hdr *shdr =
3186 (struct smb2_sync_hdr *)rdata->iov[0].iov_base; 3230 (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
3187 unsigned int credits_received = 0; 3231 struct cifs_credits credits = { .value = 0, .instance = 0 };
3188 struct smb_rqst rqst = { .rq_iov = rdata->iov, 3232 struct smb_rqst rqst = { .rq_iov = rdata->iov,
3189 .rq_nvec = 2, 3233 .rq_nvec = 2,
3190 .rq_pages = rdata->pages, 3234 .rq_pages = rdata->pages,
@@ -3199,7 +3243,8 @@ smb2_readv_callback(struct mid_q_entry *mid)
3199 3243
3200 switch (mid->mid_state) { 3244 switch (mid->mid_state) {
3201 case MID_RESPONSE_RECEIVED: 3245 case MID_RESPONSE_RECEIVED:
3202 credits_received = le16_to_cpu(shdr->CreditRequest); 3246 credits.value = le16_to_cpu(shdr->CreditRequest);
3247 credits.instance = server->reconnect_instance;
3203 /* result already set, check signature */ 3248 /* result already set, check signature */
3204 if (server->sign && !mid->decrypted) { 3249 if (server->sign && !mid->decrypted) {
3205 int rc; 3250 int rc;
@@ -3224,11 +3269,11 @@ smb2_readv_callback(struct mid_q_entry *mid)
3224 cifs_stats_bytes_read(tcon, rdata->got_bytes); 3269 cifs_stats_bytes_read(tcon, rdata->got_bytes);
3225 break; 3270 break;
3226 case MID_RESPONSE_MALFORMED: 3271 case MID_RESPONSE_MALFORMED:
3227 credits_received = le16_to_cpu(shdr->CreditRequest); 3272 credits.value = le16_to_cpu(shdr->CreditRequest);
3273 credits.instance = server->reconnect_instance;
3228 /* fall through */ 3274 /* fall through */
3229 default: 3275 default:
3230 if (rdata->result != -ENODATA) 3276 rdata->result = -EIO;
3231 rdata->result = -EIO;
3232 } 3277 }
3233#ifdef CONFIG_CIFS_SMB_DIRECT 3278#ifdef CONFIG_CIFS_SMB_DIRECT
3234 /* 3279 /*
@@ -3255,7 +3300,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
3255 3300
3256 queue_work(cifsiod_wq, &rdata->work); 3301 queue_work(cifsiod_wq, &rdata->work);
3257 DeleteMidQEntry(mid); 3302 DeleteMidQEntry(mid);
3258 add_credits(server, credits_received, 0); 3303 add_credits(server, &credits, 0);
3259} 3304}
3260 3305
3261/* smb2_async_readv - send an async read, and set up mid to handle result */ 3306/* smb2_async_readv - send an async read, and set up mid to handle result */
@@ -3285,17 +3330,8 @@ smb2_async_readv(struct cifs_readdata *rdata)
3285 3330
3286 rc = smb2_new_read_req( 3331 rc = smb2_new_read_req(
3287 (void **) &buf, &total_len, &io_parms, rdata, 0, 0); 3332 (void **) &buf, &total_len, &io_parms, rdata, 0, 0);
3288 if (rc) { 3333 if (rc)
3289 if (rc == -EAGAIN && rdata->credits) {
3290 /* credits was reset by reconnect */
3291 rdata->credits = 0;
3292 /* reduce in_flight value since we won't send the req */
3293 spin_lock(&server->req_lock);
3294 server->in_flight--;
3295 spin_unlock(&server->req_lock);
3296 }
3297 return rc; 3334 return rc;
3298 }
3299 3335
3300 if (smb3_encryption_required(io_parms.tcon)) 3336 if (smb3_encryption_required(io_parms.tcon))
3301 flags |= CIFS_TRANSFORM_REQ; 3337 flags |= CIFS_TRANSFORM_REQ;
@@ -3305,24 +3341,24 @@ smb2_async_readv(struct cifs_readdata *rdata)
3305 3341
3306 shdr = (struct smb2_sync_hdr *)buf; 3342 shdr = (struct smb2_sync_hdr *)buf;
3307 3343
3308 if (rdata->credits) { 3344 if (rdata->credits.value > 0) {
3309 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, 3345 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
3310 SMB2_MAX_BUFFER_SIZE)); 3346 SMB2_MAX_BUFFER_SIZE));
3311 shdr->CreditRequest = 3347 shdr->CreditRequest =
3312 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); 3348 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3313 spin_lock(&server->req_lock); 3349
3314 server->credits += rdata->credits - 3350 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3315 le16_to_cpu(shdr->CreditCharge); 3351 if (rc)
3316 spin_unlock(&server->req_lock); 3352 goto async_readv_out;
3317 wake_up(&server->request_q); 3353
3318 rdata->credits = le16_to_cpu(shdr->CreditCharge);
3319 flags |= CIFS_HAS_CREDITS; 3354 flags |= CIFS_HAS_CREDITS;
3320 } 3355 }
3321 3356
3322 kref_get(&rdata->refcount); 3357 kref_get(&rdata->refcount);
3323 rc = cifs_call_async(io_parms.tcon->ses->server, &rqst, 3358 rc = cifs_call_async(io_parms.tcon->ses->server, &rqst,
3324 cifs_readv_receive, smb2_readv_callback, 3359 cifs_readv_receive, smb2_readv_callback,
3325 smb3_handle_read_data, rdata, flags); 3360 smb3_handle_read_data, rdata, flags,
3361 &rdata->credits);
3326 if (rc) { 3362 if (rc) {
3327 kref_put(&rdata->refcount, cifs_readdata_release); 3363 kref_put(&rdata->refcount, cifs_readdata_release);
3328 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); 3364 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
@@ -3332,6 +3368,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
3332 io_parms.offset, io_parms.length, rc); 3368 io_parms.offset, io_parms.length, rc);
3333 } 3369 }
3334 3370
3371async_readv_out:
3335 cifs_small_buf_release(buf); 3372 cifs_small_buf_release(buf);
3336 return rc; 3373 return rc;
3337} 3374}
@@ -3378,7 +3415,10 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
3378 io_parms->tcon->tid, ses->Suid, 3415 io_parms->tcon->tid, ses->Suid,
3379 io_parms->offset, io_parms->length, 3416 io_parms->offset, io_parms->length,
3380 rc); 3417 rc);
3381 } 3418 } else
3419 trace_smb3_read_done(xid, req->PersistentFileId,
3420 io_parms->tcon->tid, ses->Suid,
3421 io_parms->offset, 0);
3382 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 3422 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
3383 return rc == -ENODATA ? 0 : rc; 3423 return rc == -ENODATA ? 0 : rc;
3384 } else 3424 } else
@@ -3417,14 +3457,16 @@ smb2_writev_callback(struct mid_q_entry *mid)
3417{ 3457{
3418 struct cifs_writedata *wdata = mid->callback_data; 3458 struct cifs_writedata *wdata = mid->callback_data;
3419 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 3459 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
3460 struct TCP_Server_Info *server = tcon->ses->server;
3420 unsigned int written; 3461 unsigned int written;
3421 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; 3462 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
3422 unsigned int credits_received = 0; 3463 struct cifs_credits credits = { .value = 0, .instance = 0 };
3423 3464
3424 switch (mid->mid_state) { 3465 switch (mid->mid_state) {
3425 case MID_RESPONSE_RECEIVED: 3466 case MID_RESPONSE_RECEIVED:
3426 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 3467 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3427 wdata->result = smb2_check_receive(mid, tcon->ses->server, 0); 3468 credits.instance = server->reconnect_instance;
3469 wdata->result = smb2_check_receive(mid, server, 0);
3428 if (wdata->result != 0) 3470 if (wdata->result != 0)
3429 break; 3471 break;
3430 3472
@@ -3448,7 +3490,8 @@ smb2_writev_callback(struct mid_q_entry *mid)
3448 wdata->result = -EAGAIN; 3490 wdata->result = -EAGAIN;
3449 break; 3491 break;
3450 case MID_RESPONSE_MALFORMED: 3492 case MID_RESPONSE_MALFORMED:
3451 credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); 3493 credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3494 credits.instance = server->reconnect_instance;
3452 /* fall through */ 3495 /* fall through */
3453 default: 3496 default:
3454 wdata->result = -EIO; 3497 wdata->result = -EIO;
@@ -3481,7 +3524,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
3481 3524
3482 queue_work(cifsiod_wq, &wdata->work); 3525 queue_work(cifsiod_wq, &wdata->work);
3483 DeleteMidQEntry(mid); 3526 DeleteMidQEntry(mid);
3484 add_credits(tcon->ses->server, credits_received, 0); 3527 add_credits(server, &credits, 0);
3485} 3528}
3486 3529
3487/* smb2_async_writev - send an async write, and set up mid to handle result */ 3530/* smb2_async_writev - send an async write, and set up mid to handle result */
@@ -3499,17 +3542,8 @@ smb2_async_writev(struct cifs_writedata *wdata,
3499 unsigned int total_len; 3542 unsigned int total_len;
3500 3543
3501 rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len); 3544 rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len);
3502 if (rc) { 3545 if (rc)
3503 if (rc == -EAGAIN && wdata->credits) { 3546 return rc;
3504 /* credits was reset by reconnect */
3505 wdata->credits = 0;
3506 /* reduce in_flight value since we won't send the req */
3507 spin_lock(&server->req_lock);
3508 server->in_flight--;
3509 spin_unlock(&server->req_lock);
3510 }
3511 goto async_writev_out;
3512 }
3513 3547
3514 if (smb3_encryption_required(tcon)) 3548 if (smb3_encryption_required(tcon))
3515 flags |= CIFS_TRANSFORM_REQ; 3549 flags |= CIFS_TRANSFORM_REQ;
@@ -3526,6 +3560,9 @@ smb2_async_writev(struct cifs_writedata *wdata,
3526 req->DataOffset = cpu_to_le16( 3560 req->DataOffset = cpu_to_le16(
3527 offsetof(struct smb2_write_req, Buffer)); 3561 offsetof(struct smb2_write_req, Buffer));
3528 req->RemainingBytes = 0; 3562 req->RemainingBytes = 0;
3563
3564 trace_smb3_write_enter(0 /* xid */, wdata->cfile->fid.persistent_fid,
3565 tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes);
3529#ifdef CONFIG_CIFS_SMB_DIRECT 3566#ifdef CONFIG_CIFS_SMB_DIRECT
3530 /* 3567 /*
3531 * If we want to do a server RDMA read, fill in and append 3568 * If we want to do a server RDMA read, fill in and append
@@ -3595,23 +3632,22 @@ smb2_async_writev(struct cifs_writedata *wdata,
3595 req->Length = cpu_to_le32(wdata->bytes); 3632 req->Length = cpu_to_le32(wdata->bytes);
3596#endif 3633#endif
3597 3634
3598 if (wdata->credits) { 3635 if (wdata->credits.value > 0) {
3599 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, 3636 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
3600 SMB2_MAX_BUFFER_SIZE)); 3637 SMB2_MAX_BUFFER_SIZE));
3601 shdr->CreditRequest = 3638 shdr->CreditRequest =
3602 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1); 3639 cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3603 spin_lock(&server->req_lock); 3640
3604 server->credits += wdata->credits - 3641 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
3605 le16_to_cpu(shdr->CreditCharge); 3642 if (rc)
3606 spin_unlock(&server->req_lock); 3643 goto async_writev_out;
3607 wake_up(&server->request_q); 3644
3608 wdata->credits = le16_to_cpu(shdr->CreditCharge);
3609 flags |= CIFS_HAS_CREDITS; 3645 flags |= CIFS_HAS_CREDITS;
3610 } 3646 }
3611 3647
3612 kref_get(&wdata->refcount); 3648 kref_get(&wdata->refcount);
3613 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL, 3649 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
3614 wdata, flags); 3650 wdata, flags, &wdata->credits);
3615 3651
3616 if (rc) { 3652 if (rc) {
3617 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId, 3653 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId,
@@ -3674,6 +3710,10 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
3674 offsetof(struct smb2_write_req, Buffer)); 3710 offsetof(struct smb2_write_req, Buffer));
3675 req->RemainingBytes = 0; 3711 req->RemainingBytes = 0;
3676 3712
3713 trace_smb3_write_enter(xid, io_parms->persistent_fid,
3714 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
3715 io_parms->offset, io_parms->length);
3716
3677 iov[0].iov_base = (char *)req; 3717 iov[0].iov_base = (char *)req;
3678 /* 1 for Buffer */ 3718 /* 1 for Buffer */
3679 iov[0].iov_len = total_len - 1; 3719 iov[0].iov_len = total_len - 1;
@@ -3836,6 +3876,9 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3836 rqst.rq_iov = iov; 3876 rqst.rq_iov = iov;
3837 rqst.rq_nvec = 2; 3877 rqst.rq_nvec = 2;
3838 3878
3879 trace_smb3_query_dir_enter(xid, persistent_fid, tcon->tid,
3880 tcon->ses->Suid, index, output_size);
3881
3839 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 3882 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3840 cifs_small_buf_release(req); 3883 cifs_small_buf_release(req);
3841 rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base; 3884 rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
@@ -3843,18 +3886,26 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3843 if (rc) { 3886 if (rc) {
3844 if (rc == -ENODATA && 3887 if (rc == -ENODATA &&
3845 rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) { 3888 rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
3889 trace_smb3_query_dir_done(xid, persistent_fid,
3890 tcon->tid, tcon->ses->Suid, index, 0);
3846 srch_inf->endOfSearch = true; 3891 srch_inf->endOfSearch = true;
3847 rc = 0; 3892 rc = 0;
3848 } else 3893 } else {
3894 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
3895 tcon->ses->Suid, index, 0, rc);
3849 cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); 3896 cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
3897 }
3850 goto qdir_exit; 3898 goto qdir_exit;
3851 } 3899 }
3852 3900
3853 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 3901 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
3854 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3902 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
3855 info_buf_size); 3903 info_buf_size);
3856 if (rc) 3904 if (rc) {
3905 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
3906 tcon->ses->Suid, index, 0, rc);
3857 goto qdir_exit; 3907 goto qdir_exit;
3908 }
3858 3909
3859 srch_inf->unicode = true; 3910 srch_inf->unicode = true;
3860 3911
@@ -3882,6 +3933,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3882 else 3933 else
3883 cifs_dbg(VFS, "illegal search buffer type\n"); 3934 cifs_dbg(VFS, "illegal search buffer type\n");
3884 3935
3936 trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid,
3937 tcon->ses->Suid, index, srch_inf->entries_in_buffer);
3885 return rc; 3938 return rc;
3886 3939
3887qdir_exit: 3940qdir_exit: