26 Feb, 2013

1 commit

  • The following set of operations on a NFS client and server will cause

    server# mkdir a
    client# cd a
    server# mv a a.bak
    client# sleep 30 # (or whatever the dir attrcache timeout is)
    client# stat .
    stat: cannot stat `.': Stale NFS file handle

    Obviously, we should not be getting an ESTALE error back there since the
    inode still exists on the server. The problem is that the lookup code
    will call d_revalidate on the dentry that "." refers to, because NFS has
    FS_REVAL_DOT set.

    nfs_lookup_revalidate will see that the parent directory has changed and
    will try to reverify the dentry by redoing a LOOKUP. That of course
    fails, so the lookup code returns ESTALE.

    The problem here is that d_revalidate is really a bad fit for this case.
    What we really want to know at this point is whether the inode is still
    good or not, but we don't really care what name it goes by or whether
    the dcache is still valid.

    Add a new d_op->d_weak_revalidate operation and have complete_walk call
    that instead of d_revalidate. The intent there is to allow for a
    "weaker" d_revalidate that just checks to see whether the inode is still
    good. This is also gives us an opportunity to kill off the FS_REVAL_DOT
    special casing.

    [AV: changed method name, added note in porting, fixed confusion re
    having it possibly called from RCU mode (it won't be)]

    Cc: NeilBrown
    Signed-off-by: Jeff Layton
    Signed-off-by: Al Viro

    Jeff Layton
     

21 Dec, 2012

1 commit


04 Aug, 2012

1 commit


01 Aug, 2012

1 commit

  • Currently swapfiles are managed entirely by the core VM by using ->bmap to
    allocate space and write to the blocks directly. This effectively ensures
    that the underlying blocks are allocated and avoids the need for the swap
    subsystem to locate what physical blocks store offsets within a file.

    If the swap subsystem is to use the filesystem information to locate the
    blocks, it is critical that information such as block groups, block
    bitmaps and the block descriptor table that map the swap file were
    resident in memory. This patch adds address_space_operations that the VM
    can call when activating or deactivating swap backed by a file.

    int swap_activate(struct file *);
    int swap_deactivate(struct file *);

    The ->swap_activate() method is used to communicate to the file that the
    VM relies on it, and the address_space should take adequate measures such
    as reserving space in the underlying device, reserving memory for mempools
    and pinning information such as the block descriptor table in memory. The
    ->swap_deactivate() method is called on sys_swapoff() if ->swap_activate()
    returned success.

    After a successful swapfile ->swap_activate, the swapfile is marked
    SWP_FILE and swapper_space.a_ops will proxy to
    sis->swap_file->f_mappings->a_ops using ->direct_io to write swapcache
    pages and ->readpage to read.

    It is perfectly possible that direct_IO be used to read the swap pages but
    it is an unnecessary complication. Similarly, it is possible that
    ->writepage be used instead of direct_io to write the pages but filesystem
    developers have stated that calling writepage from the VM is undesirable
    for a variety of reasons and using direct_IO opens up the possibility of
    writing back batches of swap pages in the future.

    [a.p.zijlstra@chello.nl: Original patch]
    Signed-off-by: Mel Gorman
    Acked-by: Rik van Riel
    Cc: Christoph Hellwig
    Cc: David S. Miller
    Cc: Eric B Munson
    Cc: Eric Paris
    Cc: James Morris
    Cc: Mel Gorman
    Cc: Mike Christie
    Cc: Neil Brown
    Cc: Peter Zijlstra
    Cc: Sebastian Andrzej Siewior
    Cc: Trond Myklebust
    Cc: Xiaotian Feng
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mel Gorman
     

14 Jul, 2012

7 commits

  • boolean "does it have to be exclusive?" flag is passed instead;
    Local filesystem should just ignore it - the object is guaranteed
    not to be there yet.

    Signed-off-by: Al Viro

    Al Viro
     
  • Just the flags; only NFS cares even about that, but there are
    legitimate uses for such argument. And getting rid of that
    completely would require splitting ->lookup() into a couple
    of methods (at least), so let's leave that alone for now...

    Signed-off-by: Al Viro

    Al Viro
     
  • Just the lookup flags. Die, bastard, die...

    Signed-off-by: Al Viro

    Al Viro
     
  • Just pass struct file *. Methods are happier that way...
    There's no need to return struct file * from finish_open() now,
    so let it return int. Next: saner prototypes for parts in
    namei.c

    Signed-off-by: Al Viro

    Al Viro
     
  • Change of calling conventions:
    old new
    NULL 1
    file 0
    ERR_PTR(-ve) -ve

    Caller *knows* that struct file *; no need to return it.

    Signed-off-by: Al Viro

    Al Viro
     
  • ... and let finish_open() report having opened the file via that sucker.
    Next step: don't modify od->filp at all.

    [AV: FILE_CREATE was already used by cifs; Miklos' fix folded]

    Signed-off-by: Al Viro

    Al Viro
     
  • Add a new inode operation which is called on the last component of an open.
    Using this the filesystem can look up, possibly create and open the file in one
    atomic operation. If it cannot perform this (e.g. the file type turned out to
    be wrong) it may signal this by returning NULL instead of an open struct file
    pointer.

    i_op->atomic_open() is only called if the last component is negative or needs
    lookup. Handling cached positive dentries here doesn't add much value: these
    can be opened using f_op->open(). If the cached file turns out to be invalid,
    the open can be retried, this time using ->atomic_open() with a fresh dentry.

    For now leave the old way of using open intents in lookup and revalidate in
    place. This will be removed once all the users are converted.

    David Howells noticed that if ->atomic_open() opens the file but does not create
    it, handle_truncate() will be called on it even if it is not a regular file.
    Fix this by checking the file type in this case too.

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Al Viro

    Miklos Szeredi
     

02 Jun, 2012

2 commits

  • Pull vfs changes from Al Viro.
    "A lot of misc stuff. The obvious groups:
    * Miklos' atomic_open series; kills the damn abuse of
    ->d_revalidate() by NFS, which was the major stumbling block for
    all work in that area.
    * ripping security_file_mmap() and dealing with deadlocks in the
    area; sanitizing the neighborhood of vm_mmap()/vm_munmap() in
    general.
    * ->encode_fh() switched to saner API; insane fake dentry in
    mm/cleancache.c gone.
    * assorted annotations in fs (endianness, __user)
    * parts of Artem's ->s_dirty work (jff2 and reiserfs parts)
    * ->update_time() work from Josef.
    * other bits and pieces all over the place.

    Normally it would've been in two or three pull requests, but
    signal.git stuff had eaten a lot of time during this cycle ;-/"

    Fix up trivial conflicts in Documentation/filesystems/vfs.txt (the
    'truncate_range' inode method was removed by the VM changes, the VFS
    update adds an 'update_time()' method), and in fs/btrfs/ulist.[ch] (due
    to sparse fix added twice, with other changes nearby).

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (95 commits)
    nfs: don't open in ->d_revalidate
    vfs: retry last component if opening stale dentry
    vfs: nameidata_to_filp(): don't throw away file on error
    vfs: nameidata_to_filp(): inline __dentry_open()
    vfs: do_dentry_open(): don't put filp
    vfs: split __dentry_open()
    vfs: do_last() common post lookup
    vfs: do_last(): add audit_inode before open
    vfs: do_last(): only return EISDIR for O_CREAT
    vfs: do_last(): check LOOKUP_DIRECTORY
    vfs: do_last(): make ENOENT exit RCU safe
    vfs: make follow_link check RCU safe
    vfs: do_last(): use inode variable
    vfs: do_last(): inline walk_component()
    vfs: do_last(): make exit RCU safe
    vfs: split do_lookup()
    Btrfs: move over to use ->update_time
    fs: introduce inode operation ->update_time
    reiserfs: get rid of resierfs_sync_super
    reiserfs: mark the superblock as dirty a bit later
    ...

    Linus Torvalds
     
  • Btrfs has to make sure we have space to allocate new blocks in order to modify
    the inode, so updating time can fail. We've gotten around this by having our
    own file_update_time but this is kind of a pain, and Christoph has indicated he
    would like to make xfs do something different with atime updates. So introduce
    ->update_time, where we will deal with i_version an a/m/c time updates and
    indicate which changes need to be made. The normal version just does what it
    has always done, updates the time and marks the inode dirty, and then
    filesystems can choose to do something different.

    I've gone through all of the users of file_update_time and made them check for
    errors with the exception of the fault code since it's complicated and I wasn't
    quite sure what to do there, also Jan is going to be pushing the file time
    updates into page_mkwrite for those who have it so that should satisfy btrfs and
    make it not a big deal to check the file_update_time() return code in the
    generic fault path. Thanks,

    Signed-off-by: Josef Bacik

    Josef Bacik
     

30 May, 2012

1 commit

  • Remove vmtruncate_range(), and remove the truncate_range method from
    struct inode_operations: only tmpfs ever supported it, and tmpfs has now
    converted over to using the fallocate method of file_operations.

    Update Documentation accordingly, adding (setlease and) fallocate lines.
    And while we're in mm.h, remove duplicate declarations of shmem_lock() and
    shmem_file_setup(): everyone is now using the ones in shmem_fs.h.

    Based-on-patch-by: Cong Wang
    Signed-off-by: Hugh Dickins
    Cc: Christoph Hellwig
    Cc: Cong Wang
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hugh Dickins
     

09 Apr, 2012

1 commit


07 Mar, 2012

1 commit


07 Jan, 2012

1 commit


04 Jan, 2012

3 commits


28 Sep, 2011

1 commit

  • There are numerous broken references to Documentation files (in other
    Documentation files, in comments, etc.). These broken references are
    caused by typo's in the references, and by renames or removals of the
    Documentation files. Some broken references are simply odd.

    Fix these broken references, sometimes by dropping the irrelevant text
    they were part of.

    Signed-off-by: Paul Bolle
    Signed-off-by: Jiri Kosina

    Paul Bolle
     

26 Jul, 2011

1 commit

  • Replace the ->check_acl method with a ->get_acl method that simply reads an
    ACL from disk after having a cache miss. This means we can replace the ACL
    checking boilerplate code with a single implementation in namei.c.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Al Viro

    Christoph Hellwig
     

21 Jul, 2011

3 commits

  • Btrfs needs to be able to control how filemap_write_and_wait_range() is called
    in fsync to make it less of a painful operation, so push down taking i_mutex and
    the calling of filemap_write_and_wait() down into the ->fsync() handlers. Some
    file systems can drop taking the i_mutex altogether it seems, like ext3 and
    ocfs2. For correctness sake I just pushed everything down in all cases to make
    sure that we keep the current behavior the same for everybody, and then each
    individual fs maintainer can make up their mind about what to do from there.
    Thanks,

    Acked-by: Jan Kara
    Signed-off-by: Josef Bacik
    Signed-off-by: Al Viro

    Josef Bacik
     
  • Now that the per-sb shrinker is responsible for shrinking 2 or more
    caches, increase the batch size to keep econmies of scale for
    shrinking each cache. Increase the shrinker batch size to 1024
    objects.

    To allow for a large increase in batch size, add a conditional
    reschedule to prune_icache_sb() so that we don't hold the LRU spin
    lock for too long. This mirrors the behaviour of the
    __shrink_dcache_sb(), and allows us to increase the batch size
    without needing to worry about problems caused by long lock hold
    times.

    To ensure that filesystems using the per-sb shrinker callouts don't
    cause problems, document that the object freeing method must
    reschedule appropriately inside loops.

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

    Dave Chinner
     
  • Now we have a per-superblock shrinker implementation, we can add a
    filesystem specific callout to it to allow filesystem internal
    caches to be shrunk by the superblock shrinker.

    Rather than perpetuate the multipurpose shrinker callback API (i.e.
    nr_to_scan == 0 meaning "tell me how many objects freeable in the
    cache), two operations will be added. The first will return the
    number of objects that are freeable, the second is the actual
    shrinker call.

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

    Dave Chinner
     

20 Jul, 2011

2 commits


27 May, 2011

1 commit

  • Tell the filesystem if we just updated timestamp (I_DIRTY_SYNC) or
    anything else, so that the filesystem can track internally if it
    needs to push out a transaction for fdatasync or not.

    This is just the prototype change with no user for it yet. I plan
    to push large XFS changes for the next merge window, and getting
    this trivial infrastructure in this window would help a lot to avoid
    tree interdependencies.

    Also remove incorrect comments that ->dirty_inode can't block. That
    has been changed a long time ago, and many implementations rely on it.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Al Viro

    Christoph Hellwig
     

31 Mar, 2011

1 commit


25 Mar, 2011

1 commit

  • Now that inode state changes are protected by the inode->i_lock and
    the inode LRU manipulations by the inode_lru_lock, we can remove the
    inode_lock from prune_icache and the initial part of iput_final().

    instead of using the inode_lock to protect the inode during
    iput_final, use the inode->i_lock instead. This protects the inode
    against new references being taken while we change the inode state
    to I_FREEING, as well as preventing prune_icache from grabbing the
    inode while we are manipulating it. Hence we no longer need the
    inode_lock in iput_final prior to setting I_FREEING on the inode.

    For prune_icache, we no longer need the inode_lock to protect the
    LRU list, and the inodes themselves are protected against freeing
    races by the inode->i_lock. Hence we can lift the inode_lock from
    prune_icache as well.

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

    Dave Chinner
     

18 Mar, 2011

1 commit


17 Mar, 2011

1 commit


16 Jan, 2011

4 commits

  • Unexport do_add_mount() and make ->d_automount() return the vfsmount to be
    added rather than calling do_add_mount() itself. follow_automount() will then
    do the addition.

    This slightly complicates things as ->d_automount() normally wants to add the
    new vfsmount to an expiration list and start an expiration timer. The problem
    with that is that the vfsmount will be deleted if it has a refcount of 1 and
    the timer will not repeat if the expiration list is empty.

    To this end, we require the vfsmount to be returned from d_automount() with a
    refcount of (at least) 2. One of these refs will be dropped unconditionally.
    In addition, follow_automount() must get a 3rd ref around the call to
    do_add_mount() lest it eat a ref and return an error, leaving the mount we
    have open to being expired as we would otherwise have only 1 ref on it.

    d_automount() should also add the the vfsmount to the expiration list (by
    calling mnt_set_expiry()) and start the expiration timer before returning, if
    this mechanism is to be used. The vfsmount will be unlinked from the
    expiration list by follow_automount() if do_add_mount() fails.

    This patch also fixes the call to do_add_mount() for AFS to propagate the mount
    flags from the parent vfsmount.

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

    David Howells
     
  • Allow d_manage() to be called from pathwalk when it is in RCU-walk mode as well
    as when it is in Ref-walk mode. This permits __follow_mount_rcu() to call
    d_manage() directly. d_manage() needs a parameter to indicate that it is in
    RCU-walk mode as it isn't allowed to sleep if in that mode (but should return
    -ECHILD instead).

    autofs4_d_manage() can then be set to retain RCU-walk mode if the daemon
    accesses it and otherwise request dropping back to ref-walk mode.

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

    David Howells
     
  • 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
     
  • 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
     

14 Jan, 2011

1 commit


07 Jan, 2011

3 commits