Skip to content
  • David Howells's avatar
    Add a dentry op to handle automounting rather than abusing follow_link() · 9875cf80
    David Howells authored
    
    
    Add a dentry op (d_automount) to handle automounting directories rather than
    abusing the follow_link() inode operation.  The operation is keyed off a new
    dentry flag (DCACHE_NEED_AUTOMOUNT).
    
    This also makes it easier to add an AT_ flag to suppress terminal segment
    automount during pathwalk and removes the need for the kludge code in the
    pathwalk algorithm to handle directories with follow_link() semantics.
    
    The ->d_automount() dentry operation:
    
    	struct vfsmount *(*d_automount)(struct path *mountpoint);
    
    takes a pointer to the directory to be mounted upon, which is expected to
    provide sufficient data to determine what should be mounted.  If successful, it
    should return the vfsmount struct it creates (which it should also have added
    to the namespace using do_add_mount() or similar).  If there's a collision with
    another automount attempt, NULL should be returned.  If the directory specified
    by the parameter should be used directly rather than being mounted upon,
    -EISDIR should be returned.  In any other case, an error code should be
    returned.
    
    The ->d_automount() operation is called with no locks held and may sleep.  At
    this point the pathwalk algorithm will be in ref-walk mode.
    
    Within fs/namei.c itself, a new pathwalk subroutine (follow_automount()) is
    added to handle mountpoints.  It will return -EREMOTE if the automount flag was
    set, but no d_automount() op was supplied, -ELOOP if we've encountered too many
    symlinks or mountpoints, -EISDIR if the walk point should be used without
    mounting and 0 if successful.  The path will be updated to point to the mounted
    filesystem if a successful automount took place.
    
    __follow_mount() is replaced by follow_managed() which is more generic
    (especially with the patch that adds ->d_manage()).  This handles transits from
    directories during pathwalk, including automounting and skipping over
    mountpoints (and holding processes with the next patch).
    
    __follow_mount_rcu() will jump out of RCU-walk mode if it encounters an
    automount point with nothing mounted on it.
    
    follow_dotdot*() does not handle automounts as you don't want to trigger them
    whilst following "..".
    
    I've also extracted the mount/don't-mount logic from autofs4 and included it
    here.  It makes the mount go ahead anyway if someone calls open() or creat(),
    tries to traverse the directory, tries to chdir/chroot/etc. into the directory,
    or sticks a '/' on the end of the pathname.  If they do a stat(), however,
    they'll only trigger the automount if they didn't also say O_NOFOLLOW.
    
    I've also added an inode flag (S_AUTOMOUNT) so that filesystems can mark their
    inodes as automount points.  This flag is automatically propagated to the
    dentry as DCACHE_NEED_AUTOMOUNT by __d_instantiate().  This saves NFS and could
    save AFS a private flag bit apiece, but is not strictly necessary.  It would be
    preferable to do the propagation in d_set_d_op(), but that doesn't normally
    have access to the inode.
    
    [AV: fixed breakage in case if __follow_mount_rcu() fails and nameidata_drop_rcu()
    succeeds in RCU case of do_lookup(); we need to fall through to non-RCU case after
    that, rather than just returning with ungrabbed *path]
    
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Was-Acked-by: default avatarIan Kent <raven@themaw.net>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    9875cf80