07 Dec, 2011

1 commit

  • __d_path() API is asking for trouble and in case of apparmor d_namespace_path()
    getting just that. The root cause is that when __d_path() misses the root
    it had been told to look for, it stores the location of the most remote ancestor
    in *root. Without grabbing references. Sure, at the moment of call it had
    been pinned down by what we have in *path. And if we raced with umount -l, we
    could have very well stopped at vfsmount/dentry that got freed as soon as
    prepend_path() dropped vfsmount_lock.

    It is safe to compare these pointers with pre-existing (and known to be still
    alive) vfsmount and dentry, as long as all we are asking is "is it the same
    address?". Dereferencing is not safe and apparmor ended up stepping into
    that. d_namespace_path() really wants to examine the place where we stopped,
    even if it's not connected to our namespace. As the result, it looked
    at ->d_sb->s_magic of a dentry that might've been already freed by that point.
    All other callers had been careful enough to avoid that, but it's really
    a bad interface - it invites that kind of trouble.

    The fix is fairly straightforward, even though it's bigger than I'd like:
    * prepend_path() root argument becomes const.
    * __d_path() is never called with NULL/NULL root. It was a kludge
    to start with. Instead, we have an explicit function - d_absolute_root().
    Same as __d_path(), except that it doesn't get root passed and stops where
    it stops. apparmor and tomoyo are using it.
    * __d_path() returns NULL on path outside of root. The main
    caller is show_mountinfo() and that's precisely what we pass root for - to
    skip those outside chroot jail. Those who don't want that can (and do)
    use d_path().
    * __d_path() root argument becomes const. Everyone agrees, I hope.
    * apparmor does *NOT* try to use __d_path() or any of its variants
    when it sees that path->mnt is an internal vfsmount. In that case it's
    definitely not mounted anywhere and dentry_path() is exactly what we want
    there. Handling of sysctl()-triggered weirdness is moved to that place.
    * if apparmor is asked to do pathname relative to chroot jail
    and __d_path() tells it we it's not in that jail, the sucker just calls
    d_absolute_path() instead. That's the other remaining caller of __d_path(),
    BTW.
    * seq_path_root() does _NOT_ return -ENAMETOOLONG (it's stupid anyway -
    the normal seq_file logics will take care of growing the buffer and redoing
    the call of ->show() just fine). However, if it gets path not reachable
    from root, it returns SEQ_SKIP. The only caller adjusted (i.e. stopped
    ignoring the return value as it used to do).

    Reviewed-by: John Johansen
    ACKed-by: John Johansen
    Signed-off-by: Al Viro
    Cc: stable@vger.kernel.org

    Al Viro
     

21 Nov, 2011

1 commit

  • To prevent an NFS server from being used to create a directory loop in an NFS
    superblock on the client, the following patch was committed:

    commit 1836750115f20b774e55c032a3893e8c5bdf41ed
    Author: Al Viro
    Date: Tue Jul 12 21:42:24 2011 -0400
    Subject: fix loop checks in d_materialise_unique()

    This causes ELOOP to be reported to anyone trying to access the dentry that
    would otherwise cause the kernel to complete the loop.

    However, no indication is given to the caller as to why an operation that ought
    to work doesn't. The fault is with the kernel, which doesn't want to try and
    solve the problem as it gets horrendously messy if there's another mountpoint
    somewhere in the trees being spliced that can't be moved[*].

    [*] The real problem is that we don't handle the excision of a subtree that
    gets moved _out_ of what we can see. This can happen on the server where a
    directory is merely moved between two other dirs on the same filesystem, but
    where destination dir is not accessible by the client.

    So, given the choice to return ELOOP rather than trying to reconfigure the
    dentry tree, we should give the caller some indication of why they aren't being
    allowed to make what should be a legitimate request and log a message.

    Signed-off-by: David Howells
    Acked-by: Sachin Prabhu
    Signed-off-by: Al Viro

    David Howells
     

08 Nov, 2011

1 commit


02 Nov, 2011

