25 Mar, 2011

4 commits

  • The autofs4_lock introduced by the rcu-walk changes has unnecessarily
    broad scope. The locking is better handled by the per-autofs super
    block lookup_lock.

    Signed-off-by: Ian Kent
    Acked-by: David Howells
    Signed-off-by: Al Viro

    Ian Kent
     
  • 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
    Signed-off-by: Al Viro

    Ian Kent
     
  • There is a missing dput() when returning from autofs4_expire_direct()
    when we see that the dentry is already a pending mount.

    Signed-off-by: Ian Kent
    Acked-by: David Howells
    Signed-off-by: Al Viro

    Ian Kent
     
  • When direct (and offset) mounts were introduced the the last used
    timeout could no longer be updated in ->d_revalidate(). This is
    because covered direct mounts would be followed over without calling
    the autofs file system. As a result the definition of the busyness
    check for all entries was changed to be "actually busy" being an open
    file or working directory within the automount. But now we have a call
    back in the follow so the last used update on any access can be
    re-instated. This requires DCACHE_MANAGE_TRANSIT to always be set.

    Signed-off-by: Ian Kent
    Signed-off-by: Al Viro

    Ian Kent
     

18 Jan, 2011

1 commit

  • The initialization condition in fs/autofs4/expire.c:get_next_positive_dentry()
    appears to be incorrect. If prev == NULL I believe that root should be
    returned.

    Further down, at the current dentry check for it being simple_positive()
    it looks like the d_lock for dentry p should be dropped instead of dentry
    ret, otherwise when p is assinged to ret we end up with no lock on p and
    a lost lock on ret, which leads to a deadlock.

    Signed-off-by: Ian Kent
    Signed-off-by: Al Viro

    Ian Kent
     

16 Jan, 2011

