[funini.com] -> [kei@sodan] -> Kernel Reading

root/fs/cifs/cifs_debug.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cifs_dump_mem
  2. cifs_dump_detail
  3. cifs_dump_mids
  4. cifs_debug_data_proc_show
  5. cifs_debug_data_proc_open
  6. cifs_stats_proc_write
  7. cifs_stats_proc_show
  8. cifs_stats_proc_open
  9. cifs_proc_init
  10. cifs_proc_clean
  11. cifsFYI_proc_show
  12. cifsFYI_proc_open
  13. cifsFYI_proc_write
  14. cifs_oplock_proc_show
  15. cifs_oplock_proc_open
  16. cifs_oplock_proc_write
  17. cifs_experimental_proc_show
  18. cifs_experimental_proc_open
  19. cifs_experimental_proc_write
  20. cifs_linux_ext_proc_show
  21. cifs_linux_ext_proc_open
  22. cifs_linux_ext_proc_write
  23. cifs_lookup_cache_proc_show
  24. cifs_lookup_cache_proc_open
  25. cifs_lookup_cache_proc_write
  26. traceSMB_proc_show
  27. traceSMB_proc_open
  28. traceSMB_proc_write
  29. cifs_multiuser_mount_proc_show
  30. cifs_multiuser_mount_proc_open
  31. cifs_multiuser_mount_proc_write
  32. cifs_security_flags_proc_show
  33. cifs_security_flags_proc_open
  34. cifs_security_flags_proc_write
  35. cifs_proc_init
  36. cifs_proc_clean

/*
 *   fs/cifs_debug.c
 *
 *   Copyright (C) International Business Machines  Corp., 2000,2005
 *
 *   Modified by Steve French (sfrench@us.ibm.com)
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program;  if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifsfs.h"

void
cifs_dump_mem(char *label, void *data, int length)
{
        int i, j;
        int *intptr = data;
        char *charptr = data;
        char buf[10], line[80];

        printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n",
                label, length, data);
        for (i = 0; i < length; i += 16) {
                line[0] = 0;
                for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
                        sprintf(buf, " %08x", intptr[i / 4 + j]);
                        strcat(line, buf);
                }
                buf[0] = ' ';
                buf[2] = 0;
                for (j = 0; (j < 16) && (i + j < length); j++) {
                        buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
                        strcat(line, buf);
                }
                printk(KERN_DEBUG "%s\n", line);
        }
}

#ifdef CONFIG_CIFS_DEBUG2
void cifs_dump_detail(struct smb_hdr *smb)
{
        cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
                  smb->Command, smb->Status.CifsError,
                  smb->Flags, smb->Flags2, smb->Mid, smb->Pid));
        cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb)));
}


void cifs_dump_mids(struct TCP_Server_Info *server)
{
        struct list_head *tmp;
        struct mid_q_entry *mid_entry;

        if (server == NULL)
                return;

        cERROR(1, ("Dump pending requests:"));
        spin_lock(&GlobalMid_Lock);
        list_for_each(tmp, &server->pending_mid_q) {
                mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
                cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
                        mid_entry->midState,
                        (int)mid_entry->command,
                        mid_entry->pid,
                        mid_entry->tsk,
                        mid_entry->mid));
#ifdef CONFIG_CIFS_STATS2
                cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
                        mid_entry->largeBuf,
                        mid_entry->resp_buf,
                        mid_entry->when_received,
                        jiffies));
#endif /* STATS2 */
                cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
                          mid_entry->multiEnd));
                if (mid_entry->resp_buf) {
                        cifs_dump_detail(mid_entry->resp_buf);
                        cifs_dump_mem("existing buf: ",
                                mid_entry->resp_buf, 62);
                }
        }
        spin_unlock(&GlobalMid_Lock);
}
#endif /* CONFIG_CIFS_DEBUG2 */