1 commit

  • This adds a d_prune dentry operation that is called by the VFS prior to
    pruning (i.e. unhashing and killing) a hashed dentry from the dcache.
    Wrap dentry_lru_del() and use the new _prune() helper in the cases where we
    are about to unhash and kill the dentry.

    This will be used by Ceph to maintain a flag indicating whether the
    complete contents of a directory are contained in the dcache, allowing it
    to satisfy lookups and readdir without addition server communication.

    Renumber a few DCACHE_* #defines to group DCACHE_OP_PRUNE with the other
    DCACHE_OP_ bits.

    Signed-off-by: Sage Weil
    Signed-off-by: Christoph Hellwig

    Sage Weil
     

07 Aug, 2011

1 commit

  • Gcc tends to generate better code with small integers, including the
    DCACHE_xyz flag tests - so move the common ones to be first in the list.
    Also just remove the unused DCACHE_INOTIFY_PARENT_WATCHED and
    DCACHE_AUTOFS_PENDING values, their users no longer exists in the source
    tree.

    And add a "unlikely()" to the DCACHE_OP_COMPARE test, since we want the
    common case to be a nice straight-line fall-through.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

04 Aug, 2011

1 commit


01 Aug, 2011

3 commits

  • Reorganise shrink_dcache_for_umount_subtree() in light of the demise of
    dcache_lock. Without that dcache_lock, there is no need for the batching of
    removal of dentries from the system under it (we wanted to make intensive use
    of the locked data whilst we held it, but didn't want to hold it for long at a
    time).

    This works, provided the preceding patch is correct in its removal of locking
    on dentry->d_lock on the basis that no one should be locking these dentries any
    more as the whole superblock is defunct.

    With this patch, the calls to dentry_lru_del() and __d_shrink() are placed at
    the point where each dentry is detached handled.

    It is possible that, as an alternative, the batching should still be done -
    but only for dentry_lru_del() of all a dentry's children in one go. In such a
    case, the batching would be done under dcache_lru_lock.

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

    David Howells
     
  • Locks of the dcache_lock were replaced by locks of dentry->d_lock in commits
    such as:

    2304450783dfde7b0b94ae234edd0dbffa865073
    2fd6b7f50797f2e993eea59e0a0b8c6399c811dc

    as part of the RCU-based pathwalk changes, despite the fact that the caller
    (shrink_dcache_for_umount()) notes in the banner comment the reasons that
    d_lock is not necessary in these functions:

    /*
    * destroy the dentries attached to a superblock on unmounting
    * - we don't need to use dentry->d_lock because:
    * - the superblock is detached from all mountings and open files, so the
    * dentry trees will not be rearranged by the VFS
    * - s_umount is write-locked, so the memory pressure shrinker will ignore
    * any dentries belonging to this superblock that it comes across
    * - the filesystem itself is no longer permitted to rearrange the dentries
    * in this superblock
    */

    So remove these locks. If the locks are actually necessary, then this banner
    comment should be altered instead.

    The hash table chains are protected by 1-bit locks in the hash table heads, so
    those shouldn't be a problem.

    Note that to make this work, __d_drop() has to be split so that the RCUwalk
    barrier can be avoided. This causes problems otherwise as it has an assertion
    that dentry->d_lock is locked - but there is no need for that as no one else
    can be trying to access this dentry, except to step over it (and that should
    be handled by d_free(), I think).

    Signed-off-by: David Howells
    Cc: Nick Piggin
    Signed-off-by: Al Viro

    David Howells
     
  • Remove the detached-dentry counter from shrink_dcache_for_umount_subtree() as
    the value it computes is no longer used as of commit
    312d3ca856d369bb04d0443846b85b4cdde6fa8a which made the nr_dentry counters
    summed per-CPU rather than global atomic.

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

    David Howells
     

27 Jul, 2011

1 commit


