[CIFS] CIFS Stats improvements

New cifs_writepages routine was not updated bytes written in cifs stats.
Also added ability to clear /proc/fs/cifs/Stats by writing (0 or 1) to it.
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Steve French 2005-10-11 19:58:06 -07:00
Родитель 4ca9c190d9
Коммит 1047abc159
9 изменённых файлов: 98 добавлений и 8 удалений

Просмотреть файл

@ -9,7 +9,7 @@ wsize and rsize can now be larger than negotiated buffer size if server
supports large readx/writex, even when directio mount flag not specified. supports large readx/writex, even when directio mount flag not specified.
Write size will in many cases now be 16K instead of 4K which greatly helps Write size will in many cases now be 16K instead of 4K which greatly helps
file copy performance on lightly loaded networks. Fix oops in dnotify file copy performance on lightly loaded networks. Fix oops in dnotify
when experimental config flag enabled. when experimental config flag enabled. Make cifsFYI more granular.
Version 1.37 Version 1.37
------------ ------------

Просмотреть файл

@ -482,9 +482,16 @@ These experimental features and tracing can be enabled by changing flags in
kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable
tracing to the kernel message log type: tracing to the kernel message log type:
echo 1 > /proc/fs/cifs/cifsFYI echo 7 > /proc/fs/cifs/cifsFYI
and for more extensive tracing including the start of smb requests and responses cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
logging of various informational messages. 2 enables logging of non-zero
SMB return codes while 4 enables logging of requests that take longer
than one second to complete (except for byte range lock requests).
Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
source code (typically by setting it in the beginning of cifsglob.h),
and setting it to seven enables all three. Finally, tracing
the start of smb requests and responses can be enabled via:
echo 1 > /proc/fs/cifs/traceSMB echo 1 > /proc/fs/cifs/traceSMB

Просмотреть файл

@ -203,6 +203,49 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
} }
#ifdef CONFIG_CIFS_STATS #ifdef CONFIG_CIFS_STATS
static int
cifs_stats_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
int rc;
struct list_head *tmp;
struct cifsTconInfo *tcon;
rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '1' || c == 'y' || c == 'Y') {
read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo,
cifsConnectionList);
atomic_set(&tcon->num_smbs_sent, 0);
atomic_set(&tcon->num_writes, 0);
atomic_set(&tcon->num_reads, 0);
atomic_set(&tcon->num_oplock_brks, 0);
atomic_set(&tcon->num_opens, 0);
atomic_set(&tcon->num_closes, 0);
atomic_set(&tcon->num_deletes, 0);
atomic_set(&tcon->num_mkdirs, 0);
atomic_set(&tcon->num_rmdirs, 0);
atomic_set(&tcon->num_renames, 0);
atomic_set(&tcon->num_t2renames, 0);
atomic_set(&tcon->num_ffirst, 0);
atomic_set(&tcon->num_fnext, 0);
atomic_set(&tcon->num_fclose, 0);
atomic_set(&tcon->num_hardlinks, 0);
atomic_set(&tcon->num_symlinks, 0);
atomic_set(&tcon->num_locks, 0);
}
read_unlock(&GlobalSMBSeslock);
}
return count;
}
static int static int
cifs_stats_read(char *buf, char **beginBuffer, off_t offset, cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
int count, int *eof, void *data) int count, int *eof, void *data)
@ -365,8 +408,10 @@ cifs_proc_init(void)
cifs_debug_data_read, NULL); cifs_debug_data_read, NULL);
#ifdef CONFIG_CIFS_STATS #ifdef CONFIG_CIFS_STATS
create_proc_read_entry("Stats", 0, proc_fs_cifs, pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
cifs_stats_read, NULL); cifs_stats_read, NULL);
if (pde)
pde->write_proc = cifs_stats_write;
#endif #endif
pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
cifsFYI_read, NULL); cifsFYI_read, NULL);
@ -483,6 +528,8 @@ cifsFYI_write(struct file *file, const char __user *buffer,
cifsFYI = 0; cifsFYI = 0;
else if (c == '1' || c == 'y' || c == 'Y') else if (c == '1' || c == 'y' || c == 'Y')
cifsFYI = 1; cifsFYI = 1;
else if((c > '1') && (c <= '9'))
cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
return count; return count;
} }

Просмотреть файл

@ -26,6 +26,9 @@
void cifs_dump_mem(char *label, void *data, int length); void cifs_dump_mem(char *label, void *data, int length);
extern int traceSMB; /* flag which enables the function below */ extern int traceSMB; /* flag which enables the function below */
void dump_smb(struct smb_hdr *, int); void dump_smb(struct smb_hdr *, int);
#define CIFS_INFO 0x01
#define CIFS_RC 0x02
#define CIFS_TIMER 0x04
/* /*
* debug ON * debug ON
@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int);
/* information message: e.g., configuration, major event */ /* information message: e.g., configuration, major event */
extern int cifsFYI; extern int cifsFYI;
#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg) #define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
#define cFYI(button,prspec) if (button) cifsfyi prspec #define cFYI(button,prspec) if (button) cifsfyi prspec

Просмотреть файл