3 commits

  • This patch required a previous patch to add the ->d_automount()
    dentry operation.

    Add a function to use the newly defined ->d_manage() dentry operation
    for blocking during mount and expire.

    Whether the VFS calls the dentry operations d_automount() and d_manage()
    is controled by the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags. autofs
    uses the d_automount() operation to callback to user space to request
    mount operations and the d_manage() operation to block walks into mounts
    that are under construction or destruction.

    In order to prevent these functions from being called unnecessarily the
    DMANAGED_* flags are cleared for cases which would cause this. In the
    common case the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags are both
    set for dentrys waiting to be mounted. The DMANAGED_TRANSIT flag is
    cleared upon successful mount request completion and set during expire
    runs, both during the dentry expire check, and if selected for expire,
    is left set until a subsequent successful mount request completes.

    The exception to this is the so-called rootless multi-mount which has
    no actual mount at its base. In this case the DMANAGED_AUTOMOUNT flag
    is cleared upon successful mount request completion as well and set
    again after a successful expire.

    Signed-off-by: Ian Kent
    Signed-off-by: David Howells
    Signed-off-by: Al Viro

    Ian Kent
     
  • Add a function to use the newly defined ->d_automount() dentry operation
    for triggering mounts instead of doing the user space callback in ->lookup()
    and ->d_revalidate().

    Note, to be useful the subsequent patch to add the ->d_manage() dentry
    operation is also needed so the discussion of functionality is deferred to
    that patch.

    Signed-off-by: Ian Kent
    Signed-off-by: David Howells
    Signed-off-by: Al Viro

    Ian Kent
     
  • Add a dentry op (d_manage) to permit a filesystem to hold a process and make it
    sleep when it tries to transit away from one of that filesystem's directories
    during a pathwalk. The operation is keyed off a new dentry flag
    (DCACHE_MANAGE_TRANSIT).

    The filesystem is allowed to be selective about which processes it holds and
    which it permits to continue on or prohibits from transiting from each flagged
    directory. This will allow autofs to hold up client processes whilst letting
    its userspace daemon through to maintain the directory or the stuff behind it
    or mounted upon it.

    The ->d_manage() dentry operation:

    int (*d_manage)(struct path *path, bool mounting_here);

    takes a pointer to the directory about to be transited away from and a flag
    indicating whether the transit is undertaken by do_add_mount() or
    do_move_mount() skipping through a pile of filesystems mounted on a mountpoint.

    It should return 0 if successful and to let the process continue on its way;
    -EISDIR to prohibit the caller from skipping to overmounted filesystems or
    automounting, and to use this directory; or some other error code to return to
    the user.

    ->d_manage() is called with namespace_sem writelocked if mounting_here is true
    and no other locks held, so it may sleep. However, if mounting_here is true,
    it may not initiate or wait for a mount or unmount upon the parameter
    directory, even if the act is actually performed by userspace.

    Within fs/namei.c, follow_managed() is extended to check with d_manage() first
    on each managed directory, before transiting away from it or attempting to
    automount upon it.

    follow_down() is renamed follow_down_one() and should only be used where the
    filesystem deliberately intends to avoid management steps (e.g. autofs).

    A new follow_down() is added that incorporates the loop done by all other
    callers of follow_down() (do_add/move_mount(), autofs and NFSD; whilst AFS, NFS
    and CIFS do use it, their use is removed by converting them to use
    d_automount()). The new follow_down() calls d_manage() as appropriate. It
    also takes an extra parameter to indicate if it is being called from mount code
    (with namespace_sem writelocked) which it passes to d_manage(). follow_down()
    ignores automount points so that it can be used to mount on them.

    __follow_mount_rcu() is made to abort rcu-walk mode if it hits a directory with
    DCACHE_MANAGE_TRANSIT set on the basis that we're probably going to have to
    sleep. It would be possible to enter d_manage() in rcu-walk mode too, and have
    that determine whether to abort or not itself. That would allow the autofs
    daemon to continue on in rcu-walk mode.

    Note that DCACHE_MANAGE_TRANSIT on a directory should be cleared when it isn't
    required as every tranist from that directory will cause d_manage() to be
    invoked. It can always be set again when necessary.

    ==========================
    WHAT THIS MEANS FOR AUTOFS
    ==========================

    Autofs currently uses the lookup() inode op and the d_revalidate() dentry op to
    trigger the automounting of indirect mounts, and both of these can be called
    with i_mutex held.

    autofs knows that the i_mutex will be held by the caller in lookup(), and so
    can drop it before invoking the daemon - but this isn't so for d_revalidate(),
    since the lock is only held on _some_ of the code paths that call it. This
    means that autofs can't risk dropping i_mutex from its d_revalidate() function
    before it calls the daemon.

    The bug could manifest itself as, for example, a process that's trying to
    validate an automount dentry that gets made to wait because that dentry is
    expired and needs cleaning up:

    mkdir S ffffffff8014e05a 0 32580 24956
    Call Trace:
    [] :autofs4:autofs4_wait+0x674/0x897
    [] avc_has_perm+0x46/0x58
    [] autoremove_wake_function+0x0/0x2e
    [] :autofs4:autofs4_expire_wait+0x41/0x6b
    [] :autofs4:autofs4_revalidate+0x91/0x149
    [] __lookup_hash+0xa0/0x12f
    [] lookup_create+0x46/0x80
    [] sys_mkdirat+0x56/0xe4

    versus the automount daemon which wants to remove that dentry, but can't
    because the normal process is holding the i_mutex lock:

    automount D ffffffff8014e05a 0 32581 1 32561
    Call Trace:
    [] __mutex_lock_slowpath+0x60/0x9b
    [] do_path_lookup+0x2ca/0x2f1
    [] .text.lock.mutex+0xf/0x14
    [] do_rmdir+0x77/0xde
    [] tracesys+0x71/0xe0
    [] tracesys+0xd5/0xe0

    which means that the system is deadlocked.

    This patch allows autofs to hold up normal processes whilst the daemon goes
    ahead and does things to the dentry tree behind the automouter point without
    risking a deadlock as almost no locks are held in d_manage() and none in
    d_automount().

    Signed-off-by: David Howells
    Was-Acked-by: Ian Kent
    Signed-off-by: Al Viro

    David Howells
     

