From patchwork Tue Jan 21 15:46:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Reaver X-Patchwork-Id: 13946428 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FB971E51D for ; Tue, 21 Jan 2025 15:46:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474388; cv=none; b=OOcIvsprMkhuuJDTzEMeLlJhDy2RiLfIBYBhuG5cIkJlTcVN/8OshbpgkBxvQ2Vk5Xq3F3E/5SpgNUCqChvkCGjSHdI3x7+oCFOyOVycWL9ZlxNonIVgbvfElmuQ3cyesAdxDqKpKGZsvBxINcWqCvxxgV1hqBczQSFKbstTmnI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474388; c=relaxed/simple; bh=mNcvn9K9+bu9KCWmscH/uBK62BhZNNzz6y+9wgMDxt0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cTUpB/7V5yyGJckjod6eDqIaRpk67Vdan72ZU84dNE2lCOESKdisSkh0VrpMoRjNtqIuAM84kRhLhz2X9yf/O56QxiTg2egf+jO50X8DkK2N0N61UFVeWg8xCdLscL2dymmKsweKTjf+Kk6BzYRcVmOK9MAPGKbej6UIbGpbuL4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com; spf=pass smtp.mailfrom=davidreaver.com; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b=dewXfSKn; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ZbzoI0vl; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b="dewXfSKn"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ZbzoI0vl" Received: from phl-compute-03.internal (phl-compute-03.phl.internal [10.202.2.43]) by mailfhigh.phl.internal (Postfix) with ESMTP id 116611140207; Tue, 21 Jan 2025 10:46:25 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-03.internal (MEProxy); Tue, 21 Jan 2025 10:46:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=davidreaver.com; h=cc:cc:content-transfer-encoding:content-type:content-type :date:date:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:subject:subject:to:to; s=fm1; t=1737474385; x=1737560785; bh=xRhQg7Z3M6ZAaAlZ9W4J+pXvUNzw4SL1 05Brt9UfWhc=; b=dewXfSKnBbDjEQCrMnta8hssbRTwPfiyRQ4bZYiRdzl8yghS DXBWW9briHewprZk+SnAVVcsjfHLlm4Za2ZpCUzNGaB71MwdtsaCyoIOKcG/iOjl PQdz+fOX9aDP/RLz9ipDQvtb2X9bX+rZPO0V5wa21Z6oL0kEy0Niiq40HaYYtUId q9OCWRY4H26W4+91VM+AS2Vkfj8+7kj/YLUtkw/Zr9cX3q3Bc85mPE+N6I6LPzQS OMY+KaOBzGCZn+zqEDVlc/5LeipyJk/1pNzxwwZKjCKr1p3m50oW/f+4ghkq0MsF KP5aRBRqqeocOJqMDTUXZdkH1RIXii9M7RuFWA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1737474385; x= 1737560785; bh=xRhQg7Z3M6ZAaAlZ9W4J+pXvUNzw4SL105Brt9UfWhc=; b=Z bzoI0vlytlpL9HZXrlSJmF7GQm3zg31w4QiT79RcAyNvPuTpSJvfEtA8EL+qHJGE vS7ozkjmVKybLuroJqdT8vcrjzboFmV01K+rs2FDBSoOd6gz38pAK5Ffb62VkVGx brRVJ5a0thwl4+DNtMNpD3FVj1nk+lKXdVgZOw9rTqpqEDDk2aBj3prKZcd8XXIJ a7WFCUV4U2AWOHzWZsKouFIVWILEmEdu7jupM9T4gErgEmopPpYFAIr/HkQ6AAFS Bo6LuM4B4OGvHb5DK/WZO5JrLokGv4hGEz2Ct0pOYbdEQoTWfHz1XP/wOzfw7yS8 eK9ci+Xyi+ZaYuRpwGK6g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejvddghedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdej necuhfhrohhmpeffrghvihguucftvggrvhgvrhcuoehmvgesuggrvhhiughrvggrvhgvrh drtghomheqnecuggftrfgrthhtvghrnhepieefiefhgfdvgfetheffteehheelfedukedv vdeuleeifffhfefftdehieefudejnecuffhomhgrihhnpehkvghrnhgvlhdrohhrghenuc evlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmvgesuggr vhhiughrvggrvhgvrhdrtghomhdpnhgspghrtghpthhtohepuddtpdhmohguvgepshhmth hpohhuthdprhgtphhtthhopehgrhgvghhkhheslhhinhhugihfohhunhgurghtihhonhdr ohhrghdprhgtphhtthhopehtjheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepmhgvse gurghvihgurhgvrghvvghrrdgtohhmpdhrtghpthhtoheprhhoshhtvgguthesghhoohgu mhhishdrohhrghdprhgtphhtthhopegsrhgruhhnvghrsehkvghrnhgvlhdrohhrghdprh gtphhtthhopehvihhrohesiigvnhhivhdrlhhinhhugidrohhrghdruhhkpdhrtghpthht oheptghorhgsvghtsehlfihnrdhnvghtpdhrtghpthhtohepjhgrmhgvshdrsghothhtoh hmlhgvhieshhgrnhhsvghnphgrrhhtnhgvrhhshhhiphdrtghomhdprhgtphhtthhopehk jhhlgiesthgvmhhplhgvohhfshhtuhhpihgurdgtohhm X-ME-Proxy: Feedback-ID: i67e946c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 21 Jan 2025 10:46:23 -0500 (EST) From: David Reaver To: Greg Kroah-Hartman , Tejun Heo Cc: David Reaver , Steven Rostedt , Christian Brauner , Al Viro , Jonathan Corbet , James Bottomley , Krister Johansen , linux-fsdevel@vger.kernel.org Subject: [PATCH 1/5] samples/kernfs: Adds boilerplate/README for sample_kernfs Date: Tue, 21 Jan 2025 07:46:12 -0800 Message-ID: <20250121154618.42760-1-me@davidreaver.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250121153646.37895-1-me@davidreaver.com> References: <20250121153646.37895-1-me@davidreaver.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Adds the necessary Kconfig/Makefile boilerplate to get sample_kernfs compiled into the kernel. Also adds a README.rst file to describe how the filesystem works from a user's perspective. Signed-off-by: David Reaver --- MAINTAINERS | 1 + samples/Kconfig | 6 ++++ samples/Makefile | 1 + samples/kernfs/Makefile | 3 ++ samples/kernfs/README.rst | 55 ++++++++++++++++++++++++++++++++++ samples/kernfs/sample_kernfs.c | 20 +++++++++++++ 6 files changed, 86 insertions(+) create mode 100644 samples/kernfs/Makefile create mode 100644 samples/kernfs/README.rst create mode 100644 samples/kernfs/sample_kernfs.c diff --git a/MAINTAINERS b/MAINTAINERS index 0fa7c5728f1e..5791aced4b93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12702,6 +12702,7 @@ S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git F: fs/kernfs/ F: include/linux/kernfs.h +F: samples/kernfs/ KEXEC M: Eric Biederman diff --git a/samples/Kconfig b/samples/Kconfig index b288d9991d27..968294ffb35d 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -291,6 +291,12 @@ config SAMPLE_CGROUP help Build samples that demonstrate the usage of the cgroup API. +config SAMPLE_KERNFS + bool "Build sample_kernfs pseudo-filesystem." + help + Build a sample pseudo-filesystem that demonstrates the use of the + kernfs API. The filesystem name is sample_kernfs. + source "samples/rust/Kconfig" endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index b85fa64390c5..e024e76e396d 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_SAMPLE_CONNECTOR) += connector/ obj-$(CONFIG_SAMPLE_FANOTIFY_ERROR) += fanotify/ subdir-$(CONFIG_SAMPLE_HIDRAW) += hidraw obj-$(CONFIG_SAMPLE_HW_BREAKPOINT) += hw_breakpoint/ +obj-$(CONFIG_SAMPLE_KERNFS) += kernfs/ obj-$(CONFIG_SAMPLE_KDB) += kdb/ obj-$(CONFIG_SAMPLE_KFIFO) += kfifo/ obj-$(CONFIG_SAMPLE_KOBJECT) += kobject/ diff --git a/samples/kernfs/Makefile b/samples/kernfs/Makefile new file mode 100644 index 000000000000..3bd2e4773b91 --- /dev/null +++ b/samples/kernfs/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_SAMPLE_KERNFS) += sample_kernfs.o diff --git a/samples/kernfs/README.rst b/samples/kernfs/README.rst new file mode 100644 index 000000000000..e0e747514df1 --- /dev/null +++ b/samples/kernfs/README.rst @@ -0,0 +1,55 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================================================== +Sample pseudo-filesystem built on top of ``kernfs`` +=================================================== + +This directory contains a kernel module that implements a pseudo-filesystem +built on top of ``kernfs`` and it demonstrates the basic of how to use ``kernfs``. + +Usage +===== + +Compile your kernel with ``CONFIG_SAMPLE_KERNFS=y`` and create a +``sample_kernfs`` mount with:: + + # mkdir /sample_kernfs + # mount -t sample_kernfs none /sample_kernfs + +Filesystem layout +================= + +The filesystem contains a tree of counters. Here is an example, where +``sample_kernfs`` is mounted at ``/sample_kernfs``:: + + /sample_kernfs + ├── counter + ├── inc + ├── sub1/ + │ ├── counter + │ └── inc + └── sub2/ + ├── counter + ├── inc + ├── sub3/ + │ ├── counter + │ └── inc + └── sub4/ + ├── counter + └── inc + +When a directory is created, it is automatically populated with two files: +``counter`` and ``inc``. ``counter`` reports the current count for that node, +and every time it is read it increments by the value in ``inc``. ``counter`` can +be reset to a given value by writing that value to the ``counter`` file:: + + $ cat counter + 1 + $ cat counter + 2 + $ echo 4 > counter + $ cat counter + 5 + $ echo 3 > inc + $ cat counter + 8 diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c new file mode 100644 index 000000000000..82d4b73a4534 --- /dev/null +++ b/samples/kernfs/sample_kernfs.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * A sample kernel module showing how to build a pseudo-filesystem on top of + * kernfs. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include + +static int __init sample_kernfs_init(void) +{ + pr_info("Loaded sample_kernfs module.\n"); + return 0; +} + +module_init(sample_kernfs_init) +MODULE_DESCRIPTION("Sample kernel module showing how to use kernfs"); +MODULE_LICENSE("GPL"); From patchwork Tue Jan 21 15:46:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Reaver X-Patchwork-Id: 13946429 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEA8415383C for ; Tue, 21 Jan 2025 15:46:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474412; cv=none; b=Txijwvbrb2iD4FtSvbkUVZUWKnlxtIsdzgS6xQuAzvUOlcJa2tbR2wVXOmQJEPQ4zwbK9IESwG2UL8eSRwtJM225efF7IDBj+teKXlBi0DcwHtzKodp1J2f9LKC6EW4jFS8oZTfcSVuIoYrjr+AvMh3uTbLlfd6IMd58wzr4Ks8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474412; c=relaxed/simple; bh=9Y6Jwh1Q6ztKytHccbJhZDFI1e1hh+CWeIK8rGnZcRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LrlNCI9hhW2J+XA4686GFUejVHWNbJ4MfCeXhWZ2c3xZbibv0URu4lOJTLHEvxAe+TSl/VTgCnfB7kgHsin6JgT+6hhiKyZiT6Opgyh9C5Hcx8IvquyEiWN5L6DPTH2hRPDHSr2CpDUcGIq5Iscv0wIQ11PRqOHrE3j/L/azMec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com; spf=pass smtp.mailfrom=davidreaver.com; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b=XzixGwz7; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=xOepJp35; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b="XzixGwz7"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="xOepJp35" Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfhigh.phl.internal (Postfix) with ESMTP id BCC2C11401A8; Tue, 21 Jan 2025 10:46:49 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-09.internal (MEProxy); Tue, 21 Jan 2025 10:46:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=davidreaver.com; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1737474409; x= 1737560809; bh=vHoCF68rFLj2RfdBRp0BprGKUNmf9JimnOKnExNcSys=; b=X zixGwz7gZjsRoU4jxrat6tFURw9sCYEQmIqQZts7pdlpcYjFz4CXarlgfk3QzpZY j8zxib1445eEyOVsuDPdTl7y7YZSdhAAQ6fsjSOHQVfWn9816Vb+/v7KoOdIlGAC FA5kiiS+r6p5sMvrjcVBKw0cg0IYcXfDXcao52lIoPR3/bPwtav882JIGU4eBQoI dVAhHm895FUvAJzF/V/k85/yAC9Z2hgOg//kzs6t/oFbvS809ML8/KhwDQnM8/L/ AzRMQLSFyDyeYap5pqs8ifQ8n5/DAFf3Wf/SX+SaIDnp2ceUiRLvOSAzBx8l4qvK xCTelVdp1gMSNg6UiedHQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1737474409; x=1737560809; bh=v HoCF68rFLj2RfdBRp0BprGKUNmf9JimnOKnExNcSys=; b=xOepJp35a31uiY2oe rnWTKcWx7fI83DEsNFKZzooNd+8Y1APTWDxCR/ZYwE2vT4Q7+NeSxZtxm+VZ4qIQ MpEAO9OzRFUoqV52kPxnySl17AxYHYMqcqp4xiUlmPk4iZQAKousXs8ejXU+FzNp Vr9jyoDgS7kmcmADHmZYwBcTqcOklFkmbi9FAkpYe6RvStC+6QwJhEvQippaIROY o4GRXZiPJMJhB3EnEZyVvlx6pYjCFTc+FduTfaYZ2N0sJHK85DSaro4U8jghGCti HO0VrK/os0oANRKIeiTXrfwNXkzuWDGfzkFo+4Qp4ys2GPrg342ks6TRsTuYEPRh onPhw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejvddgheduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttden ucfhrhhomhepffgrvhhiugcutfgvrghvvghruceomhgvsegurghvihgurhgvrghvvghrrd gtohhmqeenucggtffrrghtthgvrhhnpeduveetffevuedutdektdevtdetuedtfedvgefh hfejieevgedvtedvjeetjeelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh epmhgrihhlfhhrohhmpehmvgesuggrvhhiughrvggrvhgvrhdrtghomhdpnhgspghrtghp thhtohepuddtpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehgrhgvghhkhheslh hinhhugihfohhunhgurghtihhonhdrohhrghdprhgtphhtthhopehtjheskhgvrhhnvghl rdhorhhgpdhrtghpthhtohepmhgvsegurghvihgurhgvrghvvghrrdgtohhmpdhrtghpth htoheprhhoshhtvgguthesghhoohgumhhishdrohhrghdprhgtphhtthhopegsrhgruhhn vghrsehkvghrnhgvlhdrohhrghdprhgtphhtthhopehvihhrohesiigvnhhivhdrlhhinh hugidrohhrghdruhhkpdhrtghpthhtoheptghorhgsvghtsehlfihnrdhnvghtpdhrtghp thhtohepjhgrmhgvshdrsghothhtohhmlhgvhieshhgrnhhsvghnphgrrhhtnhgvrhhshh hiphdrtghomhdprhgtphhtthhopehkjhhlgiesthgvmhhplhgvohhfshhtuhhpihgurdgt ohhm X-ME-Proxy: Feedback-ID: i67e946c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 21 Jan 2025 10:46:47 -0500 (EST) From: David Reaver To: Greg Kroah-Hartman , Tejun Heo Cc: David Reaver , Steven Rostedt , Christian Brauner , Al Viro , Jonathan Corbet , James Bottomley , Krister Johansen , linux-fsdevel@vger.kernel.org Subject: [PATCH 2/5] samples/kernfs: Make filesystem mountable Date: Tue, 21 Jan 2025 07:46:40 -0800 Message-ID: <20250121154641.42975-1-me@davidreaver.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250121153646.37895-1-me@davidreaver.com> References: <20250121153646.37895-1-me@davidreaver.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implements the bare minimum functionality to safely mount and unmount the sample_kernfs filesystem. Signed-off-by: David Reaver --- samples/kernfs/sample_kernfs.c | 69 +++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c index 82d4b73a4534..3ea8411a72ae 100644 --- a/samples/kernfs/sample_kernfs.c +++ b/samples/kernfs/sample_kernfs.c @@ -6,12 +6,79 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ +#include +#include +#include #include #include +#define SAMPLE_KERNFS_MAGIC 0x8d000ff0 + +static void sample_kernfs_fs_context_free(struct fs_context *fc) +{ + struct kernfs_fs_context *kfc = fc->fs_private; + + kernfs_free_fs_context(fc); + kfree(kfc); +} + +static const struct fs_context_operations sample_kernfs_fs_context_ops = { + .get_tree = kernfs_get_tree, + .free = sample_kernfs_fs_context_free, +}; + +static int sample_kernfs_init_fs_context(struct fs_context *fc) +{ + struct kernfs_fs_context *kfc; + struct kernfs_root *root; + int err; + + kfc = kzalloc(sizeof(struct kernfs_fs_context), GFP_KERNEL); + if (!kfc) + return -ENOMEM; + + root = kernfs_create_root(NULL, 0, NULL); + if (IS_ERR(root)) { + err = PTR_ERR(root); + goto err_free_kfc; + } + + kfc->root = root; + kfc->magic = SAMPLE_KERNFS_MAGIC; + fc->fs_private = kfc; + fc->ops = &sample_kernfs_fs_context_ops; + fc->global = true; + + return 0; + +err_free_kfc: + kfree(kfc); + return err; +} + +static void sample_kernfs_kill_sb(struct super_block *sb) +{ + struct kernfs_root *root = kernfs_root_from_sb(sb); + + kernfs_kill_sb(sb); + kernfs_destroy_root(root); +} + +static struct file_system_type sample_kernfs_fs_type = { + .name = "sample_kernfs", + .init_fs_context = sample_kernfs_init_fs_context, + .kill_sb = sample_kernfs_kill_sb, + .fs_flags = FS_USERNS_MOUNT, +}; + static int __init sample_kernfs_init(void) { - pr_info("Loaded sample_kernfs module.\n"); + int err; + + err = register_filesystem(&sample_kernfs_fs_type); + if (err) + return err; + return 0; } From patchwork Tue Jan 21 15:46:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Reaver X-Patchwork-Id: 13946430 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85C591E51D for ; Tue, 21 Jan 2025 15:47:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474425; cv=none; b=bDbKy2LhRjG758+0B7Adm8dOXB8iT6timnqDENSNTohTmjwpzqX5SyYByOqE2VLHwTHLDIPOLyRevK4viEwDevLDGKE+GuuoV6N95zhKE1M4uEGOgJyunbOzNAcy3KKiY75wftoAqOBIuPIfVBnXjaqGr65ACni5jWUzMhv8saA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474425; c=relaxed/simple; bh=Tbw7QXRqo4mt07TRq9auXc5khpNtsubsMBtRuEVJpRM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gXYbCkvKwt+uMVuRP1HwfLA4DfjumT2GLl9cr2OynMMvdc7QSm1SX1jVInf526StFimddlFYkBHx64K34I2Of3ietzZp3hfWNf65IjdLsR8VjYguQi31q6ijOp/Ea3hcsmQz/AWOD3EhuFrkhMGUy57JJmH1Fw2dQzXzgHLqveI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com; spf=pass smtp.mailfrom=davidreaver.com; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b=bxEk73uW; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=B21g0p4r; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b="bxEk73uW"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="B21g0p4r" Received: from phl-compute-08.internal (phl-compute-08.phl.internal [10.202.2.48]) by mailfhigh.phl.internal (Postfix) with ESMTP id 9632B11401A8; Tue, 21 Jan 2025 10:47:02 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-08.internal (MEProxy); Tue, 21 Jan 2025 10:47:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=davidreaver.com; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1737474422; x= 1737560822; bh=W5C4F9PM/PfNqSW4bOY/QOCtG2nxDvTduzMolvI7/po=; b=b xEk73uWM4WQlWvRRXiSG4EeepgqCM6qDaeZnFZP0CxrH7/mxR69Z3OSe1PpC4OVG FmhP+kaALUt33Of4+nsFHtlwVpi7JdOHMkCubSR8MHX7rEMjSQLKrIMZHYfUdBbS lQRaJhhUs+DV/f8xF8aoEKAXP53VE2P4ZMswb9F7yWA48gzXIPBzXFjjjBcp5jP1 0WxDhhYrIWLVF/PPWxXx/ojEbhwMOK8auJZsbU5U1ubuovH4JhieQptpw8c/+wQk u0RteUpfA0Fr9WJ2+4jFBIaHbBeaHkH/tacRvDXGsePUjkc6yIrJtTVEa7Rdk2pq O2DUQmmwjdtVdNZ6hSMMw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1737474422; x=1737560822; bh=W 5C4F9PM/PfNqSW4bOY/QOCtG2nxDvTduzMolvI7/po=; b=B21g0p4r7myARh0ui 1Prhostia08QWqFlXaYW+zVHPxWTpCYf3pdyLe/ywaBfVRc/vf4F3sGc0Wce5Zym obJZZQjuDgZHju7GpPBXffJjuMJFW4WtSlx+P6XrLdqcko3goAd+y8EiM9jRgVJF eWQf/LkqzL4sz/gkC6h0JD1BjSCoIr7RHJ/WzU5y7l/MDNPOND8hd6/4emBwtQej bBNt32PZS6MZC8AWLlU6N7Yy1w27xThSlIbaXZ4zcvYCKF/yVKoVOiZjQRVq7ghh bInPDoBsJkxERT1qiAHEEdqszfYDUOcOhOdqx7ax7HejhxWvRRYAwoG9ZdsDgVow joWKQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejvddghedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttden ucfhrhhomhepffgrvhhiugcutfgvrghvvghruceomhgvsegurghvihgurhgvrghvvghrrd gtohhmqeenucggtffrrghtthgvrhhnpeduveetffevuedutdektdevtdetuedtfedvgefh hfejieevgedvtedvjeetjeelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh epmhgrihhlfhhrohhmpehmvgesuggrvhhiughrvggrvhgvrhdrtghomhdpnhgspghrtghp thhtohepuddtpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehgrhgvghhkhheslh hinhhugihfohhunhgurghtihhonhdrohhrghdprhgtphhtthhopehtjheskhgvrhhnvghl rdhorhhgpdhrtghpthhtohepmhgvsegurghvihgurhgvrghvvghrrdgtohhmpdhrtghpth htoheprhhoshhtvgguthesghhoohgumhhishdrohhrghdprhgtphhtthhopegsrhgruhhn vghrsehkvghrnhgvlhdrohhrghdprhgtphhtthhopehvihhrohesiigvnhhivhdrlhhinh hugidrohhrghdruhhkpdhrtghpthhtoheptghorhgsvghtsehlfihnrdhnvghtpdhrtghp thhtohepjhgrmhgvshdrsghothhtohhmlhgvhieshhgrnhhsvghnphgrrhhtnhgvrhhshh hiphdrtghomhdprhgtphhtthhopehkjhhlgiesthgvmhhplhgvohhfshhtuhhpihgurdgt ohhm X-ME-Proxy: Feedback-ID: i67e946c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 21 Jan 2025 10:47:00 -0500 (EST) From: David Reaver To: Greg Kroah-Hartman , Tejun Heo Cc: David Reaver , Steven Rostedt , Christian Brauner , Al Viro , Jonathan Corbet , James Bottomley , Krister Johansen , linux-fsdevel@vger.kernel.org Subject: [PATCH 3/5] samples/kernfs: Add counter file to each directory Date: Tue, 21 Jan 2025 07:46:57 -0800 Message-ID: <20250121154659.43079-1-me@davidreaver.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250121153646.37895-1-me@davidreaver.com> References: <20250121153646.37895-1-me@davidreaver.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The counter file is automatically added to all sample_kernfs directories (including the root directory). This demonstrates how to tie an internal datastructure -- sample_kernfs_directory in this case -- to kernfs nodes via kernfs_node->priv. Also demonstrates how to read and write simple integer values to/from kernfs files. Signed-off-by: David Reaver --- samples/kernfs/sample_kernfs.c | 110 ++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c index 3ea8411a72ae..b6d44fc3b935 100644 --- a/samples/kernfs/sample_kernfs.c +++ b/samples/kernfs/sample_kernfs.c @@ -14,6 +14,93 @@ #define SAMPLE_KERNFS_MAGIC 0x8d000ff0 +/** + * struct sample_kernfs_directory - Represents a directory in the pseudo-filesystem + * @count: Holds the current count in the counter file. + */ +struct sample_kernfs_directory { + atomic64_t count; +}; + +static struct sample_kernfs_directory *sample_kernfs_create_dir(void) +{ + struct sample_kernfs_directory *dir; + + dir = kzalloc(sizeof(struct sample_kernfs_directory), GFP_KERNEL); + if (!dir) + return NULL; + + return dir; +} + +static struct sample_kernfs_directory *kernfs_of_to_dir(struct kernfs_open_file *of) +{ + struct kernfs_node *dir_kn = kernfs_get_parent(of->kn); + struct sample_kernfs_directory *dir = dir_kn->priv; + + /* kernfs_get_parent adds a reference; drop it with kernfs_put */ + kernfs_put(dir_kn); + + return dir; +} + +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); + + seq_printf(sf, "%llu\n", count); + + return 0; +} + +static ssize_t sample_kernfs_counter_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->count, new_value); + + return nbytes; +} + +static struct kernfs_ops counter_kf_ops = { + .seq_show = sample_kernfs_counter_seq_show, + .write = sample_kernfs_counter_write, +}; + +static int sample_kernfs_add_file(struct kernfs_node *dir_kn, const char *name, + struct kernfs_ops *ops) +{ + struct kernfs_node *kn; + + kn = __kernfs_create_file(dir_kn, name, 0666, current_fsuid(), + current_fsgid(), 0, ops, NULL, NULL, NULL); + + if (IS_ERR(kn)) + return PTR_ERR(kn); + + return 0; +} + +static int sample_kernfs_populate_dir(struct kernfs_node *dir_kn) +{ + int err; + + err = sample_kernfs_add_file(dir_kn, "counter", &counter_kf_ops); + if (err) + return err; + + return 0; +} + static void sample_kernfs_fs_context_free(struct fs_context *fc) { struct kernfs_fs_context *kfc = fc->fs_private; @@ -30,6 +117,7 @@ static const struct fs_context_operations sample_kernfs_fs_context_ops = { static int sample_kernfs_init_fs_context(struct fs_context *fc) { struct kernfs_fs_context *kfc; + struct sample_kernfs_directory *root_dir; struct kernfs_root *root; int err; @@ -37,10 +125,17 @@ static int sample_kernfs_init_fs_context(struct fs_context *fc) if (!kfc) return -ENOMEM; - root = kernfs_create_root(NULL, 0, NULL); + root_dir = sample_kernfs_create_dir(); + if (!root_dir) { + err = -ENOMEM; + goto err_free_kfc; + } + + /* dir gets stored in root->priv so we can access it later. */ + root = kernfs_create_root(NULL, 0, root_dir); if (IS_ERR(root)) { err = PTR_ERR(root); - goto err_free_kfc; + goto err_free_dir; } kfc->root = root; @@ -49,8 +144,16 @@ static int sample_kernfs_init_fs_context(struct fs_context *fc) fc->ops = &sample_kernfs_fs_context_ops; fc->global = true; + err = sample_kernfs_populate_dir(kernfs_root_to_node(root)); + if (err) + goto err_free_root; + return 0; +err_free_root: + kernfs_destroy_root(root); +err_free_dir: + kfree(root_dir); err_free_kfc: kfree(kfc); return err; @@ -59,9 +162,12 @@ static int sample_kernfs_init_fs_context(struct fs_context *fc) static void sample_kernfs_kill_sb(struct super_block *sb) { struct kernfs_root *root = kernfs_root_from_sb(sb); + struct kernfs_node *root_kn = kernfs_root_to_node(root); + struct sample_kernfs_directory *root_dir = root_kn->priv; kernfs_kill_sb(sb); kernfs_destroy_root(root); + kfree(root_dir); } static struct file_system_type sample_kernfs_fs_type = { From patchwork Tue Jan 21 15:47:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Reaver X-Patchwork-Id: 13946431 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF9C31E51D for ; Tue, 21 Jan 2025 15:47:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474435; cv=none; b=niyt0YWg1au/7gEjcMg/cKz1fiAtUj17NRwyX8upDPfggbi+oVnTSCuOUTbgkCGA5uZDPO01b0Odij8GOWV4vMy48vE5EV2axAdKyJSn5aHRolrlNsXbojWZZ6JnzJFsv3GWoAMBPEYtgh3q0v8fPZ8/DT9EXJBH2T5zzYzFJT0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474435; c=relaxed/simple; bh=GJgRTwJNMrvtt23OSJL7fsWrRantcnQpj5/kZp8XSX0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ad3OjJ+43nzRMrgnoWf61ETOTtfxwsAKRyEmuLqi+tslLcC5rWNcnBdIzOo3HYMXV+ciHrFshaln2o6l/gpuQYoeltBiQ3IcUBPtIeZEFqZaKtFNwqwsi+6xDNgdc1vg39cu34IEyt+AXEaeW5K2bJPAyvcv6xJ5+5POPp9J3gM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com; spf=pass smtp.mailfrom=davidreaver.com; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b=UdWTYFgM; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=v8z82WJz; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b="UdWTYFgM"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="v8z82WJz" Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfhigh.phl.internal (Postfix) with ESMTP id BCFE011401A8; Tue, 21 Jan 2025 10:47:12 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-09.internal (MEProxy); Tue, 21 Jan 2025 10:47:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=davidreaver.com; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1737474432; x= 1737560832; bh=+dpuSj/YgA/FHya1kHurTlC4CWRVvZf6PYZabCw2m74=; b=U dWTYFgMUUUG/nl5kxDOaAIMm76WXNGfD86hJ+Wqq5t9dUgLM78eb3SvFYKKgM2OI YcyzbzpiZLI9r7fIdLqjpme5A1p8GoHh9e0YW4DFQK0CIR/4UPbL/8s74+mMrm9k 49vwqB5C9zI7/3paXxvOixrnX1VlZrIPeS3DTxDDtS1of87rTjnMk0jXxCfQYL3m r1nMeZ6RHTY3fVOxsYN9wqX+e48lvtno/JLe0Plxq3hH6ci2qojKx3y15Zpe5+HN SVrmAQ+HBQ1Ncid+BCjW/20TbyvoQXRnK4VTj+EuAriAombEfoovVj6GTkK8x0OX WP9pWKzsnrFEq4PX7aDJA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1737474432; x=1737560832; bh=+ dpuSj/YgA/FHya1kHurTlC4CWRVvZf6PYZabCw2m74=; b=v8z82WJzH7mOiVfu5 eP7rBBwcYUwS9Nj0pbl6ZFnOqbRqzvSH6L1+STiEgYIMU1LgenD7nZT6H+pIN3ix mhuuz4GG1RVfIxBT7Vm2OY4ZqAKN+5Enrqvl+Pj3ouyP3CdGdtu+TgtnaE2Uxogl MdlMs21Q3cu3mMXzUuiAN5vumca8W3xb+L6Bzo93lCOe1l4JQiQDejs5Av+Kahpo yJj4tqL2tcEPcBNtMjavQT9BTE6a7d4SedF5MKz0deQVOl6TjRQBo+DSStP5ZJvV HbV/gkXZt2nWj1MNnahZuy0LDnN5X+854Nl/axF//XKTEY8do0XfYd+hHs/kNK9G r4qtw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejvddgheduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttden ucfhrhhomhepffgrvhhiugcutfgvrghvvghruceomhgvsegurghvihgurhgvrghvvghrrd gtohhmqeenucggtffrrghtthgvrhhnpeduveetffevuedutdektdevtdetuedtfedvgefh hfejieevgedvtedvjeetjeelieenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmh epmhgrihhlfhhrohhmpehmvgesuggrvhhiughrvggrvhgvrhdrtghomhdpnhgspghrtghp thhtohepuddtpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehgrhgvghhkhheslh hinhhugihfohhunhgurghtihhonhdrohhrghdprhgtphhtthhopehtjheskhgvrhhnvghl rdhorhhgpdhrtghpthhtohepmhgvsegurghvihgurhgvrghvvghrrdgtohhmpdhrtghpth htoheprhhoshhtvgguthesghhoohgumhhishdrohhrghdprhgtphhtthhopegsrhgruhhn vghrsehkvghrnhgvlhdrohhrghdprhgtphhtthhopehvihhrohesiigvnhhivhdrlhhinh hugidrohhrghdruhhkpdhrtghpthhtoheptghorhgsvghtsehlfihnrdhnvghtpdhrtghp thhtohepjhgrmhgvshdrsghothhtohhmlhgvhieshhgrnhhsvghnphgrrhhtnhgvrhhshh hiphdrtghomhdprhgtphhtthhopehkjhhlgiesthgvmhhplhgvohhfshhtuhhpihgurdgt ohhm X-ME-Proxy: Feedback-ID: i67e946c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 21 Jan 2025 10:47:11 -0500 (EST) From: David Reaver To: Greg Kroah-Hartman , Tejun Heo Cc: David Reaver , Steven Rostedt , Christian Brauner , Al Viro , Jonathan Corbet , James Bottomley , Krister Johansen , linux-fsdevel@vger.kernel.org Subject: [PATCH 4/5] samples/kernfs: Allow creating and removing directories Date: Tue, 21 Jan 2025 07:47:06 -0800 Message-ID: <20250121154707.43185-1-me@davidreaver.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250121153646.37895-1-me@davidreaver.com> References: <20250121153646.37895-1-me@davidreaver.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Users can mkdir and rmdir sample_kernfs directories, similar to how cgroups are added and removed in the cgroup pseudo-filesystem. New directories automatically get a counter file. kernfs doesn't expose functions to traverse child nodes. We demonstrate how to keep track of child nodes ourselves in sample_kernfs_directory. Removing a directory is surprisingly tricky and can deadlock if you use kernfs_remove() instead of kernfs_remove_self(), so a comment explains the motivation for using kernfs_remove_self(). I also added a comment explaining the lack of locking when manipulating the subdirs/children lists. Signed-off-by: David Reaver --- samples/kernfs/sample_kernfs.c | 94 ++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c index b6d44fc3b935..e632b5f66924 100644 --- a/samples/kernfs/sample_kernfs.c +++ b/samples/kernfs/sample_kernfs.c @@ -17,9 +17,13 @@ /** * struct sample_kernfs_directory - Represents a directory in the pseudo-filesystem * @count: Holds the current count in the counter 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; + struct list_head subdirs; + struct list_head siblings; }; static struct sample_kernfs_directory *sample_kernfs_create_dir(void) @@ -30,6 +34,9 @@ static struct sample_kernfs_directory *sample_kernfs_create_dir(void) if (!dir) return NULL; + INIT_LIST_HEAD(&dir->subdirs); + INIT_LIST_HEAD(&dir->siblings); + return dir; } @@ -101,6 +108,87 @@ static int sample_kernfs_populate_dir(struct kernfs_node *dir_kn) return 0; } +static void sample_kernfs_remove_subtree(struct sample_kernfs_directory *dir) +{ + struct sample_kernfs_directory *child, *tmp; + + /* + * Recursively remove children. This approach is acceptable for this + * sample since we expect the tree depth to remain small and manageable. + * For real-world filesystems, an iterative approach should be used to + * avoid stack overflows. + * + * Also, we could be more careful with locking our lists, but kernfs + * holds a tree-wide lock before calling our rmdir, so we should be + * safe. + */ + list_for_each_entry_safe(child, tmp, &dir->subdirs, siblings) { + sample_kernfs_remove_subtree(child); + } + + /* Remove this directory from its parent's subdirs list */ + list_del(&dir->siblings); + + kfree(dir); +} + +static int sample_kernfs_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode) +{ + struct kernfs_node *dir_kn; + struct sample_kernfs_directory *dir, *parent_dir; + int ret; + + dir = sample_kernfs_create_dir(); + if (!dir) + return -ENOMEM; + + /* dir gets stored in dir_kn->priv so we can access it later. */ + dir_kn = kernfs_create_dir_ns(parent_kn, name, mode, current_fsuid(), + current_fsgid(), dir, NULL); + + if (IS_ERR(dir_kn)) { + ret = PTR_ERR(dir_kn); + goto err_free_dir; + } + + ret = sample_kernfs_populate_dir(dir_kn); + if (ret) + goto err_free_dir_kn; + + /* Add directory to parent->subdirs */ + parent_dir = parent_kn->priv; + list_add(&dir->siblings, &parent_dir->subdirs); + + return 0; + +err_free_dir_kn: + kernfs_remove(dir_kn); +err_free_dir: + sample_kernfs_remove_subtree(dir); + return ret; +} + +static int sample_kernfs_rmdir(struct kernfs_node *kn) +{ + struct sample_kernfs_directory *dir = kn->priv; + + /* + * kernfs_remove_self avoids a deadlock by breaking active protection; + * see kernfs_break_active_protection(). This is required since + * kernfs_iop_rmdir() holds a tree-wide lock. + */ + kernfs_remove_self(kn); + + sample_kernfs_remove_subtree(dir); + + return 0; +} + +static struct kernfs_syscall_ops sample_kernfs_kf_syscall_ops = { + .mkdir = sample_kernfs_mkdir, + .rmdir = sample_kernfs_rmdir, +}; + static void sample_kernfs_fs_context_free(struct fs_context *fc) { struct kernfs_fs_context *kfc = fc->fs_private; @@ -132,7 +220,7 @@ static int sample_kernfs_init_fs_context(struct fs_context *fc) } /* dir gets stored in root->priv so we can access it later. */ - root = kernfs_create_root(NULL, 0, root_dir); + root = kernfs_create_root(&sample_kernfs_kf_syscall_ops, 0, root_dir); if (IS_ERR(root)) { err = PTR_ERR(root); goto err_free_dir; @@ -153,7 +241,7 @@ static int sample_kernfs_init_fs_context(struct fs_context *fc) err_free_root: kernfs_destroy_root(root); err_free_dir: - kfree(root_dir); + sample_kernfs_remove_subtree(root_dir); err_free_kfc: kfree(kfc); return err; @@ -167,7 +255,7 @@ static void sample_kernfs_kill_sb(struct super_block *sb) kernfs_kill_sb(sb); kernfs_destroy_root(root); - kfree(root_dir); + sample_kernfs_remove_subtree(root_dir); } static struct file_system_type sample_kernfs_fs_type = { From patchwork Tue Jan 21 15:47:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Reaver X-Patchwork-Id: 13946432 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E9B61E51D for ; Tue, 21 Jan 2025 15:47:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474445; cv=none; b=oEtQydDbL2tgfX4R9ajM6ed5hnNoLKeLJL1EFdzRLHw8slmm14LkNi5J57mxYUWOrKWdJYfnH5y1SUIPlA4Br2M280We9tcXyluLTjkSihj+QtD2tDgB4aDJRQHwBK7U5MMJ7TfBp4KskgdCEZ0q49/Dfk0z4zYV1PrdYG5qbrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737474445; c=relaxed/simple; bh=6EloJYI9kgbDyE7k3p0lFEr8X4AAjesJgfnUDnigGO8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tNSgjOr94UePpSVeQE/qG2uisPoIytB1Sv7wBO34dME1FrATZ2SzbOTFMnhGUYKhMwoyFlqoFvKZBRNIqxidpYGQ8CPVLoujQVKxmnE6nV7C7pvIAZNrtlliPN2Q/CU6lxk9kAuJ4GTVlAK4ompFjJ0dpZd9zvLgvQNZw9ZtpfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com; spf=pass smtp.mailfrom=davidreaver.com; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b=om2NMjXf; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=V/OwZSjJ; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=davidreaver.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=davidreaver.com header.i=@davidreaver.com header.b="om2NMjXf"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="V/OwZSjJ" Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfhigh.phl.internal (Postfix) with ESMTP id 30E011140207; Tue, 21 Jan 2025 10:47:23 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-09.internal (MEProxy); Tue, 21 Jan 2025 10:47:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=davidreaver.com; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1737474443; x= 1737560843; bh=z421Buuoe3xBjBaJiL2rQxq6qPXzp06EqCnslaWE9bY=; b=o m2NMjXfoXpESKg8TBEKGD+I58bE82T2DnkAjlpBzvsxwblctcaqlSX6nBcXkYbmr jpBEPnsKbEYLLXJdIRbKSkGB1t92URuMi6jyF6lebjx+5QdQZeSo7R6I6t8xyViQ SttwddpZpHNrNUZrHzyMYLBrbYG9QAHPK1awsI6Gm4uZb+UPm4ForuANX7BTqsed 9hO2nde4DkDf6H1Yh9Xc4tgUa+2/0W77/u6iGCHUhoEeVaGlqHR3B2HjD9yWDnzY VVimjHSuJg0dtaEEIh6HQ6uDAtNMME0pFN8DK2xaFwnszD1heCEDuMHyYWu61XtL mg0j/q8dfrfz+STgU5IBQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1737474443; x=1737560843; bh=z 421Buuoe3xBjBaJiL2rQxq6qPXzp06EqCnslaWE9bY=; b=V/OwZSjJLXcsy8LF4 YYDJC7u+WSJdDoWgaPa4Q6Y5dBPf/xmPewnEiNYgy0WO5r0cp2WzNMfyMxwTHRAn 22DoB1KEtu6Bg2uYIgzOV2EOi/GWF9l+92jJ2dOdSHVKYu5jOkHWLlyhmrGbsnCz LS1gauXmkGzrH0sV10/vPQX2nhQTb+hC1Bm0VnQmeIiVTOoFI0PLjMUp7eZNT+UT HaFiCmoI9GEGqNhnYFZa62JW/G6YuMyEXA55MgrKGxZ2qT8xrmfRm4/2aJ+6BXub XhSnx+Ocgivby0DUo4C4i9VxPGJfvp3g8E/LTLai1slw3nGjpIfHd/oQJjh4dc2C Ch8fw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejvddgheduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttden ucfhrhhomhepffgrvhhiugcutfgvrghvvghruceomhgvsegurghvihgurhgvrghvvghrrd gtohhmqeenucggtffrrghtthgvrhhnpeduveetffevuedutdektdevtdetuedtfedvgefh hfejieevgedvtedvjeetjeelieenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmh epmhgrihhlfhhrohhmpehmvgesuggrvhhiughrvggrvhgvrhdrtghomhdpnhgspghrtghp thhtohepuddtpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehgrhgvghhkhheslh hinhhugihfohhunhgurghtihhonhdrohhrghdprhgtphhtthhopehtjheskhgvrhhnvghl rdhorhhgpdhrtghpthhtohepmhgvsegurghvihgurhgvrghvvghrrdgtohhmpdhrtghpth htoheprhhoshhtvgguthesghhoohgumhhishdrohhrghdprhgtphhtthhopegsrhgruhhn vghrsehkvghrnhgvlhdrohhrghdprhgtphhtthhopehvihhrohesiigvnhhivhdrlhhinh hugidrohhrghdruhhkpdhrtghpthhtoheptghorhgsvghtsehlfihnrdhnvghtpdhrtghp thhtohepjhgrmhgvshdrsghothhtohhmlhgvhieshhgrnhhsvghnphgrrhhtnhgvrhhshh hiphdrtghomhdprhgtphhtthhopehkjhhlgiesthgvmhhplhgvohhfshhtuhhpihgurdgt ohhm X-ME-Proxy: Feedback-ID: i67e946c9:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 21 Jan 2025 10:47:21 -0500 (EST) From: David Reaver To: Greg Kroah-Hartman , Tejun Heo Cc: David Reaver , Steven Rostedt , Christian Brauner , Al Viro , Jonathan Corbet , James Bottomley , Krister Johansen , linux-fsdevel@vger.kernel.org Subject: [PATCH 5/5] samples/kernfs: Add inc file to allow changing counter increment Date: Tue, 21 Jan 2025 07:47:17 -0800 Message-ID: <20250121154719.43303-1-me@davidreaver.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250121153646.37895-1-me@davidreaver.com> References: <20250121153646.37895-1-me@davidreaver.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 --- samples/kernfs/sample_kernfs.c | 42 +++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) 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; }