#ifdef CONFIG_PROC_FS
static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
{
        struct list_head *tmp;
        struct list_head *tmp1;
        struct mid_q_entry *mid_entry;
        struct cifsSesInfo *ses;
        struct cifsTconInfo *tcon;
        int i;

        seq_puts(m,
                    "Display Internal CIFS Data Structures for Debugging\n"
                    "---------------------------------------------------\n");
        seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
        seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
        seq_printf(m, "Servers:");

        i = 0;
        read_lock(&GlobalSMBSeslock);
        list_for_each(tmp, &GlobalSMBSessionList) {
                i++;
                ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
                if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
                   (ses->serverNOS == NULL)) {
                        seq_printf(m, "\nentry for %s not fully "
                                        "displayed\n\t", ses->serverName);
                } else {
                        seq_printf(m,
                                    "\n%d) Name: %s  Domain: %s Mounts: %d OS:"
                                    " %s  \n\tNOS: %s\tCapability: 0x%x\n\tSMB"
                                    " session status: %d\t",
                                i, ses->serverName, ses->serverDomain,
                                atomic_read(&ses->inUse),
                                ses->serverOS, ses->serverNOS,
                                ses->capabilities, ses->status);
                }
                if (ses->server) {
                        seq_printf(m, "TCP status: %d\n\tLocal Users To "
                                    "Server: %d SecMode: 0x%x Req On Wire: %d",
                                ses->server->tcpStatus,
                                atomic_read(&ses->server->socketUseCount),
                                ses->server->secMode,
                                atomic_read(&ses->server->inFlight));

#ifdef CONFIG_CIFS_STATS2
                        seq_printf(m, " In Send: %d In MaxReq Wait: %d",
                                atomic_read(&ses->server->inSend),
                                atomic_read(&ses->server->num_waiters));
#endif

                        seq_puts(m, "\nMIDs:\n");

                        spin_lock(&GlobalMid_Lock);
                        list_for_each(tmp1, &ses->server->pending_mid_q) {
                                mid_entry = list_entry(tmp1, struct
                                        mid_q_entry,
                                        qhead);
                                seq_printf(m, "State: %d com: %d pid:"
                                                " %d tsk: %p mid %d\n",
                                                mid_entry->midState,
                                                (int)mid_entry->command,
                                                mid_entry->pid,
                                                mid_entry->tsk,
                                                mid_entry->mid);
                        }
                        spin_unlock(&GlobalMid_Lock);
                }

        }
        read_unlock(&GlobalSMBSeslock);
        seq_putc(m, '\n');

        seq_puts(m, "Shares:");

        i = 0;
        read_lock(&GlobalSMBSeslock);
        list_for_each(tmp, &GlobalTreeConnectionList) {
                __u32 dev_type;
                i++;
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
                dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
                seq_printf(m, "\n%d) %s Uses: %d ", i,
                                 tcon->treeName, atomic_read(&tcon->useCount));
                if (tcon->nativeFileSystem) {
                        seq_printf(m, "Type: %s ",
                                         tcon->nativeFileSystem);
                }
                seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x"
                                 "\nPathComponentMax: %d Status: %d",
                            le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
                            le32_to_cpu(tcon->fsAttrInfo.Attributes),
                            le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
                            tcon->tidStatus);
                if (dev_type == FILE_DEVICE_DISK)
                        seq_puts(m, " type: DISK ");
                else if (dev_type == FILE_DEVICE_CD_ROM)
                        seq_puts(m, " type: CDROM ");
                else
                        seq_printf(m, " type: %d ", dev_type);

                if (tcon->tidStatus == CifsNeedReconnect)
                        seq_puts(m, "\tDISCONNECTED ");
        }
        read_unlock(&GlobalSMBSeslock);

        seq_putc(m, '\n');

        /* BB add code to dump additional info such as TCP session info now */
        return 0;
}

static int cifs_debug_data_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_debug_data_proc_show, NULL);
}

static const struct file_operations cifs_debug_data_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_debug_data_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
};

#ifdef CONFIG_CIFS_STATS
static ssize_t cifs_stats_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        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' || c == '0') {
                read_lock(&GlobalSMBSeslock);
#ifdef CONFIG_CIFS_STATS2
                atomic_set(&totBufAllocCount, 0);
                atomic_set(&totSmBufAllocCount, 0);
#endif /* CONFIG_CIFS_STATS2 */
                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 cifs_stats_proc_show(struct seq_file *m, void *v)
{
        int i;
        struct list_head *tmp;
        struct cifsTconInfo *tcon;

        seq_printf(m,
                        "Resources in use\nCIFS Session: %d\n",
                        sesInfoAllocCount.counter);
        seq_printf(m, "Share (unique mount targets): %d\n",
                        tconInfoAllocCount.counter);
        seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
                        bufAllocCount.counter,
                        cifs_min_rcv + tcpSesAllocCount.counter);
        seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
                        smBufAllocCount.counter, cifs_min_small);
#ifdef CONFIG_CIFS_STATS2
        seq_printf(m, "Total Large %d Small %d Allocations\n",
                                atomic_read(&totBufAllocCount),
                                atomic_read(&totSmBufAllocCount));
