diff mbox

[1/8] vfs: new d_allocate method

Message ID 1466606110-24297-2-git-send-email-mszeredi@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Miklos Szeredi June 22, 2016, 2:35 p.m. UTC
Allow filesystem to initialize dentry (->d_fsdata to be explicit) at
allocation time.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 Documentation/filesystems/Locking |  2 ++
 Documentation/filesystems/vfs.txt |  3 +++
 fs/dcache.c                       | 11 +++++++++++
 include/linux/dcache.h            |  1 +
 4 files changed, 17 insertions(+)

Comments

Al Viro June 22, 2016, 5:02 p.m. UTC | #1
On Wed, Jun 22, 2016 at 04:35:03PM +0200, Miklos Szeredi wrote:
> Allow filesystem to initialize dentry (->d_fsdata to be explicit) at
> allocation time.

Something similar had been discussed a while ago (I don't remember whether
you'd been on Cc, though).  E.g. ceph and lustre would benefit from having
such method (proposed name was ->d_init(), seeing that it's not always
just an allocation).  The subtle part is barriers and I would really like
to see a proof that you don't need any.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Miklos Szeredi June 22, 2016, 8:33 p.m. UTC | #2
On Wed, Jun 22, 2016 at 7:02 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> On Wed, Jun 22, 2016 at 04:35:03PM +0200, Miklos Szeredi wrote:
>> Allow filesystem to initialize dentry (->d_fsdata to be explicit) at
>> allocation time.
>
> Something similar had been discussed a while ago (I don't remember whether
> you'd been on Cc, though).  E.g. ceph and lustre would benefit from having
> such method (proposed name was ->d_init(), seeing that it's not always
> just an allocation).  The subtle part is barriers and I would really like
> to see a proof that you don't need any.

Thanks for the review.  Yeah, I missed the rcu concequences.  And I
also didn't benchmark anything, it's obviously going to hurt somewhat
for fs that need to alloc an fsdata due to this.  I'm waiting to hear
better ideas.

One, rather ugly, is to make the max internal name length fs depenent,
and allow fs to use that space if it wants to trading it for a longer
d_iname.

Thaks,
Miklos
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75eea7ce3d7c..6da7d7363709 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -15,6 +15,7 @@  prototypes:
 	int (*d_compare)(const struct dentry *, const struct dentry *,
 			unsigned int, const char *, const struct qstr *);
 	int (*d_delete)(struct dentry *);
+	int (*d_allocate)(struct dentry *);
 	void (*d_release)(struct dentry *);
 	void (*d_iput)(struct dentry *, struct inode *);
 	char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
@@ -28,6 +29,7 @@  d_weak_revalidate:no		no		yes	 	no
 d_hash		no		no		no		maybe
 d_compare:	yes		no		no		maybe
 d_delete:	no		yes		no		no
+d_allocate:	no		no		yes		no
 d_release:	no		no		yes		no
 d_prune:        no              yes             no              no
 d_iput:		no		no		yes		no
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index c61a223ef3ff..4d8f1a5d8936 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -933,6 +933,7 @@  struct dentry_operations {
 	int (*d_compare)(const struct dentry *, const struct dentry *,
 			unsigned int, const char *, const struct qstr *);
 	int (*d_delete)(const struct dentry *);
+	int (*d_allocate)(struct dentry *);
 	void (*d_release)(struct dentry *);
 	void (*d_iput)(struct dentry *, struct inode *);
 	char *(*d_dname)(struct dentry *, char *, int);
@@ -1003,6 +1004,8 @@  struct dentry_operations {
 	always cache a reachable dentry. d_delete must be constant and
 	idempotent.
 
+  d_allocate: called when a dentry is really allocated
+
   d_release: called when a dentry is really deallocated
 
   d_iput: called when a dentry loses its inode (just prior to its
diff --git a/fs/dcache.c b/fs/dcache.c
index 817c243c1ff1..dc573af50edc 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1559,6 +1559,7 @@  struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
 {
 	struct dentry *dentry;
 	char *dname;
+	int err;
 
 	dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
 	if (!dentry)
@@ -1617,6 +1618,16 @@  struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
 	INIT_LIST_HEAD(&dentry->d_child);
 	d_set_d_op(dentry, dentry->d_sb->s_d_op);
 
+	if (dentry->d_op && dentry->d_op->d_allocate) {
+		err = dentry->d_op->d_allocate(dentry);
+		if (err) {
+			if (dname_external(dentry))
+				kfree(external_name(dentry));
+			kmem_cache_free(dentry_cache, dentry);
+			return NULL;
+		}
+	}
+
 	this_cpu_inc(nr_dentry);
 
 	return dentry;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index f28100f6b556..a2f01284b277 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -133,6 +133,7 @@  struct dentry_operations {
 	int (*d_compare)(const struct dentry *, const struct dentry *,
 			unsigned int, const char *, const struct qstr *);
 	int (*d_delete)(const struct dentry *);
+	int (*d_allocate)(struct dentry *);
 	void (*d_release)(struct dentry *);
 	void (*d_prune)(struct dentry *);
 	void (*d_iput)(struct dentry *, struct inode *);