From: Linus Torvalds Date: Fri, 6 Dec 2019 01:11:48 +0000 (-0800) Subject: Merge branch 'next.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs X-Git-Tag: v5.5-rc1~31 X-Git-Url: https://repo.jachan.dev/J-linux.git/commitdiff_plain/b0d4beaa5a4b7d31070c41c2e50740304a3f1138?hp=-c Merge branch 'next.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull autofs updates from Al Viro: "autofs misuses checks for ->d_subdirs emptiness; the cursors are in the same lists, resulting in false negatives. It's not needed anyway, since autofs maintains counter in struct autofs_info, containing 0 for removed ones, 1 for live symlinks and 1 + number of children for live directories, which is precisely what we need for those checks. This series switches to use of that counter and untangles the crap around its uses (it needs not be atomic and there's a bunch of completely pointless "defensive" checks). This fell out of dcache_readdir work; the main point is to get rid of ->d_subdirs abuses in there. I've more followup cleanups, but I hadn't run those by Ian yet, so they can go next cycle" * 'next.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: autofs: don't bother with atomics for ino->count autofs_dir_rmdir(): check ino->count for deciding whether it's empty... autofs: get rid of pointless checks around ->count handling autofs_clear_leaf_automount_flags(): use ino->count instead of ->d_subdirs --- b0d4beaa5a4b7d31070c41c2e50740304a3f1138 diff --combined fs/autofs/expire.c index 91f5787dae7c,31d616aa6fc9..a1c7701007e7 --- a/fs/autofs/expire.c +++ b/fs/autofs/expire.c @@@ -211,7 -211,7 +211,7 @@@ static int autofs_tree_busy(struct vfsm } } else { struct autofs_info *ino = autofs_dentry_ino(p); - unsigned int ino_count = atomic_read(&ino->count); + unsigned int ino_count = READ_ONCE(ino->count); /* allow for dget above and top is already dgot */ if (p == top) @@@ -379,7 -379,7 +379,7 @@@ static struct dentry *should_expire(str /* Not a forced expire? */ if (!(how & AUTOFS_EXP_FORCED)) { /* ref-walk currently on this dentry? */ - ino_count = atomic_read(&ino->count) + 1; + ino_count = READ_ONCE(ino->count) + 1; if (d_count(dentry) > ino_count) return NULL; } @@@ -396,7 -396,7 +396,7 @@@ /* Not a forced expire? */ if (!(how & AUTOFS_EXP_FORCED)) { /* ref-walk currently on this dentry? */ - ino_count = atomic_read(&ino->count) + 1; + ino_count = READ_ONCE(ino->count) + 1; if (d_count(dentry) > ino_count) return NULL; } @@@ -459,10 -459,9 +459,10 @@@ static struct dentry *autofs_expire_ind */ how &= ~AUTOFS_EXP_LEAVES; found = should_expire(expired, mnt, timeout, how); - if (!found || found != expired) - /* Something has changed, continue */ + if (found != expired) { // something has changed, continue + dput(found); goto next; + } if (expired != dentry) dput(dentry);