#endif /* CONFIG_CIFS_STATS2 */

        seq_printf(m, "Operations (MIDs): %d\n", midCount.counter);
        seq_printf(m,
                "\n%d session %d share reconnects\n",
                tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);

        seq_printf(m,
                "Total vfs operations: %d maximum at one time: %d\n",
                GlobalCurrentXid, GlobalMaxActiveXid);

        i = 0;
        read_lock(&GlobalSMBSeslock);
        list_for_each(tmp, &GlobalTreeConnectionList) {
                i++;
                tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
                seq_printf(m, "\n%d) %s", i, tcon->treeName);
                if (tcon->tidStatus == CifsNeedReconnect)
                        seq_puts(m, "\tDISCONNECTED ");
                seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
                        atomic_read(&tcon->num_smbs_sent),
                        atomic_read(&tcon->num_oplock_brks));
                seq_printf(m, "\nReads:  %d Bytes: %lld",
                        atomic_read(&tcon->num_reads),
                        (long long)(tcon->bytes_read));
                seq_printf(m, "\nWrites: %d Bytes: %lld",
                        atomic_read(&tcon->num_writes),
                        (long long)(tcon->bytes_written));
                seq_printf(m,
                        "\nLocks: %d HardLinks: %d Symlinks: %d",
                        atomic_read(&tcon->num_locks),
                        atomic_read(&tcon->num_hardlinks),
                        atomic_read(&tcon->num_symlinks));

                seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d",
                        atomic_read(&tcon->num_opens),
                        atomic_read(&tcon->num_closes),
                        atomic_read(&tcon->num_deletes));
                seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
                        atomic_read(&tcon->num_mkdirs),
                        atomic_read(&tcon->num_rmdirs));
                seq_printf(m, "\nRenames: %d T2 Renames %d",
                        atomic_read(&tcon->num_renames),
                        atomic_read(&tcon->num_t2renames));
                seq_printf(m, "\nFindFirst: %d FNext %d FClose %d",
                        atomic_read(&tcon->num_ffirst),
                        atomic_read(&tcon->num_fnext),
                        atomic_read(&tcon->num_fclose));
        }
        read_unlock(&GlobalSMBSeslock);

        seq_putc(m, '\n');
        return 0;
}

static int cifs_stats_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_stats_proc_show, NULL);
}

static const struct file_operations cifs_stats_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_stats_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_stats_proc_write,
};
#endif /* STATS */

static struct proc_dir_entry *proc_fs_cifs;
static const struct file_operations cifsFYI_proc_fops;
static const struct file_operations cifs_oplock_proc_fops;
static const struct file_operations cifs_lookup_cache_proc_fops;
static const struct file_operations traceSMB_proc_fops;
static const struct file_operations cifs_multiuser_mount_proc_fops;
static const struct file_operations cifs_security_flags_proc_fops;
static const struct file_operations cifs_experimental_proc_fops;
static const struct file_operations cifs_linux_ext_proc_fops;

void
cifs_proc_init(void)
{
        proc_fs_cifs = proc_mkdir("fs/cifs", NULL);
        if (proc_fs_cifs == NULL)
                return;

        proc_fs_cifs->owner = THIS_MODULE;
        proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops);

#ifdef CONFIG_CIFS_STATS
        proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops);
#endif /* STATS */
        proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops);
        proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops);
        proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops);
        proc_create("Experimental", 0, proc_fs_cifs,
                    &cifs_experimental_proc_fops);
        proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs,
                    &cifs_linux_ext_proc_fops);
        proc_create("MultiuserMount", 0, proc_fs_cifs,
                    &cifs_multiuser_mount_proc_fops);
        proc_create("SecurityFlags", 0, proc_fs_cifs,
                    &cifs_security_flags_proc_fops);
        proc_create("LookupCacheEnabled", 0, proc_fs_cifs,
                    &cifs_lookup_cache_proc_fops);
}

void
cifs_proc_clean(void)
{
        if (proc_fs_cifs == NULL)
                return;

        remove_proc_entry("DebugData", proc_fs_cifs);
        remove_proc_entry("cifsFYI", proc_fs_cifs);
        remove_proc_entry("traceSMB", proc_fs_cifs);
#ifdef CONFIG_CIFS_STATS
        remove_proc_entry("Stats", proc_fs_cifs);
#endif
        remove_proc_entry("MultiuserMount", proc_fs_cifs);
        remove_proc_entry("OplockEnabled", proc_fs_cifs);
        remove_proc_entry("SecurityFlags", proc_fs_cifs);
        remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
        remove_proc_entry("Experimental", proc_fs_cifs);
        remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
        remove_proc_entry("fs/cifs", NULL);
}

static int cifsFYI_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", cifsFYI);
        return 0;
}

static int cifsFYI_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifsFYI_proc_show, NULL);
}

static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
                size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                cifsFYI = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                cifsFYI = 1;
        else if ((c > '1') && (c <= '9'))
                cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */

        return count;
}

static const struct file_operations cifsFYI_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifsFYI_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifsFYI_proc_write,
};