07 Jan, 2011

5 commits

  • Rather than keep a d_mounted count in the dentry, set a dentry flag instead.
    The flag can be cleared by checking the hash table to see if there are any
    mounts left, which is not time critical because it is performed at detach time.

    The mounted state of a dentry is only used to speculatively take a look in the
    mount hash table if it is set -- before following the mount, vfsmount lock is
    taken and mount re-checked without races.

    This saves 4 bytes on 32-bit, nothing on 64-bit but it does provide a hole I
    might use later (and some configs have larger than 32-bit spinlocks which might
    make use of the hole).

    Autofs4 conversion and changelog by Ian Kent :
    In autofs4, when expring direct (or offset) mounts we need to ensure that we
    block user path walks into the autofs mount, which is covered by another mount.
    To do this we clear the mounted status so that follows stop before walking into
    the mount and are essentially blocked until the expire is completed. The
    automount daemon still finds the correct dentry for the umount due to the
    follow mount logic in fs/autofs4/root.c:autofs4_follow_link(), which is set as
    an inode operation for direct and offset mounts only and is called following
    the lookup that stopped at the covered mount.

    At the end of the expire the covering mount probably has gone away so the
    mounted status need not be restored. But we need to check this and only restore
    the mounted status if the expire failed.

    XXX: autofs may not work right if we have other mounts go over the top of it?

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • dcache_lock no longer protects anything. remove it.

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Protect d_subdirs and d_child with d_lock, except in filesystems that aren't
    using dcache_lock for these anyway (eg. using i_mutex).

    Note: if we change the locking rule in future so that ->d_child protection is
    provided only with ->d_parent->d_lock, it may allow us to reduce some locking.
    But it would be an exception to an otherwise regular locking scheme, so we'd
    have to see some good results. Probably not worthwhile.

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Protect d_unhashed(dentry) condition with d_lock. This means keeping
    DCACHE_UNHASHED bit in synch with hash manipulations.

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Make d_count non-atomic and protect it with d_lock. This allows us to ensure a
    0 refcount dentry remains 0 without dcache_lock. It is also fairly natural when
    we start protecting many other dentry members with d_lock.

    Signed-off-by: Nick Piggin

    Nick Piggin
     

04 Mar, 2010

1 commit


16 Dec, 2009

2 commits

  • We need to be able to cope with the directory mutex being held during
    ->d_revalidate() in some cases, but not all cases, and not necessarily by
    us. Because we need to release the mutex when we call back to the daemon
    to do perform a mount we must be sure that it is us who holds the mutex so
    we must redirect mount requests to ->lookup() if the mutex is held.

    Signed-off-by: Ian Kent
    Cc: Sage Weil
    Cc: Al Viro
    Cc: Andreas Dilger
    Cc: Christoph Hellwig
    Cc: Yehuda Saheh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Eliminate the use of the d_lock spin lock by using the autofs super block
    info spin lock. This reduces the number of spin locks we use by one and
    makes the code for the following patch (to redirect ->d_revalidate() to
    ->lookup()) a little simpler.

    Signed-off-by: Ian Kent
    Cc: Sage Weil
    Cc: Al Viro
    Cc: Andreas Dilger
    Cc: Christoph Hellwig
    Cc: Yehuda Saheh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

01 Sep, 2009

1 commit


12 Jun, 2009

1 commit


03 May, 2009

1 commit


01 Apr, 2009

1 commit

  • A significant portion of the autofs_dev_ioctl_expire() and
    autofs4_expire_multi() functions is duplicated code. This patch cleans that
    up.

    Signed-off-by: Ian Kent
    Signed-off-by: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

07 Jan, 2009

