aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-01-11 07:24:24 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-20 13:08:36 -0500
commit76dcc26f1d7f1c98c3f595379dcd9562f01bf38d (patch)
tree98ff38d579542700ef79dd2e0b0f331524e7c1a6 /fs
parent7749981ec31aa40e28a1ef5687e46bc1aa278fae (diff)
cifs: mangle existing header for SMB_COM_NT_CANCEL
The NT_CANCEL command looks just like the original command, except for a few small differences. The send_nt_cancel function however currently takes a tcon, which we don't have in SendReceive and SendReceive2. Instead of "respinning" the entire header for an NT_CANCEL, just mangle the existing header by replacing just the fields we need. This means we don't need a tcon and allows us to call it from other places. Reviewed-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Suresh Jayaraman <sjayaraman@suse.de> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/transport.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index fe92c4cb75f5..c8e2808cd5e6 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -464,6 +464,43 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
464 return rc; 464 return rc;
465} 465}
466 466
467/*
468 * An NT cancel request header looks just like the original request except:
469 *
470 * The Command is SMB_COM_NT_CANCEL
471 * The WordCount is zeroed out
472 * The ByteCount is zeroed out
473 *
474 * This function mangles an existing request buffer into a
475 * SMB_COM_NT_CANCEL request and then sends it.
476 */
477static int
478send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
479 struct mid_q_entry *mid)
480{
481 int rc = 0;
482
483 /* -4 for RFC1001 length and +2 for BCC field */
484 in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4 + 2;
485 in_buf->Command = SMB_COM_NT_CANCEL;
486 in_buf->WordCount = 0;
487 BCC_LE(in_buf) = 0;
488
489 mutex_lock(&server->srv_mutex);
490 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
491 if (rc) {
492 mutex_unlock(&server->srv_mutex);
493 return rc;
494 }
495 rc = smb_send(server, in_buf, in_buf->smb_buf_length);
496 mutex_unlock(&server->srv_mutex);
497
498 cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
499 in_buf->Mid, rc);
500
501 return rc;
502}
503
467int 504int
468SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 505SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
469 struct kvec *iov, int n_vec, int *pRespBufType /* ret */, 506 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
@@ -753,29 +790,6 @@ out:
753 return rc; 790 return rc;
754} 791}
755 792
756/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
757
758static int
759send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
760 struct mid_q_entry *midQ)
761{
762 int rc = 0;
763 struct cifsSesInfo *ses = tcon->ses;
764 __u16 mid = in_buf->Mid;
765
766 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
767 in_buf->Mid = mid;
768 mutex_lock(&ses->server->srv_mutex);
769 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
770 if (rc) {
771 mutex_unlock(&ses->server->srv_mutex);
772 return rc;
773 }
774 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
775 mutex_unlock(&ses->server->srv_mutex);
776 return rc;
777}
778
779/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows 793/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
780 blocking lock to return. */ 794 blocking lock to return. */
781 795
@@ -890,8 +904,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
890 if (in_buf->Command == SMB_COM_TRANSACTION2) { 904 if (in_buf->Command == SMB_COM_TRANSACTION2) {
891 /* POSIX lock. We send a NT_CANCEL SMB to cause the 905 /* POSIX lock. We send a NT_CANCEL SMB to cause the
892 blocking lock to return. */ 906 blocking lock to return. */
893 907 rc = send_nt_cancel(ses->server, in_buf, midQ);
894 rc = send_nt_cancel(tcon, in_buf, midQ);
895 if (rc) { 908 if (rc) {
896 delete_mid(midQ); 909 delete_mid(midQ);
897 return rc; 910 return rc;