23 Jul, 2011

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (107 commits)
    vfs: use ERR_CAST for err-ptr tossing in lookup_instantiate_filp
    isofs: Remove global fs lock
    jffs2: fix IN_DELETE_SELF on overwriting rename() killing a directory
    fix IN_DELETE_SELF on overwriting rename() on ramfs et.al.
    mm/truncate.c: fix build for CONFIG_BLOCK not enabled
    fs:update the NOTE of the file_operations structure
    Remove dead code in dget_parent()
    AFS: Fix silly characters in a comment
    switch d_add_ci() to d_splice_alias() in "found negative" case as well
    simplify gfs2_lookup()
    jfs_lookup(): don't bother with . or ..
    get rid of useless dget_parent() in btrfs rename() and link()
    get rid of useless dget_parent() in fs/btrfs/ioctl.c
    fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
    drivers: fix up various ->llseek() implementations
    fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseek
    Ext4: handle SEEK_HOLE/SEEK_DATA generically
    Btrfs: implement our own ->llseek
    fs: add SEEK_HOLE and SEEK_DATA flags
    reiserfs: make reiserfs default to barrier=flush
    ...

    Fix up trivial conflicts in fs/xfs/linux-2.6/xfs_super.c due to the new
    shrinker callout for the inode cache, that clashed with the xfs code to
    start the periodic workers later.

    Linus Torvalds
     

22 Jul, 2011

1 commit

  • It seems to hurt performance in real life. Yes, the inode will be used
    later, but the conditional doesn't seem to predict all that well
    (negative dentries are not uncommon) and it looks like the cost of
    prefetching is simply higher than depending on the cache doing the right
    thing.

    As usual.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

21 Jul, 2011

3 commits

  • ->d_parent is never NULL...

    Signed-off-by: Al Viro

    Al Viro
     
  • Signed-off-by: Al Viro

    Al Viro
     
  • With context based shrinkers, we can implement a per-superblock
    shrinker that shrinks the caches attached to the superblock. We
    currently have global shrinkers for the inode and dentry caches that
    split up into per-superblock operations via a coarse proportioning
    method that does not batch very well. The global shrinkers also
    have a dependency - dentries pin inodes - so we have to be very
    careful about how we register the global shrinkers so that the
    implicit call order is always correct.

    With a per-sb shrinker callout, we can encode this dependency
    directly into the per-sb shrinker, hence avoiding the need for
    strictly ordering shrinker registrations. We also have no need for
    any proportioning code for the shrinker subsystem already provides
    this functionality across all shrinkers. Allowing the shrinker to
    operate on a single superblock at a time means that we do less
    superblock list traversals and locking and reclaim should batch more
    effectively. This should result in less CPU overhead for reclaim and
    potentially faster reclaim of items from each filesystem.

    Signed-off-by: Dave Chinner
    Signed-off-by: Al Viro

    Dave Chinner
     

20 Jul, 2011

3 commits

  • ... and simplify the living hell out of callers

    Signed-off-by: Al Viro

    Al Viro
     
  • New helper (non-exported, fs/internal.h-only): __d_alloc(sb, name).
    Allocates dentry, sets its ->d_sb to given superblock and sets
    ->d_op accordingly. Old d_alloc(NULL, name) callers are converted
    to that (all of them know what superblock they want). d_alloc()
    itself is left only for parent != NULl case; uses __d_alloc(),
    inserts result into the list of parent's children.

    Note that now ->d_sb is assign-once and never NULL *and*
    ->d_parent is never NULL either.

    Signed-off-by: Al Viro

    Al Viro
     
  • Btrfs (and I'd venture most other fs's) stores its indexes in nice disk order
    for readdir, but unfortunately in the case of anything that stats the files in
    order that readdir spits back (like oh say ls) that means we still have to do
    the normal lookup of the file, which means looking up our other index and then
    looking up the inode. What I want is a way to create dummy dentries when we
    find them in readdir so that when ls or anything else subsequently does a
    stat(), we already have the location information in the dentry and can go
    straight to the inode itself. The lookup stuff just assumes that if it finds a
    dentry it is done, it doesn't perform a lookup. So add a DCACHE_NEED_LOOKUP
    flag so that the lookup code knows it still needs to run i_op->lookup() on the
    parent to get the inode for the dentry. I have tested this with btrfs and I
    went from something that looks like this

    http://people.redhat.com/jwhiter/ls-noreada.png

    To this

    http://people.redhat.com/jwhiter/ls-good.png

    Thats a savings of 1300 seconds, or 22 minutes. That is a significant savings.
    Thanks,

    Signed-off-by: Josef Bacik
    Signed-off-by: Al Viro

    Josef Bacik
     

