diff options
| author | Christoph Hellwig <hch@lst.de> | 2008-08-11 15:48:57 +0200 | 
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-10-23 05:13:00 -0400 | 
| commit | 4ea3ada2955e4519befa98ff55dd62d6dfbd1705 (patch) | |
| tree | b473278d0df8d869d183fbc0e4a1a07585de240a | |
| parent | 3a8cff4f026c0b98bee6291eb28d4df42feb76dc (diff) | |
| download | olio-linux-3.10-4ea3ada2955e4519befa98ff55dd62d6dfbd1705.tar.xz olio-linux-3.10-4ea3ada2955e4519befa98ff55dd62d6dfbd1705.zip  | |
[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>
| -rw-r--r-- | fs/dcache.c | 35 | ||||
| -rw-r--r-- | fs/libfs.c | 26 | ||||
| -rw-r--r-- | include/linux/dcache.h | 1 | 
3 files changed, 38 insertions, 24 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index e7a1a99b746..46fc7820678 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1174,6 +1174,41 @@ 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.  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 diff --git a/fs/libfs.c b/fs/libfs.c index 1add676a19d..74688598bcf 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -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; -} -  /**   * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation   * @sb:		filesystem to do the file handle conversion on @@ -782,7 +760,7 @@ struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,  		break;  	} -	return exportfs_d_alloc(inode); +	return d_obtain_alias(inode);  }  EXPORT_SYMBOL_GPL(generic_fh_to_dentry); @@ -815,7 +793,7 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,  		break;  	} -	return exportfs_d_alloc(inode); +	return d_obtain_alias(inode);  }  EXPORT_SYMBOL_GPL(generic_fh_to_parent); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index efba1de629a..2404257d6c6 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 *);  |