Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 01:11:47 +0000 (17:11 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 01:11:47 +0000 (17:11 -0800)
Pull misc vfs updates from Al Viro:
 "All kinds of stuff.  That probably should've been 5 or 6 separate
  branches, but by the time I'd realized how large and mixed that bag
  had become it had been too close to -final to play with rebasing.

  Some fs/namei.c cleanups there, memdup_user_nul() introduction and
  switching open-coded instances, burying long-dead code, whack-a-mole
  of various kinds, several new helpers for ->llseek(), assorted
  cleanups and fixes from various people, etc.

  One piece probably deserves special mention - Neil's
  lookup_one_len_unlocked().  Similar to lookup_one_len(), but gets
  called without ->i_mutex and tries to avoid ever taking it.  That, of
  course, means that it's not useful for any directory modifications,
  but things like getting inode attributes in nfds readdirplus are fine
  with that.  I really should've asked for moratorium on lookup-related
  changes this cycle, but since I hadn't done that early enough...  I
  *am* asking for that for the coming cycle, though - I'm going to try
  and get conversion of i_mutex to rwsem with ->lookup() done under lock
  taken shared.

  There will be a patch closer to the end of the window, along the lines
  of the one Linus had posted last May - mechanical conversion of
  ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/
  inode_is_locked()/inode_lock_nested().  To quote Linus back then:

    -----
    |    This is an automated patch using
    |
    |        sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/'
    |        sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/'
    |        sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[     ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/'
    |        sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/'
    |        sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/'
    |
    |    with a very few manual fixups
    -----

  I'm going to send that once the ->i_mutex-affecting stuff in -next
  gets mostly merged (or when Linus says he's about to stop taking
  merges)"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
  nfsd: don't hold i_mutex over userspace upcalls
  fs:affs:Replace time_t with time64_t
  fs/9p: use fscache mutex rather than spinlock
  proc: add a reschedule point in proc_readfd_common()
  logfs: constify logfs_block_ops structures
  fcntl: allow to set O_DIRECT flag on pipe
  fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE
  fs: xattr: Use kvfree()
  [s390] page_to_phys() always returns a multiple of PAGE_SIZE
  nbd: use ->compat_ioctl()
  fs: use block_device name vsprintf helper
  lib/vsprintf: add %*pg format specifier
  fs: use gendisk->disk_name where possible
  poll: plug an unused argument to do_poll
  amdkfd: don't open-code memdup_user()
  cdrom: don't open-code memdup_user()
  rsxx: don't open-code memdup_user()
  mtip32xx: don't open-code memdup_user()
  [um] mconsole: don't open-code memdup_user_nul()
  [um] hostaudio: don't open-code memdup_user()
  ...

17 files changed:
1  2 
drivers/md/dm-bufio.c
drivers/staging/lustre/lustre/llite/symlink.c
fs/9p/vfs_inode.c
fs/compat_ioctl.c
fs/dcache.c
fs/ecryptfs/inode.c
fs/ext2/xattr.c
fs/ext4/xattr.c
fs/logfs/logfs.h
fs/namei.c
fs/namespace.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
fs/proc/base.c
fs/read_write.c
fs/xattr.c
include/linux/fs.h

Simple merge
index e489a3271f0697fe8a9f35708434412072a3f2a1,32c4cf48b318398cbd58fa32c48e309877a8661f..2610348f6c7268eb3cc7195137c57a82206f65ee
@@@ -149,10 -141,16 +149,10 @@@ static const char *ll_get_link(struct d
        return symname;
  }
  
- struct inode_operations ll_fast_symlink_inode_operations = {
 -static void ll_put_link(struct inode *unused, void *cookie)
 -{
 -      ptlrpc_req_finished(cookie);
 -}
 -
+ const struct inode_operations ll_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .setattr        = ll_setattr,
 -      .follow_link    = ll_follow_link,
 -      .put_link       = ll_put_link,
 +      .get_link       = ll_get_link,
        .getattr        = ll_getattr,
        .permission     = ll_inode_permission,
        .setxattr       = ll_setxattr,
Simple merge
Simple merge
diff --cc fs/dcache.c
Simple merge
Simple merge
diff --cc fs/ext2/xattr.c
Simple merge
diff --cc fs/ext4/xattr.c
Simple merge
Simple merge
diff --cc fs/namei.c
index 3c909aebef70f8a8a091960bd3ba434a15e2f829,1067f7a0287ab105a30fbbcb353af74b4d8f9eb2..bceefd5588a2bf908626a0a6282a5f810ecfc5c1
@@@ -838,8 -839,28 +836,28 @@@ static inline void path_to_nameidata(co
        nd->path.dentry = path->dentry;
  }
  
+ static int nd_jump_root(struct nameidata *nd)
+ {
+       if (nd->flags & LOOKUP_RCU) {
+               struct dentry *d;
+               nd->path = nd->root;
+               d = nd->path.dentry;
+               nd->inode = d->d_inode;
+               nd->seq = nd->root_seq;
+               if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
+                       return -ECHILD;
+       } else {
+               path_put(&nd->path);
+               nd->path = nd->root;
+               path_get(&nd->path);
+               nd->inode = nd->path.dentry->d_inode;
+       }
+       nd->flags |= LOOKUP_JUMPED;
+       return 0;
+ }
  /*
 - * Helper to directly jump to a known parsed path from ->follow_link,
 + * Helper to directly jump to a known parsed path from ->get_link,
   * caller must have taken a reference to path beforehand.
   */
  void nd_jump_link(struct path *path)
@@@ -999,42 -1022,21 +1017,27 @@@ const char *get_link(struct nameidata *
        nd->last_type = LAST_BIND;
        res = inode->i_link;
        if (!res) {
 +              const char * (*get)(struct dentry *, struct inode *,
 +                              struct delayed_call *);
 +              get = inode->i_op->get_link;
                if (nd->flags & LOOKUP_RCU) {
 -                      if (unlikely(unlazy_walk(nd, NULL, 0)))
 -                              return ERR_PTR(-ECHILD);
 +                      res = get(NULL, inode, &last->done);
 +                      if (res == ERR_PTR(-ECHILD)) {
 +                              if (unlikely(unlazy_walk(nd, NULL, 0)))
 +                                      return ERR_PTR(-ECHILD);
 +                              res = get(dentry, inode, &last->done);
 +                      }
 +              } else {
 +                      res = get(dentry, inode, &last->done);
                }
 -              res = inode->i_op->follow_link(dentry, &last->cookie);
 -              if (IS_ERR_OR_NULL(res)) {
 -                      last->cookie = NULL;
 +              if (IS_ERR_OR_NULL(res))
                        return res;
 -              }
        }
        if (*res == '/') {
-               if (nd->flags & LOOKUP_RCU) {
-                       struct dentry *d;
-                       if (!nd->root.mnt)
-                               set_root_rcu(nd);
-                       nd->path = nd->root;
-                       d = nd->path.dentry;
-                       nd->inode = d->d_inode;
-                       nd->seq = nd->root_seq;
-                       if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
-                               return ERR_PTR(-ECHILD);
-               } else {
-                       if (!nd->root.mnt)
-                               set_root(nd);
-                       path_put(&nd->path);
-                       nd->path = nd->root;
-                       path_get(&nd->root);
-                       nd->inode = nd->path.dentry->d_inode;
-               }
-               nd->flags |= LOOKUP_JUMPED;
+               if (!nd->root.mnt)
+                       set_root(nd);
+               if (unlikely(nd_jump_root(nd)))
+                       return ERR_PTR(-ECHILD);
                while (unlikely(*++res == '/'))
                        ;
        }
diff --cc fs/namespace.c
Simple merge
Simple merge
diff --cc fs/nfsd/vfs.c
Simple merge
diff --cc fs/proc/base.c
Simple merge
diff --cc fs/read_write.c
Simple merge
diff --cc fs/xattr.c
Simple merge
Simple merge