diff options
author | Christoph Hellwig <hch@lst.de> | 2008-08-11 09:48:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-10-23 05:13:00 -0400 |
commit | 4ea3ada2955e4519befa98ff55dd62d6dfbd1705 (patch) | |
tree | b473278d0df8d869d183fbc0e4a1a07585de240a | |
parent | 3a8cff4f026c0b98bee6291eb28d4df42feb76dc (diff) |
[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 e7a1a99b7464..46fc78206782 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1174,6 +1174,41 @@ struct dentry * d_alloc_anon(struct inode *inode) | |||
1174 | return res; | 1174 | return res; |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | /** | ||
1178 | * d_obtain_alias - find or allocate a dentry for a given inode | ||
1179 | * @inode: inode to allocate the dentry for | ||
1180 | * | ||
1181 | * Obtain a dentry for an inode resulting from NFS filehandle conversion or | ||
1182 | * similar open by handle operations. The returned dentry may be anonymous, | ||
1183 | * or may have a full name (if the inode was already in the cache). | ||
1184 | * | ||
1185 | * When called on a directory inode, we must ensure that the inode only ever | ||
1186 | * has one dentry. If a dentry is found, that is returned instead of | ||
1187 | * allocating a new one. | ||
1188 | * | ||
1189 | * On successful return, the reference to the inode has been transferred | ||
1190 | * to the dentry. If %NULL is returned (indicating kmalloc failure), | ||
1191 | * the reference on the inode has been released. To make it easier | ||
1192 | * to use in export operations a NULL or IS_ERR inode may be passed in | ||
1193 | * and will be casted to the corresponding NULL or IS_ERR dentry. | ||
1194 | */ | ||
1195 | struct dentry *d_obtain_alias(struct inode *inode) | ||
1196 | { | ||
1197 | struct dentry *dentry; | ||
1198 | |||
1199 | if (!inode) | ||
1200 | return NULL; | ||
1201 | if (IS_ERR(inode)) | ||
1202 | return ERR_CAST(inode); | ||
1203 | |||
1204 | dentry = d_alloc_anon(inode); | ||
1205 | if (!dentry) { | ||
1206 | iput(inode); | ||
1207 | dentry = ERR_PTR(-ENOMEM); | ||
1208 | } | ||
1209 | return dentry; | ||
1210 | } | ||
1211 | EXPORT_SYMBOL_GPL(d_obtain_alias); | ||
1177 | 1212 | ||
1178 | /** | 1213 | /** |
1179 | * d_splice_alias - splice a disconnected dentry into the tree if one exists | 1214 | * d_splice_alias - splice a disconnected dentry into the tree if one exists |
diff --git a/fs/libfs.c b/fs/libfs.c index 1add676a19df..74688598bcf7 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -732,28 +732,6 @@ out: | |||
732 | return ret; | 732 | return ret; |
733 | } | 733 | } |
734 | 734 | ||
735 | /* | ||
736 | * This is what d_alloc_anon should have been. Once the exportfs | ||
737 | * argument transition has been finished I will update d_alloc_anon | ||
738 | * to this prototype and this wrapper will go away. --hch | ||
739 | */ | ||
740 | static struct dentry *exportfs_d_alloc(struct inode *inode) | ||
741 | { | ||
742 | struct dentry *dentry; | ||
743 | |||
744 | if (!inode) | ||
745 | return NULL; | ||
746 | if (IS_ERR(inode)) | ||
747 | return ERR_PTR(PTR_ERR(inode)); | ||
748 | |||
749 | dentry = d_alloc_anon(inode); | ||
750 | if (!dentry) { | ||
751 | iput(inode); | ||
752 | dentry = ERR_PTR(-ENOMEM); | ||
753 | } | ||
754 | return dentry; | ||
755 | } | ||
756 | |||
757 | /** | 735 | /** |
758 | * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation | 736 | * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation |
759 | * @sb: filesystem to do the file handle conversion on | 737 | * @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, | |||
782 | break; | 760 | break; |
783 | } | 761 | } |
784 | 762 | ||
785 | return exportfs_d_alloc(inode); | 763 | return d_obtain_alias(inode); |
786 | } | 764 | } |
787 | EXPORT_SYMBOL_GPL(generic_fh_to_dentry); | 765 | EXPORT_SYMBOL_GPL(generic_fh_to_dentry); |
788 | 766 | ||
@@ -815,7 +793,7 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
815 | break; | 793 | break; |
816 | } | 794 | } |
817 | 795 | ||
818 | return exportfs_d_alloc(inode); | 796 | return d_obtain_alias(inode); |
819 | } | 797 | } |
820 | EXPORT_SYMBOL_GPL(generic_fh_to_parent); | 798 | EXPORT_SYMBOL_GPL(generic_fh_to_parent); |
821 | 799 | ||
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index efba1de629ac..2404257d6c67 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 *); | |||
231 | extern struct dentry * d_alloc_anon(struct inode *); | 231 | extern struct dentry * d_alloc_anon(struct inode *); |
232 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); | 232 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); |
233 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); | 233 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); |
234 | extern struct dentry * d_obtain_alias(struct inode *); | ||
234 | extern void shrink_dcache_sb(struct super_block *); | 235 | extern void shrink_dcache_sb(struct super_block *); |
235 | extern void shrink_dcache_parent(struct dentry *); | 236 | extern void shrink_dcache_parent(struct dentry *); |
236 | extern void shrink_dcache_for_umount(struct super_block *); | 237 | extern void shrink_dcache_for_umount(struct super_block *); |