@ -377,7 +377,11 @@ struct mid_q_entry {
__u16 mid; /* multiplex id */ __u16 mid; /* multiplex id */
__u16 pid; /* process id */ __u16 pid; /* process id */
__u32 sequence_number; /* for CIFS signing */ __u32 sequence_number; /* for CIFS signing */
struct timeval when_sent; /* time when smb sent */ unsigned long when_alloc; /* when mid was created */
#ifdef CONFIG_CIFS_STATS2
unsigned long when_sent; /* time when smb send finished */
unsigned long when_received; /* when demux complete (taken off wire) */
#endif
struct cifsSesInfo *ses; /* smb was sent to this server */ struct cifsSesInfo *ses; /* smb was sent to this server */
struct task_struct *tsk; /* task waiting for response */ struct task_struct *tsk; /* task waiting for response */
struct smb_hdr *resp_buf; /* response buffer */ struct smb_hdr *resp_buf; /* response buffer */

Просмотреть файл

@ -605,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
multi_t2_fnd: multi_t2_fnd:
task_to_wake = mid_entry->tsk; task_to_wake = mid_entry->tsk;
mid_entry->midState = MID_RESPONSE_RECEIVED; mid_entry->midState = MID_RESPONSE_RECEIVED;
#ifdef CONFIG_CIFS_STATS2
mid_entry->when_received = jiffies;
#endif
break; break;
} }
} }

Просмотреть файл

@ -1153,6 +1153,9 @@ retry:
rc, bytes_written)); rc, bytes_written));
set_bit(AS_EIO, &mapping->flags); set_bit(AS_EIO, &mapping->flags);
SetPageError(page); SetPageError(page);
} else {
cifs_stats_bytes_written(cifs_sb->tcon,
bytes_written);
} }
for (i = 0; i < n_iov; i++) { for (i = 0; i < n_iov; i++) {
page = pvec.pages[first + i]; page = pvec.pages[first + i];

Просмотреть файл

@ -813,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
if (smb->Flags2 & SMBFLG2_ERR_STATUS) { if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
/* translate the newer STATUS codes to old style errors and then to POSIX errors */ /* translate the newer STATUS codes to old style errors and then to POSIX errors */
__u32 err = le32_to_cpu(smb->Status.CifsError); __u32 err = le32_to_cpu(smb->Status.CifsError);
if(cifsFYI) if(cifsFYI & CIFS_RC)
cifs_print_status(err); cifs_print_status(err);
ntstatus_to_dos(err, &smberrclass, &smberrcode); ntstatus_to_dos(err, &smberrclass, &smberrcode);
} else { } else {

Просмотреть файл

@ -59,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->pid = current->pid; temp->pid = current->pid;
temp->command = smb_buffer->Command; temp->command = smb_buffer->Command;
cFYI(1, ("For smb_command %d", temp->command)); cFYI(1, ("For smb_command %d", temp->command));
do_gettimeofday(&temp->when_sent); /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
/* when mid allocated can be before when sent */
temp->when_alloc = jiffies;
temp->ses = ses; temp->ses = ses;
temp->tsk = current; temp->tsk = current;
} }
@ -75,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
static void static void
DeleteMidQEntry(struct mid_q_entry *midEntry) DeleteMidQEntry(struct mid_q_entry *midEntry)
{ {
#ifdef CONFIG_CIFS_STATS2
unsigned long now;
#endif
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
midEntry->midState = MID_FREE; midEntry->midState = MID_FREE;
list_del(&midEntry->qhead); list_del(&midEntry->qhead);
@ -84,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
cifs_buf_release(midEntry->resp_buf); cifs_buf_release(midEntry->resp_buf);
else else
cifs_small_buf_release(midEntry->resp_buf); cifs_small_buf_release(midEntry->resp_buf);
#ifdef CONFIG_CIFS_STATS2
now = jiffies;
/* commands taking longer than one second are indications that
something is wrong, unless it is quite a slow link or server */
if((now - midEntry->when_alloc) > HZ) {
if((cifsFYI & CIFS_TIMER) &&
(midEntry->command != SMB_COM_LOCKING_ANDX)) {
printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
midEntry->command, midEntry->mid);
printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
now - midEntry->when_alloc,
now - midEntry->when_sent,
now - midEntry->when_received);
}
}
#endif
mempool_free(midEntry, cifs_mid_poolp); mempool_free(midEntry, cifs_mid_poolp);
} }
@ -382,6 +403,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
(struct sockaddr *) &(ses->server->addr.sockAddr)); (struct sockaddr *) &(ses->server->addr.sockAddr));
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_dec(&ses->server->inSend); atomic_dec(&ses->server->inSend);
midQ->when_sent = jiffies;
#endif #endif
if(rc < 0) { if(rc < 0) {
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);
@ -646,6 +668,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
(struct sockaddr *) &(ses->server->addr.sockAddr)); (struct sockaddr *) &(ses->server->addr.sockAddr));
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_dec(&ses->server->inSend); atomic_dec(&ses->server->inSend);
midQ->when_sent = jiffies;
#endif #endif
if(rc < 0) { if(rc < 0) {
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);