follow_automount() doesn't need the entire nameidata

Only the address of ->total_link_count and the flags.
And fix an off-by-one is ELOOP detection - make it
consistent with symlink following, where we check if
the pre-increment value has reached 40, rather than
check the post-increment one.

[kudos to Christian Brauner for spotted braino]

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2020-01-16 22:05:18 -05:00
parent 25e195aa1e
commit 1c9f5e06a6

View File

@ -1208,7 +1208,7 @@ EXPORT_SYMBOL(follow_up);
* - return -EISDIR to tell follow_managed() to stop and return the path we
* were called with.
*/
static int follow_automount(struct path *path, struct nameidata *nd)
static int follow_automount(struct path *path, int *count, unsigned lookup_flags)
{
struct dentry *dentry = path->dentry;
@ -1223,13 +1223,12 @@ static int follow_automount(struct path *path, struct nameidata *nd)
* as being automount points. These will need the attentions
* of the daemon to instantiate them before they can be used.
*/
if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
if (!(lookup_flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
LOOKUP_OPEN | LOOKUP_CREATE | LOOKUP_AUTOMOUNT)) &&
dentry->d_inode)
return -EISDIR;
nd->total_link_count++;
if (nd->total_link_count >= 40)
if (count && (*count)++ >= MAXSYMLINKS)
return -ELOOP;
return finish_automount(dentry->d_op->d_automount(path), path);
@ -1290,7 +1289,8 @@ static int follow_managed(struct path *path, struct nameidata *nd)
/* Handle an automount point */
if (flags & DCACHE_NEED_AUTOMOUNT) {
ret = follow_automount(path, nd);
ret = follow_automount(path, &nd->total_link_count,
nd->flags);
if (ret < 0)
break;
continue;