@@ -695,6 +695,7 @@ PROC_FILE_DEFINE(smbd_receive_credit_max);
static struct proc_dir_entry *proc_fs_cifs;
static const struct proc_ops cifsFYI_proc_ops;
+static const struct proc_ops cifs_dns_interval_proc_ops;
static const struct proc_ops cifs_lookup_cache_proc_ops;
static const struct proc_ops traceSMB_proc_ops;
static const struct proc_ops cifs_security_flags_proc_ops;
@@ -716,6 +717,7 @@ cifs_proc_init(void)
proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_ops);
proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_ops);
+ proc_create("dns_interval", 0644, proc_fs_cifs, &cifs_dns_interval_proc_ops);
proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_ops);
proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
&cifs_linux_ext_proc_ops);
@@ -759,6 +761,7 @@ cifs_proc_clean(void)
remove_proc_entry("DebugData", proc_fs_cifs);
remove_proc_entry("open_files", proc_fs_cifs);
remove_proc_entry("cifsFYI", proc_fs_cifs);
+ remove_proc_entry("dns_interval", proc_fs_cifs);
remove_proc_entry("traceSMB", proc_fs_cifs);
remove_proc_entry("Stats", proc_fs_cifs);
remove_proc_entry("SecurityFlags", proc_fs_cifs);
@@ -821,6 +824,66 @@ static const struct proc_ops cifsFYI_proc_ops = {
.proc_write = cifsFYI_proc_write,
};
+static int cifs_dns_interval_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%u\n", dns_interval);
+ return 0;
+}
+
+static int cifs_dns_interval_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cifs_dns_interval_show, NULL);
+}
+
+static ssize_t cifs_dns_interval_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ int rc;
+ unsigned int interval;
+ char buf[12] = { 0 };
+ /* allow the minimum interval to be 10 (arbritrary) when debugging */
+ unsigned int min_interval = cifsFYI ? 10 : SMB_DNS_RESOLVE_INTERVAL_MIN;
+
+ if ((count < 1) || (count > 11))
+ return -EINVAL;
+
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+
+ if (count < 3) {
+ if (!isdigit(buf[0])) {
+ cifs_dbg(VFS, "Invalid value for dns_interval: %s\n",
+ buf);
+ return -EINVAL;
+ }
+ }
+
+ rc = kstrtouint(buf, 0, &interval);
+ if (rc) {
+ cifs_dbg(VFS, "Invalid value for dns_interval: %s\n",
+ buf);
+ return rc;
+ }
+
+ if (interval < min_interval) {
+ cifs_dbg(VFS, "minimum value for dns_interval is %u, default value is %u\n",
+ SMB_DNS_RESOLVE_INTERVAL_MIN,
+ SMB_DNS_RESOLVE_INTERVAL_DEFAULT);
+ return -EINVAL;
+ }
+
+ dns_interval = interval;
+ return count;
+}
+
+static const struct proc_ops cifs_dns_interval_proc_ops = {
+ .proc_open = cifs_dns_interval_open,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+ .proc_write = cifs_dns_interval_write,
+};
+
static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "%d\n", linuxExtEnabled);
@@ -33,6 +33,8 @@ extern int cifsFYI;
#endif
#define ONCE 8
+extern unsigned int dns_interval;
+
/*
* debug ON
* --------
@@ -66,6 +66,7 @@ bool enable_gcm_256 = true;
bool require_gcm_256; /* false by default */
bool enable_negotiate_signing; /* false by default */
unsigned int global_secflags = CIFSSEC_DEF;
+unsigned int dns_interval = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
/* unsigned int ntlmv2_support = 0; */
unsigned int sign_CIFS_PDUs = 1;
static const struct super_operations cifs_super_ops;
This patch introduces the /proc/fs/cifs/dns_interval setting, used to configure the interval that DNS resolutions must be done. Enforces the minimum value SMB_DNS_RESOLVE_INTERVAL_MIN (currently 120), but allows it to be lower (10, arbitrarily chosen) when debugging (i.e. cifsFYI > 0). Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de> --- fs/cifs/cifs_debug.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/cifs_debug.h | 2 ++ fs/cifs/cifsfs.c | 1 + 3 files changed, 66 insertions(+)