aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-01-11 07:24:21 -0500
committerSteve French <sfrench@us.ibm.com>2011-01-20 12:46:44 -0500
commit766fdbb57fdb1e53bc34c431103e95383d7f13ba (patch)
tree9e681dc6513441017603f90f45b9ffcdb5640719 /fs/cifs
parenta6827c184ea9f5452e4aaa7c799dd3c7cc9ba05e (diff)
cifs: add ability to send an echo request
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/cifs')
-rw-r--r--fs/cifs/cifspdu.h15
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c47
-rw-r--r--fs/cifs/transport.c2
4 files changed, 65 insertions, 1 deletions
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index de36b09763a8..ea205b4fcad2 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -50,6 +50,7 @@
50#define SMB_COM_SETATTR 0x09 /* trivial response */ 50#define SMB_COM_SETATTR 0x09 /* trivial response */
51#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */ 51#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
52#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/ 52#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
53#define SMB_COM_ECHO 0x2B /* echo request */
53#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */ 54#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */
54#define SMB_COM_READ_ANDX 0x2E 55#define SMB_COM_READ_ANDX 0x2E
55#define SMB_COM_WRITE_ANDX 0x2F 56#define SMB_COM_WRITE_ANDX 0x2F
@@ -760,6 +761,20 @@ typedef struct smb_com_tconx_rsp_ext {
760 * 761 *
761 */ 762 */
762 763
764typedef struct smb_com_echo_req {
765 struct smb_hdr hdr;
766 __le16 EchoCount;
767 __le16 ByteCount;
768 char Data[1];
769} __attribute__((packed)) ECHO_REQ;
770
771typedef struct smb_com_echo_rsp {
772 struct smb_hdr hdr;
773 __le16 SequenceNumber;
774 __le16 ByteCount;
775 char Data[1];
776} __attribute__((packed)) ECHO_RSP;
777
763typedef struct smb_com_logoff_andx_req { 778typedef struct smb_com_logoff_andx_req {
764 struct smb_hdr hdr; /* wct = 2 */ 779 struct smb_hdr hdr; /* wct = 2 */
765 __u8 AndXCommand; 780 __u8 AndXCommand;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7f2988bb8929..982895fa7615 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -63,6 +63,7 @@ extern char *cifs_compose_mount_options(const char *sb_mountdata,
63/* extern void renew_parental_timestamps(struct dentry *direntry);*/ 63/* extern void renew_parental_timestamps(struct dentry *direntry);*/
64extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, 64extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
65 struct TCP_Server_Info *server); 65 struct TCP_Server_Info *server);
66extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
66extern int cifs_call_async(struct TCP_Server_Info *server, 67extern int cifs_call_async(struct TCP_Server_Info *server,
67 struct smb_hdr *in_buf, mid_callback_t *callback, 68 struct smb_hdr *in_buf, mid_callback_t *callback,
68 void *cbdata); 69 void *cbdata);
@@ -358,6 +359,7 @@ extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
358 const __u64 len, struct file_lock *, 359 const __u64 len, struct file_lock *,
359 const __u16 lock_type, const bool waitFlag); 360 const __u16 lock_type, const bool waitFlag);
360extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 361extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
362extern int CIFSSMBEcho(struct TCP_Server_Info *server);
361extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 363extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
362 364
363extern struct cifsSesInfo *sesInfoAlloc(void); 365extern struct cifsSesInfo *sesInfoAlloc(void);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 3652cc60314c..54b9f5d8d1db 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -706,6 +706,53 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
706 return rc; 706 return rc;
707} 707}
708 708
709/*
710 * This is a no-op for now. We're not really interested in the reply, but
711 * rather in the fact that the server sent one and that server->lstrp
712 * gets updated.
713 *
714 * FIXME: maybe we should consider checking that the reply matches request?
715 */
716static void
717cifs_echo_callback(struct mid_q_entry *mid)
718{
719 struct TCP_Server_Info *server = mid->callback_data;
720
721 DeleteMidQEntry(mid);
722 atomic_dec(&server->inFlight);
723 wake_up(&server->request_q);
724}
725
726int
727CIFSSMBEcho(struct TCP_Server_Info *server)
728{
729 ECHO_REQ *smb;
730 int rc = 0;
731
732 cFYI(1, "In echo request");
733
734 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
735 if (rc)
736 return rc;
737
738 /* set up echo request */
739 smb->hdr.Tid = cpu_to_le16(0xffff);
740 smb->hdr.WordCount = cpu_to_le16(1);
741 smb->EchoCount = cpu_to_le16(1);
742 smb->ByteCount = cpu_to_le16(1);
743 smb->Data[0] = 'a';
744 smb->hdr.smb_buf_length += 3;
745
746 rc = cifs_call_async(server, (struct smb_hdr *)smb,
747 cifs_echo_callback, server);
748 if (rc)
749 cFYI(1, "Echo request failed: %d", rc);
750
751 cifs_small_buf_release(smb);
752
753 return rc;
754}
755
709int 756int
710CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 757CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
711{ 758{
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 166b65a3763e..a0cef4960516 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -78,7 +78,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
78 return temp; 78 return temp;
79} 79}
80 80
81static void 81void
82DeleteMidQEntry(struct mid_q_entry *midEntry) 82DeleteMidQEntry(struct mid_q_entry *midEntry)
83{ 83{
84#ifdef CONFIG_CIFS_STATS2 84#ifdef CONFIG_CIFS_STATS2