linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Axtens <dja@axtens.net>
To: nayna@linux.ibm.com, cclaudio@linux.ibm.com,
	linux-fsdevel@vger.kernel.org, greg@kroah.com,
	linuxppc-dev@lists.ozlabs.org
Cc: Daniel Axtens <dja@axtens.net>
Subject: [WIP RFC PATCH 1/6] kernfs: add create() and unlink() hooks
Date: Mon, 20 May 2019 16:25:48 +1000	[thread overview]
Message-ID: <20190520062553.14947-2-dja@axtens.net> (raw)
In-Reply-To: <20190520062553.14947-1-dja@axtens.net>

I'm building a generic firmware variable filesystem on top of kernfs
and I'd like to be able to create and unlink files.

The hooks are fairly straightforward. create() returns a kernfs_node*,
which is safe with regards to cleanup on error paths, because there
is no way that things can fail after that point in the current
implementation. However, currently O_EXCL is not implemented and
that may create failure paths, in which case we may need to revisit
this later.

Signed-off-by: Daniel Axtens <dja@axtens.net>
---
 fs/kernfs/dir.c        | 55 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/kernfs.h |  3 +++
 2 files changed, 58 insertions(+)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 016ba88f7335..74fe51dbd027 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1175,6 +1175,59 @@ static int kernfs_iop_rename(struct inode *old_dir, struct dentry *old_dentry,
 	return ret;
 }
 
+static int kernfs_iop_create(struct inode *dir, struct dentry *dentry,
+			     umode_t mode, bool excl)
+{
+	struct kernfs_node *parent = dir->i_private;
+	struct kernfs_node *kn;
+	struct kernfs_syscall_ops *scops = kernfs_root(parent)->syscall_ops;
+
+	if (!scops || !scops->create)
+		return -EPERM;
+
+	if (!kernfs_get_active(parent))
+		return -ENODEV;
+
+	// TODO: add some locking to ensure that scops->create
+	// is called only once, and possibly to handle the O_EXCL case
+	WARN_ONCE(excl, "excl unimplemented");
+
+	kn = scops->create(parent, dentry->d_name.name, mode);
+
+	if (!kn)
+		return -EPERM;
+
+	if (IS_ERR(kn))
+		return PTR_ERR(kn);
+
+	d_instantiate(dentry, kernfs_get_inode(dir->i_sb, kn));
+
+	return 0;
+}
+
+static int kernfs_iop_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct kernfs_node *parent = dir->i_private;
+	struct kernfs_node *kn = d_inode(dentry)->i_private;
+	struct kernfs_syscall_ops *scops = kernfs_root(parent)->syscall_ops;
+	int ret;
+
+
+	if (!scops || !scops->unlink)
+		return -EPERM;
+
+	if (!kernfs_get_active(parent))
+		return -ENODEV;
+
+	ret = scops->unlink(kn);
+	if (ret)
+		return ret;
+
+	drop_nlink(d_inode(dentry));
+	dput(dentry);
+	return 0;
+};
+
 const struct inode_operations kernfs_dir_iops = {
 	.lookup		= kernfs_iop_lookup,
 	.permission	= kernfs_iop_permission,
@@ -1185,6 +1238,8 @@ const struct inode_operations kernfs_dir_iops = {
 	.mkdir		= kernfs_iop_mkdir,
 	.rmdir		= kernfs_iop_rmdir,
 	.rename		= kernfs_iop_rename,
+	.create		= kernfs_iop_create,
+	.unlink		= kernfs_iop_unlink,
 };
 
 static struct kernfs_node *kernfs_leftmost_descendant(struct kernfs_node *pos)
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 2bf477f86eb1..282b96acbd7e 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -179,6 +179,9 @@ struct kernfs_syscall_ops {
 		      const char *new_name);
 	int (*show_path)(struct seq_file *sf, struct kernfs_node *kn,
 			 struct kernfs_root *root);
+	struct kernfs_node* (*create)(struct kernfs_node *parent,
+				      const char *name, umode_t mode);
+	int (*unlink)(struct kernfs_node *kn);
 };
 
 struct kernfs_root {
-- 
2.19.1


  reply	other threads:[~2019-05-20  6:26 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-20  6:25 [WIP RFC PATCH 0/6] Generic Firmware Variable Filesystem Daniel Axtens
2019-05-20  6:25 ` Daniel Axtens [this message]
2019-05-20  6:25 ` [WIP RFC PATCH 2/6] fwvarfs: a generic firmware variable filesystem Daniel Axtens
2019-05-20  6:25 ` [WIP RFC PATCH 3/6] fwvarfs: efi backend Daniel Axtens
2019-05-20  6:25 ` [WIP RFC PATCH 4/6] powerpc/powernv: Add support for OPAL secure variables Daniel Axtens
2019-05-20  6:25 ` [WIP RFC PATCH 5/6] powerpc/powernv: Remove EFI " Daniel Axtens
2019-05-20  6:25 ` [WIP RFC PATCH 6/6] fwvarfs: Add opal_secvar backend Daniel Axtens
2019-05-31  4:04 ` [WIP RFC PATCH 0/6] Generic Firmware Variable Filesystem Nayna
2019-06-03  6:04   ` Daniel Axtens
2019-06-03  7:29     ` Greg KH
2019-06-03 23:56       ` Daniel Axtens
2019-06-04 20:01         ` Nayna
2019-06-04 20:05           ` Matthew Garrett
2019-06-05  8:13             ` Greg KH
2019-06-04 20:33       ` Nayna
2019-06-05  6:14         ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190520062553.14947-2-dja@axtens.net \
    --to=dja@axtens.net \
    --cc=cclaudio@linux.ibm.com \
    --cc=greg@kroah.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=nayna@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).