1 commit

  • - the type assigned at mount when no type is given is changed
    from 0 to AUTOFS_TYPE_INDIRECT. This was done because 0 and
    AUTOFS_TYPE_INDIRECT were being treated implicitly as the same
    type.

    - previously, an offset mount had it's type set to
    AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET but the mount control
    re-implementation needs to be able distinguish all three types.
    So this was changed to make the type setting explicit.

    - a type AUTOFS_TYPE_ANY was added for use by the re-implementation
    when checking if a given path is a mountpoint. It's not really a
    type as we use this to ask if a given path is a mountpoint in the
    autofs_dev_ioctl_ismountpoint() function.

    - functions to set and test the autofs mount types have been added to
    improve readability and make the type usage explicit.

    - the mount type is used from user space for the mount control
    re-implementtion so, for consistency, all the definitions have
    been moved to the user space include file include/linux/auto_fs4.h.

    Signed-off-by: Ian Kent
    Signed-off-by: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

07 Nov, 2008

1 commit

  • When checking a directory tree in autofs_tree_busy() we can incorrectly
    decide that the tree isn't busy. This happens for the case of an active
    offset mount as autofs4_follow_mount() follows past the active offset
    mount, which has an open file handle used for expires, causing the file
    handle not to count toward the busyness check.

    Signed-off-by: Ian Kent
    Signed-off-by: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

17 Oct, 2008

2 commits

  • Add a miscellaneous device to the autofs4 module for routing ioctls. This
    provides the ability to obtain an ioctl file handle for an autofs mount
    point that is possibly covered by another mount.

    The actual problem with autofs is that it can't reconnect to existing
    mounts. Immediately one things of just adding the ability to remount
    autofs file systems would solve it, but alas, that can't work. This is
    because autofs direct mounts and the implementation of "on demand mount
    and expire" of nested mount trees have the file system mounted on top of
    the mount trigger dentry.

    To resolve this a miscellaneous device node for routing ioctl commands to
    these mount points has been implemented in the autofs4 kernel module and a
    library added to autofs. This provides the ability to open a file
    descriptor for these over mounted autofs mount points.

    Please refer to Documentation/filesystems/autofs4-mount-control.txt for a
    discussion of the problem, implementation alternatives considered and a
    description of the interface.

    [akpm@linux-foundation.org: coding-style fixes]
    [akpm@linux-foundation.org: build fix]
    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Usage of the AUTOFS_TYPE_* defines is a little confusing and appears
    inconsistent.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

25 Jul, 2008

3 commits

  • This patch re-orgnirzes the checking for and waiting on active expires and
    elininates redundant checks.

    Signed-off-by: Ian Kent
    Cc: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • For direct and offset type mounts that are covered by another mount we
    cannot check the AUTOFS_INF_EXPIRING flag during a path walk which leads
    to lookups walking into an expiring mount while it is being expired.

    For example, for the direct multi-mount map entry with a couple of
    offsets:

    /race/mm1 / :/
    /om1 :/
    /om2 :/

    an autofs trigger mount is mounted on /race/mm1 and when accessed it is
    over mounted and trigger mounts made for /race/mm1/om1 and /race/mm1/om2.
    So it isn't possible for path walks to see the expiring flag at all and
    they happily walk into the file system while it is expiring.

    When expiring these mounts follow_down() must stop at the autofs mount and
    all processes must block in the ->follow_link() method (except the daemon)
    until the expire is complete. This is done by decrementing the d_mounted
    field of the autofs trigger mount root dentry until the expire is
    completed. In ->follow_link() all processes wait on the expire and the
    mount following is completed for the daemon until the expire is complete.

    Signed-off-by: Ian Kent
    Cc: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • The selection of a dentry for expiration and the setting of the
    AUTOFS_INF_EXPIRING flag isn't done atomically which can lead to lookups
    walking into an expiring mount.

    What happens is that an expire is initiated by the daemon and a dentry is
    selected for expire but, since there is no lock held between the selection
    and setting of the expiring flag, a process may find the flag clear and
    continue walking into the mount tree at the same time the daemon attempts
    the expire it.

    Signed-off-by: Ian Kent
    Reviewed-by: Jeff Moyer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

