diff mbox series

[1/2] cifs: create procfs for dns_interval setting

Message ID 20220608215444.1216-2-ematsumiya@suse.de (mailing list archive)
State New, archived
Headers show
Series Introduce dns_interval procfs setting | expand

Commit Message

Enzo Matsumiya June 8, 2022, 9:54 p.m. UTC
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(+)
diff mbox series

Patch

diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 1dd995efd5b8..96ff549a103e 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -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);
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index ee4ea2b60c0f..40ef322450a3 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -33,6 +33,8 @@  extern int cifsFYI;
 #endif
 #define ONCE 8
 
+extern unsigned int dns_interval;
+
 /*
  *	debug ON
  *	--------
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 325423180fd2..284645da8cd3 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -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;