aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/README11
-rw-r--r--fs/cifs/cifs_debug.c49
-rw-r--r--fs/cifs/cifs_debug.h5
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/connect.c3
-rw-r--r--fs/cifs/file.c3
-rw-r--r--fs/cifs/netmisc.c2
-rw-r--r--fs/cifs/transport.c25
9 files changed, 98 insertions, 8 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index b2a938378bef..f554a70c9cf3 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -9,7 +9,7 @@ wsize and rsize can now be larger than negotiated buffer size if server
9supports large readx/writex, even when directio mount flag not specified. 9supports large readx/writex, even when directio mount flag not specified.
10Write size will in many cases now be 16K instead of 4K which greatly helps 10Write size will in many cases now be 16K instead of 4K which greatly helps
11file copy performance on lightly loaded networks. Fix oops in dnotify 11file copy performance on lightly loaded networks. Fix oops in dnotify
12when experimental config flag enabled. 12when experimental config flag enabled. Make cifsFYI more granular.
13 13
14Version 1.37 14Version 1.37
15------------ 15------------
diff --git a/fs/cifs/README b/fs/cifs/README
index e7a3ce62d71b..bb90941826ad 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -482,9 +482,16 @@ These experimental features and tracing can be enabled by changing flags in
482kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable 482kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable
483tracing to the kernel message log type: 483tracing to the kernel message log type:
484 484
485 echo 1 > /proc/fs/cifs/cifsFYI 485 echo 7 > /proc/fs/cifs/cifsFYI
486 486
487and for more extensive tracing including the start of smb requests and responses 487cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
488logging of various informational messages. 2 enables logging of non-zero
489SMB return codes while 4 enables logging of requests that take longer
490than one second to complete (except for byte range lock requests).
491Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
492source code (typically by setting it in the beginning of cifsglob.h),
493and setting it to seven enables all three. Finally, tracing
494the start of smb requests and responses can be enabled via:
488 495
489 echo 1 > /proc/fs/cifs/traceSMB 496 echo 1 > /proc/fs/cifs/traceSMB
490 497
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 6f7810992db3..f4054d695f81 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -203,6 +203,49 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
203} 203}
204 204
205#ifdef CONFIG_CIFS_STATS 205#ifdef CONFIG_CIFS_STATS
206
207static int
208cifs_stats_write(struct file *file, const char __user *buffer,
209 unsigned long count, void *data)
210{
211 char c;
212 int rc;
213 struct list_head *tmp;
214 struct cifsTconInfo *tcon;
215
216 rc = get_user(c, buffer);
217 if (rc)
218 return rc;
219
220 if (c == '1' || c == 'y' || c == 'Y') {
221 read_lock(&GlobalSMBSeslock);
222 list_for_each(tmp, &GlobalTreeConnectionList) {
223 tcon = list_entry(tmp, struct cifsTconInfo,
224 cifsConnectionList);
225 atomic_set(&tcon->num_smbs_sent, 0);
226 atomic_set(&tcon->num_writes, 0);
227 atomic_set(&tcon->num_reads, 0);
228 atomic_set(&tcon->num_oplock_brks, 0);
229 atomic_set(&tcon->num_opens, 0);
230 atomic_set(&tcon->num_closes, 0);
231 atomic_set(&tcon->num_deletes, 0);
232 atomic_set(&tcon->num_mkdirs, 0);
233 atomic_set(&tcon->num_rmdirs, 0);
234 atomic_set(&tcon->num_renames, 0);
235 atomic_set(&tcon->num_t2renames, 0);
236 atomic_set(&tcon->num_ffirst, 0);
237 atomic_set(&tcon->num_fnext, 0);
238 atomic_set(&tcon->num_fclose, 0);
239 atomic_set(&tcon->num_hardlinks, 0);
240 atomic_set(&tcon->num_symlinks, 0);
241 atomic_set(&tcon->num_locks, 0);
242 }
243 read_unlock(&GlobalSMBSeslock);
244 }
245
246 return count;
247}
248
206static int 249static int
207cifs_stats_read(char *buf, char **beginBuffer, off_t offset, 250cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
208 int count, int *eof, void *data) 251 int count, int *eof, void *data)
@@ -365,8 +408,10 @@ cifs_proc_init(void)
365 cifs_debug_data_read, NULL); 408 cifs_debug_data_read, NULL);
366 409
367#ifdef CONFIG_CIFS_STATS 410#ifdef CONFIG_CIFS_STATS
368 create_proc_read_entry("Stats", 0, proc_fs_cifs, 411 pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
369 cifs_stats_read, NULL); 412 cifs_stats_read, NULL);
413 if (pde)
414 pde->write_proc = cifs_stats_write;
370#endif 415#endif
371 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, 416 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
372 cifsFYI_read, NULL); 417 cifsFYI_read, NULL);
@@ -483,6 +528,8 @@ cifsFYI_write(struct file *file, const char __user *buffer,
483 cifsFYI = 0; 528 cifsFYI = 0;
484 else if (c == '1' || c == 'y' || c == 'Y') 529 else if (c == '1' || c == 'y' || c == 'Y')
485 cifsFYI = 1; 530 cifsFYI = 1;
531 else if((c > '1') && (c <= '9'))
532 cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
486 533
487 return count; 534 return count;
488} 535}
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index bf24d2828f68..4304d9dcfb6c 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -26,6 +26,9 @@
26void cifs_dump_mem(char *label, void *data, int length); 26void cifs_dump_mem(char *label, void *data, int length);
27extern int traceSMB; /* flag which enables the function below */ 27extern int traceSMB; /* flag which enables the function below */
28void dump_smb(struct smb_hdr *, int); 28void dump_smb(struct smb_hdr *, int);
29#define CIFS_INFO 0x01
30#define CIFS_RC 0x02
31#define CIFS_TIMER 0x04
29 32
30/* 33/*
31 * debug ON 34 * debug ON
@@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int);
36 39
37/* information message: e.g., configuration, major event */ 40/* information message: e.g., configuration, major event */
38extern int cifsFYI; 41extern int cifsFYI;
39#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg) 42#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
40 43
41#define cFYI(button,prspec) if (button) cifsfyi prspec 44#define cFYI(button,prspec) if (button) cifsfyi prspec
42 45
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 729717281b40..839a55667c3c 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -377,7 +377,11 @@ struct mid_q_entry {
377 __u16 mid; /* multiplex id */ 377 __u16 mid; /* multiplex id */
378 __u16 pid; /* process id */ 378 __u16 pid; /* process id */
379 __u32 sequence_number; /* for CIFS signing */ 379 __u32 sequence_number; /* for CIFS signing */
380 struct timeval when_sent; /* time when smb sent */ 380 unsigned long when_alloc; /* when mid was created */
381#ifdef CONFIG_CIFS_STATS2
382 unsigned long when_sent; /* time when smb send finished */
383 unsigned long when_received; /* when demux complete (taken off wire) */
384#endif
381 struct cifsSesInfo *ses; /* smb was sent to this server */ 385 struct cifsSesInfo *ses; /* smb was sent to this server */
382 struct task_struct *tsk; /* task waiting for response */ 386 struct task_struct *tsk; /* task waiting for response */
383 struct smb_hdr *resp_buf; /* response buffer */ 387 struct smb_hdr *resp_buf; /* response buffer */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 177289771abe..a8f0cbada0f0 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -605,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
605multi_t2_fnd: 605multi_t2_fnd:
606 task_to_wake = mid_entry->tsk; 606 task_to_wake = mid_entry->tsk;
607 mid_entry->midState = MID_RESPONSE_RECEIVED; 607 mid_entry->midState = MID_RESPONSE_RECEIVED;
608#ifdef CONFIG_CIFS_STATS2
609 mid_entry->when_received = jiffies;
610#endif
608 break; 611 break;
609 } 612 }
610 } 613 }
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 11806c879c47..585a62aebd59 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1153,6 +1153,9 @@ retry:
1153 rc, bytes_written)); 1153 rc, bytes_written));
1154 set_bit(AS_EIO, &mapping->flags); 1154 set_bit(AS_EIO, &mapping->flags);
1155 SetPageError(page); 1155 SetPageError(page);
1156 } else {
1157 cifs_stats_bytes_written(cifs_sb->tcon,
1158 bytes_written);
1156 } 1159 }
1157 for (i = 0; i < n_iov; i++) { 1160 for (i = 0; i < n_iov; i++) {
1158 page = pvec.pages[first + i]; 1161 page = pvec.pages[first + i];
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 29e6efc5597c..f7814689844b 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -813,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
813 if (smb->Flags2 & SMBFLG2_ERR_STATUS) { 813 if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
814 /* translate the newer STATUS codes to old style errors and then to POSIX errors */ 814 /* translate the newer STATUS codes to old style errors and then to POSIX errors */
815 __u32 err = le32_to_cpu(smb->Status.CifsError); 815 __u32 err = le32_to_cpu(smb->Status.CifsError);
816 if(cifsFYI) 816 if(cifsFYI & CIFS_RC)
817 cifs_print_status(err); 817 cifs_print_status(err);
818 ntstatus_to_dos(err, &smberrclass, &smberrcode); 818 ntstatus_to_dos(err, &smberrclass, &smberrcode);
819 } else { 819 } else {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index d8865fbd876a..981ea0d8b9cd 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -59,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
59 temp->pid = current->pid; 59 temp->pid = current->pid;
60 temp->command = smb_buffer->Command; 60 temp->command = smb_buffer->Command;
61 cFYI(1, ("For smb_command %d", temp->command)); 61 cFYI(1, ("For smb_command %d", temp->command));
62 do_gettimeofday(&temp->when_sent); 62 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
63 /* when mid allocated can be before when sent */
64 temp->when_alloc = jiffies;
63 temp->ses = ses; 65 temp->ses = ses;
64 temp->tsk = current; 66 temp->tsk = current;
65 } 67 }
@@ -75,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
75static void 77static void
76DeleteMidQEntry(struct mid_q_entry *midEntry) 78DeleteMidQEntry(struct mid_q_entry *midEntry)
77{ 79{
80#ifdef CONFIG_CIFS_STATS2
81 unsigned long now;
82#endif
78 spin_lock(&GlobalMid_Lock); 83 spin_lock(&GlobalMid_Lock);
79 midEntry->midState = MID_FREE; 84 midEntry->midState = MID_FREE;
80 list_del(&midEntry->qhead); 85 list_del(&midEntry->qhead);
@@ -84,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
84 cifs_buf_release(midEntry->resp_buf); 89 cifs_buf_release(midEntry->resp_buf);
85 else 90 else
86 cifs_small_buf_release(midEntry->resp_buf); 91 cifs_small_buf_release(midEntry->resp_buf);
92#ifdef CONFIG_CIFS_STATS2
93 now = jiffies;
94 /* commands taking longer than one second are indications that
95 something is wrong, unless it is quite a slow link or server */
96 if((now - midEntry->when_alloc) > HZ) {
97 if((cifsFYI & CIFS_TIMER) &&
98 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
99 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
100 midEntry->command, midEntry->mid);
101 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
102 now - midEntry->when_alloc,
103 now - midEntry->when_sent,
104 now - midEntry->when_received);
105 }
106 }
107#endif
87 mempool_free(midEntry, cifs_mid_poolp); 108 mempool_free(midEntry, cifs_mid_poolp);
88} 109}
89 110
@@ -382,6 +403,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
382 (struct sockaddr *) &(ses->server->addr.sockAddr)); 403 (struct sockaddr *) &(ses->server->addr.sockAddr));
383#ifdef CONFIG_CIFS_STATS2 404#ifdef CONFIG_CIFS_STATS2
384 atomic_dec(&ses->server->inSend); 405 atomic_dec(&ses->server->inSend);
406 midQ->when_sent = jiffies;
385#endif 407#endif
386 if(rc < 0) { 408 if(rc < 0) {
387 DeleteMidQEntry(midQ); 409 DeleteMidQEntry(midQ);
@@ -646,6 +668,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
646 (struct sockaddr *) &(ses->server->addr.sockAddr)); 668 (struct sockaddr *) &(ses->server->addr.sockAddr));
647#ifdef CONFIG_CIFS_STATS2 669#ifdef CONFIG_CIFS_STATS2
648 atomic_dec(&ses->server->inSend); 670 atomic_dec(&ses->server->inSend);
671 midQ->when_sent = jiffies;
649#endif 672#endif
650 if(rc < 0) { 673 if(rc < 0) {
651 DeleteMidQEntry(midQ); 674 DeleteMidQEntry(midQ);