15 Jul, 2011

1 commit

  • Both __d_unalias() and __d_materialise_dentry() need loop prevention.
    Grab rename_lock in caller, check for loops there...

    As a side benefit, we have dentry_lock_for_move() called only under
    rename_lock, which seriously reduces deadlock potential of the
    execrable "locking order" used for ->d_lock.

    Signed-off-by: Al Viro

    Al Viro
     

25 May, 2011

1 commit

  • Change each shrinker's API by consolidating the existing parameters into
    shrink_control struct. This will simplify any further features added w/o
    touching each file of shrinker.

    [akpm@linux-foundation.org: fix build]
    [akpm@linux-foundation.org: fix warning]
    [kosaki.motohiro@jp.fujitsu.com: fix up new shrinker API]
    [akpm@linux-foundation.org: fix xfs warning]
    [akpm@linux-foundation.org: update gfs2]
    Signed-off-by: Ying Han
    Cc: KOSAKI Motohiro
    Cc: Minchan Kim
    Acked-by: Pavel Emelyanov
    Cc: KAMEZAWA Hiroyuki
    Cc: Mel Gorman
    Acked-by: Rik van Riel
    Cc: Johannes Weiner
    Cc: Hugh Dickins
    Cc: Dave Hansen
    Cc: Steven Whitehouse
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ying Han
     

21 May, 2011

