Commit cb104629 authored by Steve French's avatar Steve French Committed by Steve French

Add support for cifs per-share statistics, and add corresponding make...

Add support for cifs per-share statistics, and add corresponding make menuconfig option for cifs statistics
parent 16da6fae
...@@ -1569,20 +1569,30 @@ config CIFS ...@@ -1569,20 +1569,30 @@ config CIFS
This is the client VFS module for the Common Internet File System This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block (CIFS) protocol which is the successor to the Server Message Block
(SMB) protocol, the native file sharing mechanism for most early (SMB) protocol, the native file sharing mechanism for most early
PC operating systems. CIFS is fully supported by current network PC operating systems. The CIFS protocol is fully supported by
file servers such as Windows 2000 (including Windows NT version 4 file servers such as Windows 2000 (including Windows 2003, NT 4
and Windows XP) as well by Samba (which provides excellent CIFS and Windows XP) as well by Samba (which provides excellent CIFS
server support for Linux and many other operating systems). For server support for Linux and many other operating systems). Currently
production systems the smbfs module may be used instead of this you must use the smbfs client filesystem to access older SMB servers
cifs module since smbfs is currently more stable and provides such as Windows 9x and OS/2.
support for older servers. The intent of this module is to provide the
most advanced network file system function for CIFS compliant servers, The intent of the cifs module is to provide an advanced
network file system client for mounting to CIFS compliant servers,
including support for dfs (hierarchical name space), secure per-user including support for dfs (hierarchical name space), secure per-user
session establishment, safe distributed caching (oplock), optional session establishment, safe distributed caching (oplock), optional
packet signing, Unicode and other internationalization improvements, and packet signing, Unicode and other internationalization improvements,
optional Winbind (nsswitch) integration. This module is in an early and optional Winbind (nsswitch) integration. You do not need to enable
development stage, so unless you are specifically interested in this cifs if running only a (Samba) server. It is possible to enable both
filesystem, just say N. smbfs and cifs (e.g. if you are using CIFS for accessing Windows 2003
and Samba 3 servers, and smbfs for accessing old servers). If you need
to mount to Samba or Windows 2003 servers from this machine, say Y.
config CIFS_STATS
bool "CIFS statistics"
depends on CIFS
help
Enabling this option will cause statistics for each server share
mounted by the cifs client to be displayed in /proc/fs/cifs/DebugData
config NCP_FS config NCP_FS
tristate "NCP file system support (to mount NetWare volumes)" tristate "NCP file system support (to mount NetWare volumes)"
......
...@@ -125,7 +125,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -125,7 +125,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
length = length =
sprintf(buf, sprintf(buf,
"\n%d) %s Uses: %d on FS: %s with characteristics: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d", "\n%d) %s Uses: %d on FS: %s with characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
i, tcon->treeName, i, tcon->treeName,
atomic_read(&tcon->useCount), atomic_read(&tcon->useCount),
tcon->nativeFileSystem, tcon->nativeFileSystem,
...@@ -144,6 +144,17 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -144,6 +144,17 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
buf += length; buf += length;
if(tcon->tidStatus == CifsNeedReconnect) if(tcon->tidStatus == CifsNeedReconnect)
buf += sprintf(buf, "\tDISCONNECTED "); buf += sprintf(buf, "\tDISCONNECTED ");
#ifdef CONFIG_CIFS_STATS
length = sprintf(buf,
"\nTotal SMBs: %d Reads: %d BytesRead %lld Writes: %d BytesWritten %lld",
atomic_read(&tcon->num_smbs_sent),
atomic_read(&tcon->num_reads),
(long long)(tcon->bytes_read),
atomic_read(&tcon->num_writes),
(long long)(tcon->bytes_written));
buf += length;
#endif
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
......
...@@ -63,18 +63,4 @@ extern int cifsERROR; ...@@ -63,18 +63,4 @@ extern int cifsERROR;
#define cifserror(format,arg...) #define cifserror(format,arg...)
#endif /* _CIFS_DEBUG */ #endif /* _CIFS_DEBUG */
/*
* statistics
* ----------
*/
#ifdef _CIFS_STATISTICS
#define INCREMENT(x) ((x)++)
#define DECREMENT(x) ((x)--)
#define HIGHWATERMARK(x,y) x = MAX((x), (y))
#else
#define INCREMENT(x)
#define DECREMENT(x)
#define HIGHWATERMARK(x,y)
#endif /* _CIFS_STATISTICS */
#endif /* _H_CIFS_DEBUG */ #endif /* _H_CIFS_DEBUG */
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
/* BB when mempool_resize is added back in, we will resize pool on new mount */ /* BB when mempool_resize is added back in, we will resize pool on new mount */
#define CIFS_MIN_RCV_POOL 11 /* enough for progress to five servers */ #define CIFS_MIN_RCV_POOL 11 /* enough for progress to five servers */
#ifdef CIFS_QUOTA #ifdef CONFIG_CIFS_QUOTA
static struct quotactl_ops cifs_quotactl_ops; static struct quotactl_ops cifs_quotactl_ops;
#endif #endif
...@@ -103,7 +103,7 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -103,7 +103,7 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_op = &cifs_super_ops; sb->s_op = &cifs_super_ops;
/* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) /* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
#ifdef CIFS_QUOTA #ifdef CONFIG_CIFS_QUOTA
sb->s_qcop = &cifs_quotactl_ops; sb->s_qcop = &cifs_quotactl_ops;
#endif #endif
sb->s_blocksize = CIFS_MAX_MSGSIZE; sb->s_blocksize = CIFS_MAX_MSGSIZE;
...@@ -276,7 +276,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -276,7 +276,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
return 0; return 0;
} }
#ifdef CIFS_QUOTA #ifdef CONFIG_CIFS_QUOTA
int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid, int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
struct fs_disk_quota * pdquota) struct fs_disk_quota * pdquota)
{ {
...@@ -509,7 +509,7 @@ struct inode_operations cifs_file_inode_ops = { ...@@ -509,7 +509,7 @@ struct inode_operations cifs_file_inode_ops = {
.getattr = cifs_getattr, /* do we need this anymore? */ .getattr = cifs_getattr, /* do we need this anymore? */
.rename = cifs_rename, .rename = cifs_rename,
.permission = cifs_permission, .permission = cifs_permission,
#ifdef CIFS_XATTR #ifdef CONFIG_CIFS_XATTR
.setxattr = cifs_setxattr, .setxattr = cifs_setxattr,
.getxattr = cifs_getxattr, .getxattr = cifs_getxattr,
.listxattr = cifs_listxattr, .listxattr = cifs_listxattr,
...@@ -524,7 +524,7 @@ struct inode_operations cifs_symlink_inode_ops = { ...@@ -524,7 +524,7 @@ struct inode_operations cifs_symlink_inode_ops = {
/* BB add the following two eventually */ /* BB add the following two eventually */
/* revalidate: cifs_revalidate, /* revalidate: cifs_revalidate,
setattr: cifs_notify_change, *//* BB do we need notify change */ setattr: cifs_notify_change, *//* BB do we need notify change */
#ifdef CIFS_XATTR #ifdef CONFIG_CIFS_XATTR
.setxattr = cifs_setxattr, .setxattr = cifs_setxattr,
.getxattr = cifs_getxattr, .getxattr = cifs_getxattr,
.listxattr = cifs_listxattr, .listxattr = cifs_listxattr,
...@@ -542,7 +542,7 @@ struct file_operations cifs_file_ops = { ...@@ -542,7 +542,7 @@ struct file_operations cifs_file_ops = {
.flush = cifs_flush, .flush = cifs_flush,
.mmap = cifs_file_mmap, .mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile, .sendfile = generic_file_sendfile,
#ifdef CIFS_FCNTL #ifdef CONFIG_CIFS_FCNTL
.fcntl = cifs_fcntl, .fcntl = cifs_fcntl,
#endif #endif
}; };
...@@ -551,7 +551,7 @@ struct file_operations cifs_dir_ops = { ...@@ -551,7 +551,7 @@ struct file_operations cifs_dir_ops = {
.readdir = cifs_readdir, .readdir = cifs_readdir,
.release = cifs_closedir, .release = cifs_closedir,
.read = generic_read_dir, .read = generic_read_dir,
#ifdef CIFS_FCNTL #ifdef CONFIG_CIFS_FCNTL
.fcntl = cifs_fcntl, .fcntl = cifs_fcntl,
#endif #endif
}; };
......
...@@ -197,6 +197,14 @@ struct cifsTconInfo { ...@@ -197,6 +197,14 @@ struct cifsTconInfo {
__u16 Flags; /* optional support bits */ __u16 Flags; /* optional support bits */
enum statusEnum tidStatus; enum statusEnum tidStatus;
atomic_t useCount; /* how many mounts (explicit or implicit) to this share */ atomic_t useCount; /* how many mounts (explicit or implicit) to this share */
#ifdef CONFIG_CIFS_STATS
atomic_t num_smbs_sent;
atomic_t num_writes;
atomic_t num_reads;
__u64 bytes_read;
__u64 bytes_written;
spinlock_t stat_lock;
#endif
FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */
FILE_SYSTEM_UNIX_INFO fsUnixInfo; FILE_SYSTEM_UNIX_INFO fsUnixInfo;
......
...@@ -1687,7 +1687,7 @@ struct data_blob { ...@@ -1687,7 +1687,7 @@ struct data_blob {
void (*free) (struct data_blob * data_blob); void (*free) (struct data_blob * data_blob);
}; };
#ifdef CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
/* /*
For better POSIX semantics from Linux client, (even better For better POSIX semantics from Linux client, (even better
than the existing CIFS Unix Extensions) we need updated PDUs for: than the existing CIFS Unix Extensions) we need updated PDUs for:
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "cifs_unicode.h" #include "cifs_unicode.h"
#include "cifs_debug.h" #include "cifs_debug.h"
#ifdef CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
static struct { static struct {
int index; int index;
char *name; char *name;
...@@ -155,6 +155,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -155,6 +155,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
*request_buf = cifs_buf_get(); *request_buf = cifs_buf_get();
if (*request_buf == 0) { if (*request_buf == 0) {
/* BB should we add a retry in here if not a writepage? */
return -ENOMEM; return -ENOMEM;
} }
/* Although the original thought was we needed the response buf for */ /* Although the original thought was we needed the response buf for */
...@@ -165,6 +166,12 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -165,6 +166,12 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
wct /*wct */ ); wct /*wct */ );
#ifdef CONFIG_CIFS_STATS
if(tcon != NULL) {
atomic_inc(&tcon->num_smbs_sent);
}
#endif
return rc; return rc;
} }
......
...@@ -628,12 +628,21 @@ cifs_write(struct file * file, const char *write_data, ...@@ -628,12 +628,21 @@ cifs_write(struct file * file, const char *write_data,
long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */ long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
} }
#ifdef CONFIG_CIFS_STATS
if(total_written > 0) {
atomic_inc(&pTcon->num_writes);
spin_lock(&pTcon->stat_lock);
pTcon->bytes_written += total_written;
spin_unlock(&pTcon->stat_lock);
}
#endif
/* since the write may have blocked check these pointers again */ /* since the write may have blocked check these pointers again */
if(file->f_dentry) { if(file->f_dentry) {
if(file->f_dentry->d_inode) { if(file->f_dentry->d_inode) {
file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime = file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
CURRENT_TIME; CURRENT_TIME;
if (bytes_written > 0) { if (total_written > 0) {
if (*poffset > file->f_dentry->d_inode->i_size) if (*poffset > file->f_dentry->d_inode->i_size)
i_size_write(file->f_dentry->d_inode, *poffset); i_size_write(file->f_dentry->d_inode, *poffset);
} }
...@@ -939,10 +948,15 @@ cifs_read(struct file * file, char *read_data, size_t read_size, ...@@ -939,10 +948,15 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
return rc; return rc;
} }
} else { } else {
#ifdef CONFIG_CIFS_STATS
atomic_inc(&pTcon->num_reads);
spin_lock(&pTcon->stat_lock);
pTcon->bytes_read += total_read;
spin_unlock(&pTcon->stat_lock);
#endif
*poffset += bytes_read; *poffset += bytes_read;
} }
} }
FreeXid(xid); FreeXid(xid);
return total_read; return total_read;
} }
...@@ -1104,7 +1118,12 @@ cifs_readpages(struct file *file, struct address_space *mapping, ...@@ -1104,7 +1118,12 @@ cifs_readpages(struct file *file, struct address_space *mapping,
le16_to_cpu(pSMBr->DataOffset), &lru_pvec); le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
i += bytes_read >> PAGE_CACHE_SHIFT; i += bytes_read >> PAGE_CACHE_SHIFT;
#ifdef CONFIG_CIFS_STATS
atomic_inc(&pTcon->num_reads);
spin_lock(&pTcon->stat_lock);
pTcon->bytes_read += bytes_read;
spin_unlock(&pTcon->stat_lock);
#endif
if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
cFYI(1,("Partial page %d of %d read to cache",i++,num_pages)); cFYI(1,("Partial page %d of %d read to cache",i++,num_pages));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment