Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 925

kernel-2.6.18-238.el5.src.rpm

From: Eric Sandeen <sandeen@redhat.com>
Date: Wed, 25 Mar 2009 15:44:49 -0500
Subject: [fs] d_obtain_alias helper
Message-id: 49CA97C1.9030408@redhat.com
O-Subject: [PATCH 5/10] d_obtain_alias helper
Bugzilla: 470845
RH-Acked-by: Steven Whitehouse <swhiteho@redhat.com>
RH-Acked-by: Josef Bacik <josef@redhat.com>

Backport of:

commit 4ea3ada2955e4519befa98ff55dd62d6dfbd1705
Author: Christoph Hellwig <hch@lst.de>
Date:   Mon Aug 11 15:48:57 2008 +0200

    [PATCH] new helper: d_obtain_alias

    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>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

and one small bit of this (just the ESTALE change):

commit 440037287c5ebb07033ab927ca16bb68c291d309
Author: Christoph Hellwig <hch@lst.de>
Date:   Mon Aug 11 15:49:04 2008 +0200

    [PATCH] switch all filesystems over to d_obtain_alias

    Switch all users of d_alloc_anon to d_obtain_alias.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

diff --git a/fs/dcache.c b/fs/dcache.c
index 3aec28c..6071ec0 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1117,6 +1117,42 @@ struct dentry * d_alloc_anon(struct inode *inode)
 	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.  In case of an error the reference on the inode is released.
+ * To make it easier to use in export operations a %NULL or IS_ERR inode may
+ * be passed in and will be the error will be propagate to the return value,
+ * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
+ */
+struct dentry *d_obtain_alias(struct inode *inode)
+{
+	struct dentry *dentry;
+
+	if (!inode)
+		return ERR_PTR(-ESTALE);
+	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(d_obtain_alias);
+
 
 /**
  * d_splice_alias - splice a disconnected dentry into the tree if one exists
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index f8e03cc..ba24c70 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -231,6 +231,7 @@ extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
 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 *);