01 May, 2008

2 commits

  • Here are some more places where path_{get,put}() can be used instead of
    dput()/mntput() pair. Besides that it fixes a bug in autofs4_mount_busy()
    where mntput() was called before dput().

    Signed-off-by: Jan Blunck
    Cc: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Blunck
     
  • Re-order some code in expire.c:autofs4_expire_indirect() to avoid compile
    warning, reported by Harvey Harrison:

    CHECK fs/autofs4/expire.c
    fs/autofs4/expire.c:383:2: warning: context imbalance in
    'autofs4_expire_indirect' - unexpected unlock

    Signed-off-by: Ian Kent
    Reviewed-by: Harvey Harrison
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

26 Sep, 2006

1 commit

  • If the timeout of an autofs mount is set to zero then umounts are disabled.
    This works fine, however the kernel module checks the expire timeout and
    goes no further if it is zero. This is not the right thing to do at
    shutdown as the module is passed an option to expire mounts regardless of
    their timeout setting.

    This patch allows autofs to honor the force expire option.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

27 Jun, 2006

1 commit

  • This patch converts the combination of list_del(A) and list_add(A, B) to
    list_move(A, B) under fs/.

    Cc: Ian Kent
    Acked-by: Joel Becker
    Cc: Neil Brown
    Cc: Hans Reiser
    Cc: Urban Widmark
    Acked-by: David Howells
    Acked-by: Mark Fasheh
    Signed-off-by: Akinobu Mita
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Akinobu Mita
     

26 Jun, 2006

1 commit

  • I've found a case where invalid dentrys in a mount tree, waiting to be
    cleaned up by d_invalidate, prevent the expected expire.

    In this case dentrys created during a lookup for which a mount fails or has
    no entry in the mount map contribute to the d_count of the parent dentry.
    These dentrys may not be invalidated prior to comparing the interanl usage
    count of valid autofs dentrys against the dentry d_count which makes a
    mount tree appear busy so it doesn't expire.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     

28 Mar, 2006

8 commits

  • This functionality is also need for operation of autofs v5 direct mounts.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • This patch adds expire logic for autofs direct mounts.

    Signed-off-by: Ian Kent
    Cc: Al Viro
    Cc: Christoph Hellwig
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Change the functions may_umount and may_umount_tree to boolean functions to
    aid code readability.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Alter the expire semantics that define how "busyness" is determined.
    Currently a last_used counter is updated on every revalidate from processes
    other than the mount owner process group.

    This patch changes that so that an expire candidate is busy only if it has a
    reference count greater than the expected minimum, such as when there is an
    open file or working directory in use.

    This method is the only way that busyness can be established for direct mounts
    within the new implementation. For consistency the expire semantic is made
    the same for all mounts.

    A side effect of the patch is that mounts which remain mounted unessessarily
    in the presence of some GUI programs that scan the filesystem should now
    expire.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Fix the case where an expire returns busy on a tree mount when it is in fact
    not busy. This case was overlooked when the patch to prevent the expiring
    away of "scaffolding" directories for tree mounts was applied.

    The problem arises when a tree of mounts is a member of a map with other keys.
    The current logic will not expire the tree if any other mount in the map is
    busy. The solution is to maintain a "minimum" use count for each autofs
    dentry and compare this to the actual dentry usage count during expire.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Simplify the expire tree traversal code by using a function from namespace.c
    to calculate the next entry in the top down tree traversals carried out during
    the expire operation.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent
     
  • Change the names of the boolean functions autofs4_check_mount and
    autofs4_check_tree to autofs4_mount_busy and autofs4_tree_busy respectively
    and alters their return codes to suit in order to aid code readabilty.

    A couple of white space cleanups are included as well.

    Signed-off-by: Ian Kent
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ian Kent