diff mbox series

[5/5] samples/kernfs: Add inc file to allow changing counter increment

Message ID 20250121154719.43303-1-me@davidreaver.com (mailing list archive)
State New
Headers show
Series samples/kernfs: Add a pseudo-filesystem to demonstrate kernfs usage | expand

Commit Message

David Reaver Jan. 21, 2025, 3:47 p.m. UTC
A file called inc is automatically added to sample_kernfs directories.
Users can read and write unsigned integers to this file. The value stored
in inc determines how much counter values are incremented every time they
are read.

Signed-off-by: David Reaver <me@davidreaver.com>
---
 samples/kernfs/sample_kernfs.c | 42 +++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c
index e632b5f66924..3d1e7fb4ecc5 100644
--- a/samples/kernfs/sample_kernfs.c
+++ b/samples/kernfs/sample_kernfs.c
@@ -17,11 +17,13 @@ 
 /**
  * struct sample_kernfs_directory - Represents a directory in the pseudo-filesystem
  * @count: Holds the current count in the counter file.
+ * @inc: Amount to increment count by. Value of inc file.
  * @subdirs: Holds the list of this directory's subdirectories.
  * @siblings: Used to add this dir to parent's subdirs list.
  */
 struct sample_kernfs_directory {
 	atomic64_t count;
+	atomic64_t inc;
 	struct list_head subdirs;
 	struct list_head siblings;
 };
@@ -34,6 +36,7 @@  static struct sample_kernfs_directory *sample_kernfs_create_dir(void)
 	if (!dir)
 		return NULL;

+	atomic64_set(&dir->inc, 1);
 	INIT_LIST_HEAD(&dir->subdirs);
 	INIT_LIST_HEAD(&dir->siblings);

@@ -55,7 +58,8 @@  static int sample_kernfs_counter_seq_show(struct seq_file *sf, void *v)
 {
 	struct kernfs_open_file *of = sf->private;
 	struct sample_kernfs_directory *counter_dir = kernfs_of_to_dir(of);
-	u64 count = atomic64_inc_return(&counter_dir->count);
+	u64 inc = atomic64_read(&counter_dir->inc);
+	u64 count = atomic64_add_return(inc, &counter_dir->count);

 	seq_printf(sf, "%llu\n", count);

@@ -83,6 +87,38 @@  static struct kernfs_ops counter_kf_ops = {
 	.write		= sample_kernfs_counter_write,
 };

+static int sample_kernfs_inc_seq_show(struct seq_file *sf, void *v)
+{
+	struct kernfs_open_file *of = sf->private;
+	struct sample_kernfs_directory *counter_dir = kernfs_of_to_dir(of);
+	u64 inc = atomic64_read(&counter_dir->inc);
+
+	seq_printf(sf, "%llu\n", inc);
+
+	return 0;
+}
+
+static ssize_t sample_kernfs_inc_write(struct kernfs_open_file *of, char *buf,
+					   size_t nbytes, loff_t off)
+{
+	struct sample_kernfs_directory *counter_dir = kernfs_of_to_dir(of);
+	int ret;
+	u64 new_value;
+
+	ret = kstrtou64(strstrip(buf), 10, &new_value);
+	if (ret)
+		return ret;
+
+	atomic64_set(&counter_dir->inc, new_value);
+
+	return nbytes;
+}
+
+static struct kernfs_ops inc_kf_ops = {
+	.seq_show	= sample_kernfs_inc_seq_show,
+	.write		= sample_kernfs_inc_write,
+};
+
 static int sample_kernfs_add_file(struct kernfs_node *dir_kn, const char *name,
 				  struct kernfs_ops *ops)
 {
@@ -105,6 +141,10 @@  static int sample_kernfs_populate_dir(struct kernfs_node *dir_kn)
 	if (err)
 		return err;

+	err = sample_kernfs_add_file(dir_kn, "inc", &inc_kf_ops);
+	if (err)
+		return err;
+
 	return 0;
 }