diff options
| author | Jeff Layton <jlayton@redhat.com> | 2011-01-11 07:24:21 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2011-01-20 12:46:44 -0500 |
| commit | 766fdbb57fdb1e53bc34c431103e95383d7f13ba (patch) | |
| tree | 9e681dc6513441017603f90f45b9ffcdb5640719 /fs | |
| parent | a6827c184ea9f5452e4aaa7c799dd3c7cc9ba05e (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')
| -rw-r--r-- | fs/cifs/cifspdu.h | 15 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 47 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 2 |
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 | ||
| 764 | typedef 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 | |||
| 771 | typedef 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 | |||
| 763 | typedef struct smb_com_logoff_andx_req { | 778 | typedef 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);*/ |
| 64 | extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, | 64 | extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, |
| 65 | struct TCP_Server_Info *server); | 65 | struct TCP_Server_Info *server); |
| 66 | extern void DeleteMidQEntry(struct mid_q_entry *midEntry); | ||
| 66 | extern int cifs_call_async(struct TCP_Server_Info *server, | 67 | extern 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); |
| 360 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); | 361 | extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); |
| 362 | extern int CIFSSMBEcho(struct TCP_Server_Info *server); | ||
| 361 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); | 363 | extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); |
| 362 | 364 | ||
| 363 | extern struct cifsSesInfo *sesInfoAlloc(void); | 365 | extern 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 | */ | ||
| 716 | static void | ||
| 717 | cifs_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 | |||
| 726 | int | ||
| 727 | CIFSSMBEcho(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 | |||
| 709 | int | 756 | int |
| 710 | CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) | 757 | CIFSSMBLogoff(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 | ||
| 81 | static void | 81 | void |
| 82 | DeleteMidQEntry(struct mid_q_entry *midEntry) | 82 | DeleteMidQEntry(struct mid_q_entry *midEntry) |
| 83 | { | 83 | { |
| 84 | #ifdef CONFIG_CIFS_STATS2 | 84 | #ifdef CONFIG_CIFS_STATS2 |
