* [PATCH 2/4] new helper: d_obtain_alias
@ 2008-08-11 13:48 Christoph Hellwig
2008-09-09 13:19 ` Miklos Szeredi
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2008-08-11 13:48 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel
The calling conventions of d_alloc_anon are rather unfortunate for all
users, and it's name is not very descriptive either.
Add d_obtain_alias as a new exported helper that drops the inode
reference in the failure case, too and allows to pass-through NULL
pointers and inodes to allow for tail-calls in the export operations.
Incidentally this helper already existed as a private function in
libfs.c as exportfs_d_alloc so kill that one and switch the callers
to d_obtain_alias.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/fs/dcache.c
===================================================================
--- linux-2.6.orig/fs/dcache.c 2008-08-11 10:01:26.000000000 -0300
+++ linux-2.6/fs/dcache.c 2008-08-11 10:35:13.000000000 -0300
@@ -1174,6 +1174,41 @@ struct dentry * d_alloc_anon(struct inod
return res;
}
+/**
+ * d_obtain_alias - find or allocate a dentry for a given inode
+ * @inode: inode to allocate the dentry for
+ *
+ * Obtain a dentry for an inode resulting from NFS filehandle conversion or
+ * similar open by handle operations. The returned dentry may be anonymous,
+ * or may have a full name (if the inode was already in the cache).
+ *
+ * When called on a directory inode, we must ensure that the inode only ever
+ * has one dentry. If a dentry is found, that is returned instead of
+ * allocating a new one.
+ *
+ * On successful return, the reference to the inode has been transferred
+ * to the dentry. If %NULL is returned (indicating kmalloc failure),
+ * the reference on the inode has been released. To make it easier
+ * to use in export operations a NULL or IS_ERR inode may be passed in
+ * and will be casted to the corresponding NULL or IS_ERR dentry.
+ */
+struct dentry *d_obtain_alias(struct inode *inode)
+{
+ struct dentry *dentry;
+
+ if (!inode)
+ return NULL;
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+
+ dentry = d_alloc_anon(inode);
+ if (!dentry) {
+ iput(inode);
+ dentry = ERR_PTR(-ENOMEM);
+ }
+ return dentry;
+}
+EXPORT_SYMBOL_GPL(d_obtain_alias);
/**
* d_splice_alias - splice a disconnected dentry into the tree if one exists
Index: linux-2.6/fs/libfs.c
===================================================================
--- linux-2.6.orig/fs/libfs.c 2008-08-11 10:01:27.000000000 -0300
+++ linux-2.6/fs/libfs.c 2008-08-11 10:01:35.000000000 -0300
@@ -732,28 +732,6 @@ out:
return ret;
}
-/*
- * This is what d_alloc_anon should have been. Once the exportfs
- * argument transition has been finished I will update d_alloc_anon
- * to this prototype and this wrapper will go away. --hch
- */
-static struct dentry *exportfs_d_alloc(struct inode *inode)
-{
- struct dentry *dentry;
-
- if (!inode)
- return NULL;
- if (IS_ERR(inode))
- return ERR_PTR(PTR_ERR(inode));
-
- dentry = d_alloc_anon(inode);
- if (!dentry) {
- iput(inode);
- dentry = ERR_PTR(-ENOMEM);
- }
- return dentry;
-}
-
static int fileid_length(int fileid_type)
{
switch (fileid_type) {
@@ -812,7 +790,7 @@ struct dentry *generic_fh_to_dentry(stru
break;
}
- return exportfs_d_alloc(inode);
+ return d_obtain_alias(inode);
}
EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
@@ -845,7 +823,7 @@ struct dentry *generic_fh_to_parent(stru
break;
}
- return exportfs_d_alloc(inode);
+ return d_obtain_alias(inode);
}
EXPORT_SYMBOL_GPL(generic_fh_to_parent);
Index: linux-2.6/include/linux/dcache.h
===================================================================
--- linux-2.6.orig/include/linux/dcache.h 2008-08-11 10:01:26.000000000 -0300
+++ linux-2.6/include/linux/dcache.h 2008-08-11 10:35:13.000000000 -0300
@@ -231,6 +231,7 @@ extern struct dentry * d_alloc(struct de
extern struct dentry * d_alloc_anon(struct inode *);
extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
+extern struct dentry * d_obtain_alias(struct inode *);
extern void shrink_dcache_sb(struct super_block *);
extern void shrink_dcache_parent(struct dentry *);
extern void shrink_dcache_for_umount(struct super_block *);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/4] new helper: d_obtain_alias
2008-08-11 13:48 [PATCH 2/4] new helper: d_obtain_alias Christoph Hellwig
@ 2008-09-09 13:19 ` Miklos Szeredi
2008-09-09 15:26 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Miklos Szeredi @ 2008-09-09 13:19 UTC (permalink / raw)
To: hch; +Cc: viro, linux-fsdevel
On Mon, 11 Aug 2008, Christoph Hellwig wrote:
> +/**
> + * d_obtain_alias - find or allocate a dentry for a given inode
> + * @inode: inode to allocate the dentry for
> + *
> + * Obtain a dentry for an inode resulting from NFS filehandle conversion or
> + * similar open by handle operations. The returned dentry may be anonymous,
> + * or may have a full name (if the inode was already in the cache).
> + *
> + * When called on a directory inode, we must ensure that the inode only ever
> + * has one dentry. If a dentry is found, that is returned instead of
> + * allocating a new one.
> + *
> + * On successful return, the reference to the inode has been transferred
> + * to the dentry. If %NULL is returned (indicating kmalloc failure),
^^^^^
ERR_PTR(-ENOMEM)
> + * the reference on the inode has been released.
That's useful.
> To make it easier
> + * to use in export operations a NULL or IS_ERR inode may be passed in
> + * and will be casted to the corresponding NULL or IS_ERR dentry.
> + */
Mixing NULL with ERR_PTR() seems like a bad idea. It should be either
one or the other but not both.
Miklos
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/4] new helper: d_obtain_alias
2008-09-09 13:19 ` Miklos Szeredi
@ 2008-09-09 15:26 ` Christoph Hellwig
2008-09-11 8:46 ` Miklos Szeredi
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2008-09-09 15:26 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: hch, viro, linux-fsdevel
On Tue, Sep 09, 2008 at 03:19:57PM +0200, Miklos Szeredi wrote:
> > + * and will be casted to the corresponding NULL or IS_ERR dentry.
> > + */
>
> Mixing NULL with ERR_PTR() seems like a bad idea. It should be either
> one or the other but not both.
It's how the existing interface works. I think we should move to only
ERR_PTR returns, but it's not very high on my todo list.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/4] new helper: d_obtain_alias
2008-09-09 15:26 ` Christoph Hellwig
@ 2008-09-11 8:46 ` Miklos Szeredi
0 siblings, 0 replies; 4+ messages in thread
From: Miklos Szeredi @ 2008-09-11 8:46 UTC (permalink / raw)
To: hch; +Cc: miklos, hch, viro, linux-fsdevel
On Tue, 9 Sep 2008, Christoph Hellwig wrote:
> On Tue, Sep 09, 2008 at 03:19:57PM +0200, Miklos Szeredi wrote:
> > > + * and will be casted to the corresponding NULL or IS_ERR dentry.
> > > + */
> >
> > Mixing NULL with ERR_PTR() seems like a bad idea. It should be either
> > one or the other but not both.
>
> It's how the existing interface works.
If you mean ->fh_to_dentry() and ->fh_to_parent(), yes they do work
this way. But a NULL return is simply equivalent to a -ESTALE return,
so why not turn !inode inot an -ESTALE in d_obtain_alias()? That
would fix the interface and the bug in fuse.
Miklos
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-09-11 8:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-11 13:48 [PATCH 2/4] new helper: d_obtain_alias Christoph Hellwig
2008-09-09 13:19 ` Miklos Szeredi
2008-09-09 15:26 ` Christoph Hellwig
2008-09-11 8:46 ` Miklos Szeredi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox