lkml.org 
[lkml]   [2003]   [Mar]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] d_alloc_anon
Every filesystem that implements methods to convert from a NFS
filehandle to a dentry duplicates this code (there are even more out of
tree). Factor it out in common code. The function d_alloc_anon() is
already present in 2.5 with the same interface but a slightly different
implementation.


--- 1.22/fs/dcache.c Thu Jan 23 10:55:22 2003
+++ edited/fs/dcache.c Mon Mar 3 19:41:38 2003
@@ -659,6 +659,53 @@
}

/**
+ * d_alloc_anon - allocate an anonymous dentry
+ * @inode: inode to allocate the dentry for
+ *
+ * This is similar to d_alloc_root. It is used by filesystems when
+ * creating a dentry for a given inode, often in the process of
+ * mapping a filehandle to a dentry. The returned dentry may be
+ * anonymous, or may have a full name (if the inode was already
+ * in the cache). The file system may need to make further
+ * efforts to connect this dentry into the dcache properly.
+ *
+ * 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 not been released.
+ */
+
+struct dentry * d_alloc_anon(struct inode *inode)
+{
+ struct dentry *dentry;
+ struct list_head *p;
+
+ /* Try to find a dentry. If possible, get a well-connected one. */
+ spin_lock(&dcache_lock);
+ list_for_each(p, &inode->i_dentry) {
+ dentry = list_entry(p, struct dentry, d_alias);
+ if (!(dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
+ goto found;
+ }
+ spin_unlock(&dcache_lock);
+
+ /* Didn't find dentry. Create anonymous dcache entry. */
+ dentry = d_alloc_root(inode);
+ if (dentry)
+ dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ return dentry;
+
+found:
+ dget_locked(dentry);
+ spin_unlock(&dcache_lock);
+ iput(inode);
+ return dentry;
+}
+
+/**
* d_alloc_root - allocate root dentry
* @root_inode: inode to allocate the root for
*
--- 1.13/fs/fat/inode.c Thu Apr 4 21:31:14 2002
+++ edited/fs/fat/inode.c Mon Mar 3 19:40:10 2003
@@ -430,7 +430,6 @@
int len, int fhtype, int parent)
{
struct inode *inode = NULL;
- struct list_head *lp;
struct dentry *result;

if (fhtype != 3)
@@ -477,33 +476,14 @@
if (!inode)
return ERR_PTR(-ESTALE);

-
- /* now to find a dentry.
- * If possible, get a well-connected one
- *
- * Given the way that we found the inode, it *MUST* be
- * well-connected, but it is easiest to just copy the
- * code.
- */
- spin_lock(&dcache_lock);
- for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
- result = list_entry(lp,struct dentry, d_alias);
- if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
- dget_locked(result);
- result->d_vfs_flags |= DCACHE_REFERENCED;
- spin_unlock(&dcache_lock);
- iput(inode);
- return result;
- }
- }
- spin_unlock(&dcache_lock);
- result = d_alloc_root(inode);
+
+ result = d_alloc_anon(inode);
if (result == NULL) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
result->d_op = sb->s_root->d_op;
- result->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ result->d_vfs_flags |= DCACHE_REFERENCED;
return result;


--- 1.18/fs/nfsd/nfsfh.c Mon Dec 16 17:50:09 2002
+++ edited/fs/nfsd/nfsfh.c Mon Mar 3 19:40:10 2003
@@ -135,7 +135,6 @@
* of 0 means "accept any"
*/
struct inode *inode;
- struct list_head *lp;
struct dentry *result;
if (ino == 0)
return ERR_PTR(-ESTALE);
@@ -155,27 +154,14 @@
iput(inode);
return ERR_PTR(-ESTALE);
}
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- spin_lock(&dcache_lock);
- for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
- result = list_entry(lp,struct dentry, d_alias);
- if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
- dget_locked(result);
- result->d_vfs_flags |= DCACHE_REFERENCED;
- spin_unlock(&dcache_lock);
- iput(inode);
- return result;
- }
- }
- spin_unlock(&dcache_lock);
- result = d_alloc_root(inode);
+
+
+ result = d_alloc_anon(inode);
if (result == NULL) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
- result->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ result->d_vfs_flags |= DCACHE_REFERENCED;
return result;
}

--- 1.42/fs/reiserfs/inode.c Thu Feb 13 07:42:42 2003
+++ edited/fs/reiserfs/inode.c Mon Mar 3 19:40:11 2003
@@ -1249,7 +1249,6 @@
int len, int fhtype, int parent) {
struct cpu_key key ;
struct inode *inode = NULL ;
- struct list_head *lp;
struct dentry *result;

/* fhtype happens to reflect the number of u32s encoded.
@@ -1301,27 +1300,12 @@
if (!inode)
return ERR_PTR(-ESTALE) ;

- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- spin_lock(&dcache_lock);
- for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
- result = list_entry(lp,struct dentry, d_alias);
- if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
- dget_locked(result);
- result->d_vfs_flags |= DCACHE_REFERENCED;
- spin_unlock(&dcache_lock);
- iput(inode);
- return result;
- }
- }
- spin_unlock(&dcache_lock);
- result = d_alloc_root(inode);
+ result = d_alloc_anon(inode);
if (result == NULL) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
- result->d_flags |= DCACHE_NFSD_DISCONNECTED;
+ result->d_vfs_flags |= DCACHE_REFERENCED;
return result;

}
--- 1.12/include/linux/dcache.h Sat Aug 3 18:39:21 2002
+++ edited/include/linux/dcache.h Mon Mar 3 19:40:11 2003
@@ -165,6 +165,7 @@

/* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
+extern struct dentry * d_alloc_anon(struct inode *);
extern void shrink_dcache_sb(struct super_block *);
extern void shrink_dcache_parent(struct dentry *);
extern int d_invalidate(struct dentry *);
--- 1.67/kernel/ksyms.c Tue Oct 1 14:34:41 2002
+++ edited/kernel/ksyms.c Mon Mar 3 19:40:11 2003
@@ -164,6 +164,7 @@
EXPORT_SYMBOL(d_move);
EXPORT_SYMBOL(d_instantiate);
EXPORT_SYMBOL(d_alloc);
+EXPORT_SYMBOL(d_alloc_anon);
EXPORT_SYMBOL(d_lookup);
EXPORT_SYMBOL(__d_path);
EXPORT_SYMBOL(mark_buffer_dirty);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:33    [W:0.029 / U:0.780 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site