1 commit

  • Commit e66eed651fd1 ("list: remove prefetching from regular list
    iterators") removed the include of prefetch.h from list.h, which
    uncovered several cases that had apparently relied on that rather
    obscure header file dependency.

    So this fixes things up a bit, using

    grep -L linux/prefetch.h $(git grep -l '[^a-z_]prefetchw*(' -- '*.[ch]')
    grep -L 'prefetchw*(' $(git grep -l 'linux/prefetch.h' -- '*.[ch]')

    to guide us in finding files that either need
    inclusion, or have it despite not needing it.

    There are more of them around (mostly network drivers), but this gets
    many core ones.

    Reported-by: Stephen Rothwell
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

26 Apr, 2011

1 commit

  • Now that the whole dcache_hash_bucket crap is gone, go all the way and
    also remove the weird locking layering violations for locking the hash
    buckets. Add hlist_bl_lock/unlock helpers to move the locking into the
    list abstraction instead of requiring each caller to open code it.
    After all allowing for the bit locks is the whole point of these helpers
    over the plain hlist variant.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Linus Torvalds

    Christoph Hellwig
     

24 Apr, 2011

2 commits

  • The dentry hashing rules have been really quite complicated for a long
    while, in odd ways. That made functions like __d_drop() very fragile
    and non-obvious.

    In particular, whether a dentry was hashed or not was indicated with an
    explicit DCACHE_UNHASHED bit. That's despite the fact that the hash
    abstraction that the dentries use actually have a 'is this entry hashed
    or not' model (which is a simple test of the 'pprev' pointer).

    The reason that was done is because we used the normal 'is this entry
    unhashed' model to mark whether the dentry had _ever_ been hashed in the
    dentry hash tables, and that logic goes back many years (commit
    b3423415fbc2: "dcache: avoid RCU for never-hashed dentries").

    That, in turn, meant that __d_drop had totally different unhashing logic
    for the dentry hash table case and for the anonymous dcache case,
    because in order to use the "is this dentry hashed" logic as a flag for
    whether it had ever been on the RCU hash table, we had to unhash such a
    dentry differently so that we'd never think that it wasn't 'unhashed'
    and wouldn't be free'd correctly.

    That's just insane. It made the logic really hard to follow, when there
    were two different kinds of "unhashed" states, and one of them (the one
    that used "list_bl_unhashed()") really had nothing at all to do with
    being unhashed per se, but with a very subtle lifetime rule instead.

    So turn all of it around, and make it logical.

    Instead of having a DENTRY_UNHASHED bit in d_flags to indicate whether
    the dentry is on the hash chains or not, use the hash chain unhashed
    logic for that. Suddenly "d_unhashed()" just uses "list_bl_unhashed()",
    and everything makes sense.

    And for the lifetime rule, just use an explicit DENTRY_RCUACCEES bit.
    If we ever insert the dentry into the dentry hash table so that it is
    visible to RCU lookup, we mark it DENTRY_RCUACCESS to show that it now
    needs the RCU lifetime rules. Now suddently that test at dentry free
    time makes sense too.

    And because unhashing now is sane and doesn't depend on where the dentry
    got unhashed from (because the dentry hash chain details doesn't have
    some subtle side effects), we can re-unify the __d_drop() logic and use
    common code for the unhashing.

    Also fix one more open-coded hash chain bit_spin_lock() that I missed in
    the previous chain locking cleanup commit.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • It's a useless abstraction for 'hlist_bl_head', and it doesn't actually
    help anything - quite the reverse. All the users end up having to know
    about the hlist_bl_head details anyway, using 'struct hlist_bl_node *'
    etc. So it just makes the code look confusing.

    And the cost of it is extra '&b->head' syntactic noise, but more
    importantly it spuriously makes the hash table dentry list look
    different from the per-superblock DCACHE_DISCONNECTED dentry list.

    As a result, the code ended up using ad-hoc locking for one case and
    special helper functions for what is really another totally identical
    case in the very same function.

    Make it all look and work the same.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

15 Apr, 2011

1 commit

  • The case we should be verifying when updating the dentry name is that
    the _parent_ inode (the directory) semaphore is held, not the semaphore
    for the dentry itself. It's the directory locking that rename and
    readdir() etc all care about.

    The comment just above even says so - but then the BUG_ON() still
    checked the dentry inode itself.

    Very few people noticed, because this helper function really isn't used
    for very much, so you had to be using ncpfs to ever hit it.

    I think I should just remove the BUG_ON (the function really has just
    one user), but let's run with it fixed for a while before getting rid of
    it entirely.

    Reported-and-tested-by: Bongani Hlope
    Reported-and-tested-by: Bernd Feige
    Cc: Petr Vandrovec ,
    Cc: Arnd Bergmann
    Cc: Christoph Hellwig
    Cc: Nick Piggin
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

19 Mar, 2011

2 commits

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
    fs: call security_d_instantiate in d_obtain_alias V2
    lose 'mounting_here' argument in ->d_manage()
    don't pass 'mounting_here' flag to follow_down()
    change the locking order for namespace_sem
    fix deadlock in pivot_root()
    vfs: split off vfsmount-related parts of vfs_kern_mount()
    Some fixes for pstore
    kill simple_set_mnt()

    Linus Torvalds
     
  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial: (47 commits)
    doc: CONFIG_UNEVICTABLE_LRU doesn't exist anymore
    Update cpuset info & webiste for cgroups
    dcdbas: force SMI to happen when expected
    arch/arm/Kconfig: remove one to many l's in the word.
    asm-generic/user.h: Fix spelling in comment
    drm: fix printk typo 'sracth'
    Remove one to many n's in a word
    Documentation/filesystems/romfs.txt: fixing link to genromfs
    drivers:scsi Change printk typo initate -> initiate
    serial, pch uart: Remove duplicate inclusion of linux/pci.h header
    fs/eventpoll.c: fix spelling
    mm: Fix out-of-date comments which refers non-existent functions
    drm: Fix printk typo 'failled'
    coh901318.c: Change initate to initiate.
    mbox-db5500.c Change initate to initiate.
    edac: correct i82975x error-info reported
    edac: correct i82975x mci initialisation
    edac: correct commented info
    fs: update comments to point correct document
    target: remove duplicate include of target/target_core_device.h from drivers/target/target_core_hba.c
    ...

    Trivial conflict in fs/eventpoll.c (spelling vs addition)

    Linus Torvalds
     

18 Mar, 2011

1 commit

  • While trying to track down some NFS problems with BTRFS, I kept noticing I was
    getting -EACCESS for no apparent reason. Eric Paris and printk() helped me
    figure out that it was SELinux that was giving me grief, with the following
    denial

    type=AVC msg=audit(1290013638.413:95): avc: denied { 0x800000 } for pid=1772
    comm="nfsd" name="" dev=sda1 ino=256 scontext=system_u:system_r:kernel_t:s0
    tcontext=system_u:object_r:unlabeled_t:s0 tclass=file

    Turns out this is because in d_obtain_alias if we can't find an alias we create
    one and do all the normal instantiation stuff, but we don't do the
    security_d_instantiate.

    Usually we are protected from getting a hashed dentry that hasn't yet run
    security_d_instantiate() by the parent's i_mutex, but obviously this isn't an
    option there, so in order to deal with the case that a second thread comes in
    and finds our new dentry before we get to run security_d_instantiate(), we go
    ahead and call it if we find a dentry already. Eric assures me that this is ok
    as the code checks to see if the dentry has been initialized already so calling
    security_d_instantiate() against the same dentry multiple times is ok. With
    this patch I'm no longer getting errant -EACCESS values.

    Signed-off-by: Josef Bacik
    Signed-off-by: Al Viro

    Josef Bacik
     

16 Mar, 2011

2 commits

  • The new vfs locking scheme introduced in 2.6.38 breaks NFS sillyrename
    because the latter relies on being able to determine the parent
    directory of the dentry in the ->iput() callback in order to send the
    appropriate unlink rpc call.

    Looking at the code that cares about races with dput(), there doesn't
    seem to be anything that specifically uses d_parent as a test for
    whether or not there is a race:
    - __d_lookup_rcu(), __d_lookup() all test for d_hashed() after d_parent
    - shrink_dcache_for_umount() is safe since nothing else can rearrange
    the dentries in that super block.
    - have_submount(), select_parent() and d_genocide() can test for a
    deletion if we set the DCACHE_DISCONNECTED flag when the dentry
    is removed from the parent's d_subdirs list.

    Signed-off-by: Trond Myklebust
    Cc: stable@kernel.org (2.6.38, needs commit c826cb7dfce8 "dcache.c:
    create helper function for duplicated functionality" )
    Signed-off-by: Linus Torvalds

    Trond Myklebust
     
  • This creates a helper function for he "try to ascend into the parent
    directory" case, which was written out in triplicate before. With all
    the locking and subtle sequence number stuff, we really don't want to
    duplicate that kind of code.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

10 Mar, 2011

1 commit

  • Without this patch, inodes are not promptly freed on last close of an
    unlinked file by an nfs client:

    client$ mount -tnfs4 server:/export/ /mnt/
    client$ tail -f /mnt/FOO
    ...
    server$ df -i /export
    server$ rm /export/FOO
    (^C the tail -f)
    server$ df -i /export
    server$ echo 2 >/proc/sys/vm/drop_caches
    server$ df -i /export

    the df's will show that the inode is not freed on the filesystem until
    the last step, when it could have been freed after killing the client's
    tail -f. On-disk data won't be deallocated either, leading to possible
    spurious ENOSPC.

    This occurs because when the client does the close, it arrives in a
    compound with a putfh and a close, processed like:

    - putfh: look up the filehandle.  The only alias found for the
    inode will be DCACHE_UNHASHED alias referenced by the filp
    this, so it creates a new DCACHE_DISCONECTED dentry and
    returns that instead.
    - close: closes the existing filp, which is destroyed
    immediately by dput() since it's DCACHE_UNHASHED.
    - end of the compound: release the reference
    to the current filehandle, and dput() the new
    DCACHE_DISCONECTED dentry, which gets put on the
    unused list instead of being destroyed immediately.

    Nick Piggin suggested fixing this by allowing d_obtain_alias to return
    the unhashed dentry that is referenced by the filp, instead of making it
    create a new dentry.

    Leave __d_find_alias() alone to avoid changing behavior of other
    callers.

    Also nfsd doesn't need all the checks of __d_find_alias(); any dentry,
    hashed or unhashed, disconnected or not, should work.

    Signed-off-by: J. Bruce Fields
    Signed-off-by: Al Viro

    J. Bruce Fields
     

17 Feb, 2011

1 commit


23 Jan, 2011

1 commit

  • Fix new fs/dcache.c kernel-doc warnings:

    Warning(fs/dcache.c:184): No description found for parameter 'dentry'
    Warning(fs/dcache.c:296): No description found for parameter 'parent'
    Warning(fs/dcache.c:1985): No description found for parameter 'dparent'
    Warning(fs/dcache.c:1985): Excess function parameter 'parent' description in 'd_validate'

    Signed-off-by: Randy Dunlap
    Cc: Alexander Viro
    Cc: Nick Piggin
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     

17 Jan, 2011

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (23 commits)
    sanitize vfsmount refcounting changes
    fix old umount_tree() breakage
    autofs4: Merge the remaining dentry ops tables
    Unexport do_add_mount() and add in follow_automount(), not ->d_automount()
    Allow d_manage() to be used in RCU-walk mode
    Remove a further kludge from __do_follow_link()
    autofs4: Bump version
    autofs4: Add v4 pseudo direct mount support
    autofs4: Fix wait validation
    autofs4: Clean up autofs4_free_ino()
    autofs4: Clean up dentry operations
    autofs4: Clean up inode operations
    autofs4: Remove unused code
    autofs4: Add d_manage() dentry operation
    autofs4: Add d_automount() dentry operation
    Remove the automount through follow_link() kludge code from pathwalk
    CIFS: Use d_automount() rather than abusing follow_link()
    NFS: Use d_automount() rather than abusing follow_link()
    AFS: Use d_automount() rather than abusing follow_link()
    Add an AT_NO_AUTOMOUNT flag to suppress terminal automount
    ...

    Linus Torvalds
     

16 Jan, 2011

1 commit

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

    David Howells
     

15 Jan, 2011

1 commit

  • It's indicative of a real problem, and it actually triggers with
    autofs4, but the BUG_ON() is excessive. The autofs4 case is being fixed
    (to only set d_op in the ->lookup method) but not merged yet. In the
    meantime this gets the code limping along.

    Reported-by: Alex Elder
    Cc: Ian Kent
    Cc: Nick Piggin
    Cc: Al Viro
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

13 Jan, 2011

3 commits


07 Jan, 2011

1 commit

  • The standard memcmp function on a Westmere system shows up hot in
    profiles in the `git diff` workload (both parallel and single threaded),
    and it is likely due to the costs associated with trapping into
    microcode, and little opportunity to improve memory access (dentry
    name is not likely to take up more than a cacheline).

    So replace it with an open-coded byte comparison. This increases code
    size by 8 bytes in the critical __d_lookup_rcu function, but the
    speedup is huge, averaging 10 runs of each:

    git diff st user sys elapsed CPU
    before 1.15 2.57 3.82 97.1
    after 1.14 2.35 3.61 96.8

    git diff mt user sys elapsed CPU
    before 1.27 3.85 1.46 349
    after 1.26 3.54 1.43 333

    Elapsed time for single threaded git diff at 95.0% confidence:
    -0.21 +/- 0.01
    -5.45% +/- 0.24%

    It's -0.66% +/- 0.06% elapsed time on my Opteron, so rep cmp costs on the
    fam10h seem to be relatively smaller, but there is still a win.

    Signed-off-by: Nick Piggin

    Nick Piggin