static int cifs_oplock_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", oplockEnabled);
        return 0;
}

static int cifs_oplock_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_oplock_proc_show, NULL);
}

static ssize_t cifs_oplock_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                oplockEnabled = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                oplockEnabled = 1;

        return count;
}

static const struct file_operations cifs_oplock_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_oplock_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_oplock_proc_write,
};

static int cifs_experimental_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", experimEnabled);
        return 0;
}

static int cifs_experimental_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_experimental_proc_show, NULL);
}

static ssize_t cifs_experimental_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                experimEnabled = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                experimEnabled = 1;
        else if (c == '2')
                experimEnabled = 2;

        return count;
}

static const struct file_operations cifs_experimental_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_experimental_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_experimental_proc_write,
};

static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", linuxExtEnabled);
        return 0;
}

static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_linux_ext_proc_show, NULL);
}

static ssize_t cifs_linux_ext_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                linuxExtEnabled = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                linuxExtEnabled = 1;

        return count;
}

static const struct file_operations cifs_linux_ext_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_linux_ext_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_linux_ext_proc_write,
};

static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", lookupCacheEnabled);
        return 0;
}

static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_lookup_cache_proc_show, NULL);
}

static ssize_t cifs_lookup_cache_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                lookupCacheEnabled = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                lookupCacheEnabled = 1;

        return count;
}

static const struct file_operations cifs_lookup_cache_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_lookup_cache_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_lookup_cache_proc_write,
};

static int traceSMB_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", traceSMB);
        return 0;
}

static int traceSMB_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, traceSMB_proc_show, NULL);
}

static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
                size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                traceSMB = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                traceSMB = 1;

        return count;
}

static const struct file_operations traceSMB_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = traceSMB_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = traceSMB_proc_write,
};

static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%d\n", multiuser_mount);
        return 0;
}

static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh)
{
        return single_open(fh, cifs_multiuser_mount_proc_show, NULL);
}

static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        char c;
        int rc;

        rc = get_user(c, buffer);
        if (rc)
                return rc;
        if (c == '0' || c == 'n' || c == 'N')
                multiuser_mount = 0;
        else if (c == '1' || c == 'y' || c == 'Y')
                multiuser_mount = 1;

        return count;
}

static const struct file_operations cifs_multiuser_mount_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_multiuser_mount_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_multiuser_mount_proc_write,
};

static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m, "0x%x\n", extended_security);
        return 0;
}

static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, cifs_security_flags_proc_show, NULL);
}

static ssize_t cifs_security_flags_proc_write(struct file *file,
                const char __user *buffer, size_t count, loff_t *ppos)
{
        unsigned int flags;
        char flags_string[12];
        char c;

        if ((count < 1) || (count > 11))
                return -EINVAL;

        memset(flags_string, 0, 12);

        if (copy_from_user(flags_string, buffer, count))
                return -EFAULT;

        if (count < 3) {
                /* single char or single char followed by null */
                c = flags_string[0];
                if (c == '0' || c == 'n' || c == 'N') {
                        extended_security = CIFSSEC_DEF; /* default */
                        return count;
                } else if (c == '1' || c == 'y' || c == 'Y') {
                        extended_security = CIFSSEC_MAX;
                        return count;
                } else if (!isdigit(c)) {
                        cERROR(1, ("invalid flag %c", c));
                        return -EINVAL;
                }
        }
        /* else we have a number */

        flags = simple_strtoul(flags_string, NULL, 0);

        cFYI(1, ("sec flags 0x%x", flags));

        if (flags <= 0)  {
                cERROR(1, ("invalid security flags %s", flags_string));
                return -EINVAL;
        }

        if (flags & ~CIFSSEC_MASK) {
                cERROR(1, ("attempt to set unsupported security flags 0x%x",
                        flags & ~CIFSSEC_MASK));
                return -EINVAL;
        }
        /* flags look ok - update the global security flags for cifs module */
        extended_security = flags;
        if (extended_security & CIFSSEC_MUST_SIGN) {
                /* requiring signing implies signing is allowed */
                extended_security |= CIFSSEC_MAY_SIGN;
                cFYI(1, ("packet signing now required"));
        } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
                cFYI(1, ("packet signing disabled"));
        }
        /* BB should we turn on MAY flags for other MUST options? */
        return count;
}

static const struct file_operations cifs_security_flags_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = cifs_security_flags_proc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
        .write          = cifs_security_flags_proc_write,
};
#else
inline void cifs_proc_init(void)
{
}

inline void cifs_proc_clean(void)
{
}
#endif /* PROC_FS */

/* [<][>][^][v][top][bottom][index][help] */

[funini.com] -> [kei@sodan] -> Kernel Reading