04 Jan, 2012

1 commit


09 Aug, 2011

1 commit

  • Use 'pr_debug()' for DPRINTK, which will do the proper type checking on
    the arguments (without generating code) even when DEBUG isn't #defined.

    Also, use the standard __VA_ARGS__ for the macros, and stop the
    pointless abuse of 'do { xyz } while (0)' when the macro is already a
    perfectly well-formed single statement.

    Reported-by: David Howells
    Suggested-by: Joe Perches
    Cc: Ian Kent
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

25 Mar, 2011

1 commit

  • 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
     

18 Jan, 2011

6 commits


16 Jan, 2011

7 commits

  • Merge the remaining autofs4 dentry ops tables. It doesn't matter if
    d_automount and d_manage are present on something that's not mountable or
    holdable as these ops are only used if the appropriate flags are set in
    dentry->d_flags.

    [AV] switch to ->s_d_op, since now _everything_ on autofs4 is using the
    same dentry_operations.

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

    David Howells
     
  • There are now two distinct dentry operations uses. One for dentrys
    that trigger mounts and one for dentrys that do not.

    Rationalize the use of these dentry operations and rename them to
    reflect their function.

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

    Ian Kent
     
  • Since the use of ->follow_link() has been eliminated there is no
    need to separate the indirect and direct inode operations.

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

    Ian Kent
     
  • Remove code that is not used due to the use of ->d_automount()
    and ->d_manage().

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

    Ian Kent
     
  • 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

3 commits

  • 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
     

04 Mar, 2010

1 commit


16 Dec, 2009

4 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
     
  • Define some simple helper functions for adding and deleting entries on the
    expiring dentry list.

    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
     
  • Define some simple helper functions for adding and deleting entries on the
    active (and unhashed) dentry list.

    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
     

12 Jun, 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
     

17 Oct, 2008

3 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
     
  • Track the uid and gid of the last process to request a mount for on an
    autofs dentry.

    [akpm@linux-foundation.org: fix tpyo in comment]
    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

7 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
     
  • If an autofs mount becomes catatonic before autofs4_wait_release() is
    called the wait queue counter will not be decremented down to zero and the
    entry will never be freed. There are also races decrementing the wait
    counter in the wait release function. To deal with this the counter needs
    to be updated while holding the wait queue mutex and waiters need to be
    woken up unconditionally when the wait is removed from the queue to ensure
    we eventually free the wait.

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

    Ian Kent
     
  • The autofs_wait_queue already contains all of the fields of the
    struct qstr, so change it into a qstr.

    This patch, from Jeff Moyer, has been modified a liitle by myself.

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

    Jeff Moyer
     
  • A while ago a patch to resolve a deadlock during directory creation was
    merged. This delayed the hashing of lookup dentrys until the ->mkdir()
    (or ->symlink()) operation completed to ensure we always went through
    ->lookup() instead of also having processes go through ->revalidate() so
    our VFS locking remained consistent.

    Now we are seeing a couple of side affects of that change in situations
    with heavy mount activity.

    Two cases have been identified:

    1) When a mount request is triggered, due to the delayed hashing, the
    directory created by user space for the mount point doesn't have the
    DCACHE_AUTOFS_PENDING flag set. In the case of an autofs multi-mount
    where a tree of mount point directories are created this can lead to
    the path walk continuing rather than the dentry being sent to the wait
    queue to wait for request completion. This is because, if the pending
    flag isn't set, the criteria for deciding this is a mount in progress
    fails to hold, namely that the dentry is not a mount point and has no
    subdirectories.

    2) A mount request dentry is initially created negative and unhashed.
    It remains this way until the ->mkdir() callback completes. Since it
    is unhashed a fresh dentry is used when the user space mount request
    creates the mount point directory. This leaves the original dentry
    negative and unhashed. But revalidate has no way to tell the VFS that
    the dentry has changed, other than to force another ->lookup() by
    returning false, which is at best wastefull and at worst not possible.
    This results in an -ENOENT return from the original path walk when in
    fact the mount succeeded.

    To resolve this we need to ensure that the same dentry is used in all
    calls to ->lookup() during the course of a mount request. This patch
    achieves that by adding the initial dentry to a look aside list and
    removes it at ->mkdir() or ->symlink() completion (or when the dentry is
    released), since these are the only create operations autofs4 supports.

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

    Ian Kent
     
  • Correct the error of making a positive dentry negative after it has been
    instantiated.

    The code that makes this error attempts to re-use the dentry from a
    concurrent expire and mount to resolve a race and the dentry used for the
    lookup must be negative for mounts to trigger in the required cases. The
    fact is that the dentry doesn't need to be re-used because all that is
    needed is to preserve the flag that indicates an expire is still
    incomplete at the time of the mount request.

    This change uses the the dentry to check the flag and wait for the expire
    to complete then discards it instead of attempting to re-use it.

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

    Ian Kent
     

30 Apr, 2008

1 commit


20 Oct, 2007

1 commit

  • The set of functions process_session, task_session, process_group and
    task_pgrp is confusing, as the names can be mixed with each other when looking
    at the code for a long time.

    The proposals are to
    * equip the functions that return the integer with _nr suffix to
    represent that fact,
    * and to make all functions work with task (not process) by making
    the common prefix of the same name.

    For monotony the routines signal_session() and set_signal_session() are
    replaced with task_session_nr() and set_task_session(), especially since they
    are only used with the explicit task->signal dereference.

    Signed-off-by: Pavel Emelianov
    Acked-by: Serge E. Hallyn
    Cc: Kirill Korotaev
    Cc: "Eric W. Biederman"
    Cc: Cedric Le Goater
    Cc: Herbert Poetzl
    Cc: Sukadev Bhattiprolu
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pavel Emelianov
     

21 Feb, 2007

1 commit

  • Jeff Moyer has identified a race between mount and expire.

    What happens is that during an expire the situation can arise that a directory
    is removed and another lookup is done before the expire issues a completion
    status to the kernel module. In this case, since the the lookup gets a new
    dentry, it doesn't know that there is an expire in progress and when it posts
    its mount request, matches the existing expire request and waits for its
    completion. ENOENT is then returned to user space from lookup (as the dentry
    passed in is now unhashed) without having performed the mount request.

    The solution used here is to keep track of dentrys in this unhashed state and
    reuse them, if possible, in order to preserve the flags. Additionally, this
    infrastructure will provide the framework for the reintroduction of caching of
    mount fails removed earlier in development.

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

    Ian Kent