autofs4 - fix autofs4_expire_indirect() traversal

The vfs-scale changes changed the traversal used in
autofs4_expire_indirect() from a list to a depth first tree traversal
which isn't right.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by Ian Kent and committed by Al Viro d4a85e35 f9398c23

+51 -1
+51 -1
fs/autofs4/expire.c
··· 87 87 } 88 88 89 89 /* 90 + * Calculate and dget next entry in the subdirs list under root. 91 + */ 92 + static struct dentry *get_next_positive_subdir(struct dentry *prev, 93 + struct dentry *root) 94 + { 95 + struct list_head *next; 96 + struct dentry *p, *q; 97 + 98 + spin_lock(&autofs4_lock); 99 + 100 + if (prev == NULL) { 101 + spin_lock(&root->d_lock); 102 + prev = dget_dlock(root); 103 + next = prev->d_subdirs.next; 104 + p = prev; 105 + goto start; 106 + } 107 + 108 + p = prev; 109 + spin_lock(&p->d_lock); 110 + again: 111 + next = p->d_u.d_child.next; 112 + start: 113 + if (next == &root->d_subdirs) { 114 + spin_unlock(&p->d_lock); 115 + spin_unlock(&autofs4_lock); 116 + dput(prev); 117 + return NULL; 118 + } 119 + 120 + q = list_entry(next, struct dentry, d_u.d_child); 121 + 122 + spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); 123 + /* Negative dentry - try next */ 124 + if (!simple_positive(q)) { 125 + spin_unlock(&p->d_lock); 126 + p = q; 127 + goto again; 128 + } 129 + dget_dlock(q); 130 + spin_unlock(&q->d_lock); 131 + spin_unlock(&p->d_lock); 132 + spin_unlock(&autofs4_lock); 133 + 134 + dput(prev); 135 + 136 + return q; 137 + } 138 + 139 + /* 90 140 * Calculate and dget next entry in top down tree traversal. 91 141 */ 92 142 static struct dentry *get_next_positive_dentry(struct dentry *prev, ··· 383 333 timeout = sbi->exp_timeout; 384 334 385 335 dentry = NULL; 386 - while ((dentry = get_next_positive_dentry(dentry, root))) { 336 + while ((dentry = get_next_positive_subdir(dentry, root))) { 387 337 spin_lock(&sbi->fs_lock); 388 338 ino = autofs4_dentry_ino(dentry); 389 339 /* No point expiring a pending mount */