diff options
-rw-r--r-- | fs/cifs/CHANGES | 2 | ||||
-rw-r--r-- | fs/cifs/README | 11 | ||||
-rw-r--r-- | fs/cifs/cifs_debug.c | 49 | ||||
-rw-r--r-- | fs/cifs/cifs_debug.h | 5 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 6 | ||||
-rw-r--r-- | fs/cifs/connect.c | 3 | ||||
-rw-r--r-- | fs/cifs/file.c | 3 | ||||
-rw-r--r-- | fs/cifs/netmisc.c | 2 | ||||
-rw-r--r-- | fs/cifs/transport.c | 25 |
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 | |||
9 | supports large readx/writex, even when directio mount flag not specified. | 9 | supports large readx/writex, even when directio mount flag not specified. |
10 | Write size will in many cases now be 16K instead of 4K which greatly helps | 10 | Write size will in many cases now be 16K instead of 4K which greatly helps |
11 | file copy performance on lightly loaded networks. Fix oops in dnotify | 11 | file copy performance on lightly loaded networks. Fix oops in dnotify |
12 | when experimental config flag enabled. | 12 | when experimental config flag enabled. Make cifsFYI more granular. |
13 | 13 | ||
14 | Version 1.37 | 14 | Version 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 | |||
482 | kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable | 482 | kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable |
483 | tracing to the kernel message log type: | 483 | tracing to the kernel message log type: |
484 | 484 | ||
485 | echo 1 > /proc/fs/cifs/cifsFYI | 485 | echo 7 > /proc/fs/cifs/cifsFYI |
486 | 486 | ||
487 | and for more extensive tracing including the start of smb requests and responses | 487 | cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel |
488 | logging of various informational messages. 2 enables logging of non-zero | ||
489 | SMB return codes while 4 enables logging of requests that take longer | ||
490 | than one second to complete (except for byte range lock requests). | ||
491 | Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the | ||
492 | source code (typically by setting it in the beginning of cifsglob.h), | ||
493 | and setting it to seven enables all three. Finally, tracing | ||
494 | the 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 | |||
207 | static int | ||
208 | cifs_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 | |||
206 | static int | 249 | static int |
207 | cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | 250 | cifs_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 @@ | |||
26 | void cifs_dump_mem(char *label, void *data, int length); | 26 | void cifs_dump_mem(char *label, void *data, int length); |
27 | extern int traceSMB; /* flag which enables the function below */ | 27 | extern int traceSMB; /* flag which enables the function below */ |
28 | void dump_smb(struct smb_hdr *, int); | 28 | void 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 */ |
38 | extern int cifsFYI; | 41 | extern 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) | |||
605 | multi_t2_fnd: | 605 | multi_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) | |||
75 | static void | 77 | static void |
76 | DeleteMidQEntry(struct mid_q_entry *midEntry) | 78 | DeleteMidQEntry(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); |