However, if the string is freely accessible for the duration of inode's
lifetime, consider using inode_set_cached_link() instead.
+
+---
+
+**recommended**
+
+If you really need to iterate through dentries for given inode, use
+for_each_alias(dentry, inode) instead of hlist_for_each_entry; better
+yet, see if any of the exported primitives could be used instead of
+the entire loop. You still need to hold ->i_lock of the inode over
+either form of manual loop.
{
struct dentry *dentry;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(dentry, inode) {
if (entry_ino == (u32)(long)dentry->d_fsdata) {
dentry->d_fsdata = (void *)inode->i_ino;
break;
goto out_unlock;
}
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(alias, inode) {
spin_lock(&alias->d_lock);
if (!d_unhashed(alias) &&
(ceph_dentry(alias)->flags & CEPH_DENTRY_PRIMARY_LINK)) {
struct dentry *de;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(de, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(de, inode) {
spin_lock(&de->d_lock);
de->d_flags |= DCACHE_DONTCACHE;
spin_unlock(&de->d_lock);
if (S_ISDIR(inode->i_mode))
return __d_find_any_alias(inode);
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(alias, inode) {
spin_lock(&alias->d_lock);
if (!d_unhashed(alias)) {
dget_dlock(alias);
struct dentry *dentry;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias)
+ for_each_alias(dentry, inode)
d_dispose_if_unused(dentry, &dispose);
spin_unlock(&inode->i_lock);
shrink_dentry_list(&dispose);
inode = result->d_inode;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(dentry, inode) {
dget(dentry);
spin_unlock(&inode->i_lock);
if (toput)
struct dentry *alias;
struct inode *dir;
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(alias, inode) {
spin_lock(&alias->d_lock);
dir = d_inode_rcu(alias->d_parent);
if (!dir ||
spin_lock(&inode->i_lock);
/* run all of the dentries associated with this inode. Since this is a
* directory, there damn well better only be one item on this list */
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(alias, inode) {
struct dentry *child;
/* run all of the children of the original inode and fix their
struct dentry *dentry;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(dentry, inode) {
spin_lock(&dentry->d_lock);
if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
trace_ocfs2_find_local_alias(dentry->d_name.len,
/* Try to find another, hashed alias */
spin_lock(&inode->i_lock);
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(alias, inode) {
if (alias != dentry && !d_unhashed(alias))
break;
}
struct dentry *dentry;
spin_lock(&inode->i_lock);
- hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
+ for_each_alias(dentry, inode) {
if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
spin_unlock(&inode->i_lock);
return true;
struct dentry *d_make_persistent(struct dentry *, struct inode *);
void d_make_discardable(struct dentry *dentry);
+/* inode->i_lock must be held over that */
+#define for_each_alias(dentry, inode) \
+ hlist_for_each_entry(dentry, &(inode)->i_dentry, d_u.d_alias)
+
#endif /* __LINUX_DCACHE_H */