diff options
author | Jeff Layton <jlayton@redhat.com> | 2011-01-11 07:24:24 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-01-20 13:08:36 -0500 |
commit | 76dcc26f1d7f1c98c3f595379dcd9562f01bf38d (patch) | |
tree | 98ff38d579542700ef79dd2e0b0f331524e7c1a6 /fs | |
parent | 7749981ec31aa40e28a1ef5687e46bc1aa278fae (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.c | 63 |
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 | */ | ||
477 | static int | ||
478 | send_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 | |||
467 | int | 504 | int |
468 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | 505 | SendReceive2(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 | |||
758 | static int | ||
759 | send_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; |