LINUX: Introduce afs_d_alias_foreach

We have a couple of places in the code that iterate over the dentry
aliases of an inode, and each of these involves a small #ifdef ladder
to handle slightly different ways of traversing the relevant list.
Split this logic into its own compatibility macro,
afs_d_alias_foreach[_reverse], to contain this ugliness in
osi_compat.h and make the callers more readable.

This commit should incur no functional change; it is just code
reorganization.

Reviewed-on: https://gerrit.openafs.org/15390
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit 5aaed53f07fae0856e6da9defc408960e72364a7)

Change-Id: I107c01917512da6c1043880cb93754be37919c47
Reviewed-on: https://gerrit.openafs.org/15401
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
This commit is contained in:
Andrew Deason 2023-04-07 14:10:58 -05:00 committed by Stephan Wiesand
parent 7f9445bbeb
commit 5e282943ff
3 changed files with 44 additions and 19 deletions

View File

@ -776,4 +776,46 @@ afs_setattr_prepare(struct dentry *dp, struct iattr *newattrs)
#endif
}
/*
* afs_d_alias_foreach - Iterate over dentry aliases of an inode. Use like this:
*
* afs_d_alias_lock(inode);
* afs_d_alias_foreach(dentry, inode, node) {
* spin_lock(&dentry->d_lock);
* dentry->d_foo = bar;
* spin_unlock(&dentry->d_lock);
* }
* afs_d_alias_unlock(inode);
*
* 'node' is a struct hlist_node, and is only used when D_ALIAS_IS_HLIST &&
* !HLIST_ITERATOR_NO_NODE.
*
* afs_d_alias_foreach_reverse is the same, but traverses the list in the
* reverse direction when possible (non-D_ALIAS_IS_HLIST). For
* D_ALIAS_IS_HLIST, Linux doesn't provide macros for going in reverse (struct
* hlist_head doesn't point directly to the end of the list), so just traverse
* forwards.
*
* @pre afs_d_alias_lock(inode) held
*/
#if defined(D_ALIAS_IS_HLIST)
# if defined(HLIST_ITERATOR_NO_NODE)
# define afs_d_alias_foreach(dentry, inode, node) \
hlist_for_each_entry((dentry), &((inode)->i_dentry), d_alias)
# else
# define afs_d_alias_foreach(dentry, inode, node) \
hlist_for_each_entry((dentry), (node), &((inode)->i_dentry), d_alias)
# endif /* HLIST_ITERATOR_NO_NODE */
# define afs_d_alias_foreach_reverse afs_d_alias_foreach
#else /* D_ALIAS_IS_HLIST */
# define afs_d_alias_foreach(dentry, inode, node) \
list_for_each_entry((dentry), &((inode)->i_dentry), d_alias)
# define afs_d_alias_foreach_reverse(dentry, inode, node) \
list_for_each_entry_reverse((dentry), &((inode)->i_dentry), d_alias)
#endif /* D_ALIAS_IS_HLIST */
#endif /* AFS_LINUX_OSI_COMPAT_H */

View File

@ -26,15 +26,7 @@ TryEvictDirDentries(struct inode *inode)
afs_d_alias_lock(inode);
restart:
#if defined(D_ALIAS_IS_HLIST)
# if defined(HLIST_ITERATOR_NO_NODE)
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
# else
hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
# endif
#else
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
#endif
afs_d_alias_foreach(dentry, inode, p) {
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);

View File

@ -994,16 +994,7 @@ canonical_dentry(struct inode *ip)
afs_d_alias_lock(ip);
#if defined(D_ALIAS_IS_HLIST)
# if defined(HLIST_ITERATOR_NO_NODE)
hlist_for_each_entry(cur, &ip->i_dentry, d_alias) {
# else
hlist_for_each_entry(cur, p, &ip->i_dentry, d_alias) {
# endif
#else
list_for_each_entry_reverse(cur, &ip->i_dentry, d_alias) {
#endif
afs_d_alias_foreach_reverse(cur, ip, p) {
if (!vcp->target_link || cur == vcp->target_link) {
ret = cur;
break;