Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 117462
b: refs/heads/master
c: 9308a61
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Oct 23, 2008
1 parent 293d54b commit be18069
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 440037287c5ebb07033ab927ca16bb68c291d309
refs/heads/master: 9308a6128d9074e348d9f9b5822546fe12a794a9
108 changes: 37 additions & 71 deletions trunk/fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1110,70 +1110,6 @@ static inline struct hlist_head *d_hash(struct dentry *parent,
return dentry_hashtable + (hash & D_HASHMASK);
}

/**
* 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)
{
static const struct qstr anonstring = { .name = "" };
struct dentry *tmp;
struct dentry *res;

if ((res = d_find_alias(inode))) {
iput(inode);
return res;
}

tmp = d_alloc(NULL, &anonstring);
if (!tmp)
return NULL;

tmp->d_parent = tmp; /* make sure dput doesn't croak */

spin_lock(&dcache_lock);
res = __d_find_alias(inode, 0);
if (!res) {
/* attach a disconnected dentry */
res = tmp;
tmp = NULL;
spin_lock(&res->d_lock);
res->d_sb = inode->i_sb;
res->d_parent = res;
res->d_inode = inode;
res->d_flags |= DCACHE_DISCONNECTED;
res->d_flags &= ~DCACHE_UNHASHED;
list_add(&res->d_alias, &inode->i_dentry);
hlist_add_head(&res->d_hash, &inode->i_sb->s_anon);
spin_unlock(&res->d_lock);

inode = NULL; /* don't drop reference */
}
spin_unlock(&dcache_lock);

if (inode)
iput(inode);
if (tmp)
dput(tmp);
return res;
}

/**
* d_obtain_alias - find or allocate a dentry for a given inode
* @inode: inode to allocate the dentry for
Expand All @@ -1194,19 +1130,50 @@ struct dentry * d_alloc_anon(struct inode *inode)
*/
struct dentry *d_obtain_alias(struct inode *inode)
{
struct dentry *dentry;
static const struct qstr anonstring = { .name = "" };
struct dentry *tmp;
struct dentry *res;

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);
res = d_find_alias(inode);
if (res)
goto out_iput;

tmp = d_alloc(NULL, &anonstring);
if (!tmp) {
res = ERR_PTR(-ENOMEM);
goto out_iput;
}
return dentry;
tmp->d_parent = tmp; /* make sure dput doesn't croak */

spin_lock(&dcache_lock);
res = __d_find_alias(inode, 0);
if (res) {
spin_unlock(&dcache_lock);
dput(tmp);
goto out_iput;
}

/* attach a disconnected dentry */
spin_lock(&tmp->d_lock);
tmp->d_sb = inode->i_sb;
tmp->d_inode = inode;
tmp->d_flags |= DCACHE_DISCONNECTED;
tmp->d_flags &= ~DCACHE_UNHASHED;
list_add(&tmp->d_alias, &inode->i_dentry);
hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon);
spin_unlock(&tmp->d_lock);

spin_unlock(&dcache_lock);
return tmp;

out_iput:
iput(inode);
return res;
}
EXPORT_SYMBOL_GPL(d_obtain_alias);

Expand Down Expand Up @@ -2379,7 +2346,6 @@ void __init vfs_caches_init(unsigned long mempages)
}

EXPORT_SYMBOL(d_alloc);
EXPORT_SYMBOL(d_alloc_anon);
EXPORT_SYMBOL(d_alloc_root);
EXPORT_SYMBOL(d_delete);
EXPORT_SYMBOL(d_find_alias);
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/dcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ extern void d_delete(struct dentry *);

/* allocate/de-allocate */
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 *);
Expand Down

0 comments on commit be18069

Please sign in to comment.