Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Oct 2016 20:04:49 +0000 (13:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Oct 2016 20:04:49 +0000 (13:04 -0700)
Pull misc vfs updates from Al Viro:
 "Assorted misc bits and pieces.

  There are several single-topic branches left after this (rename2
  series from Miklos, current_time series from Deepa Dinamani, xattr
  series from Andreas, uaccess stuff from from me) and I'd prefer to
  send those separately"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (39 commits)
  proc: switch auxv to use of __mem_open()
  hpfs: support FIEMAP
  cifs: get rid of unused arguments of CIFSSMBWrite()
  posix_acl: uapi header split
  posix_acl: xattr representation cleanups
  fs/aio.c: eliminate redundant loads in put_aio_ring_file
  fs/internal.h: add const to ns_dentry_operations declaration
  compat: remove compat_printk()
  fs/buffer.c: make __getblk_slow() static
  proc: unsigned file descriptors
  fs/file: more unsigned file descriptors
  fs: compat: remove redundant check of nr_segs
  cachefiles: Fix attempt to read i_blocks after deleting file [ver #2]
  cifs: don't use memcpy() to copy struct iov_iter
  get rid of separate multipage fault-in primitives
  fs: Avoid premature clearing of capabilities
  fs: Give dentry to inode_change_ok() instead of inode
  fuse: Propagate dentry down to inode_change_ok()
  ceph: Propagate dentry down to inode_change_ok()
  xfs: Propagate dentry down to inode_change_ok()
  ...

35 files changed:
1  2 
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/ptlrpc/wiretest.c
fs/btrfs/inode.c
fs/ext2/inode.c
fs/ext4/inode.c
fs/f2fs/acl.c
fs/f2fs/file.c
fs/f2fs/node.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/gfs2/inode.c
fs/hugetlbfs/inode.c
fs/internal.h
fs/locks.c
fs/namespace.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/file.c
fs/orangefs/file.c
fs/orangefs/namei.c
fs/orangefs/orangefs-debugfs.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/proc_sysctl.c
fs/xfs/xfs_file.c
include/linux/fs.h
include/linux/pagemap.h
include/linux/uio.h
include/uapi/linux/Kbuild
kernel/sysctl.c
lib/iov_iter.c
mm/shmem.c

@@@ -1121,8 -1141,8 +1121,8 @@@ ll_file_io_generic(const struct lu_env 
        struct cl_io     *io;
        ssize_t        result;
  
-       CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zu\n",
-              file->f_path.dentry->d_name.name, iot, *ppos, count);
 -      CDEBUG(D_VFSTRACE, "file: %pD, type: %d ppos: %llu, count: %zd\n",
++      CDEBUG(D_VFSTRACE, "file: %pD, type: %d ppos: %llu, count: %zu\n",
+              file, iot, *ppos, count);
  
  restart:
        io = vvp_env_thread_io(env);
Simple merge
diff --cc fs/ext2/inode.c
Simple merge
diff --cc fs/ext4/inode.c
Simple merge
diff --cc fs/f2fs/acl.c
Simple merge
diff --cc fs/f2fs/file.c
Simple merge
diff --cc fs/f2fs/node.c
Simple merge
diff --cc fs/fuse/dir.c
@@@ -1618,10 -1606,10 +1619,10 @@@ int fuse_do_setattr(struct dentry *dent
        int err;
        bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
  
 -      if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
 +      if (!fc->default_permissions)
                attr->ia_valid |= ATTR_FORCE;
  
-       err = inode_change_ok(inode, attr);
+       err = setattr_prepare(dentry, attr);
        if (err)
                return err;
  
@@@ -1715,61 -1703,101 +1716,61 @@@ error
  static int fuse_setattr(struct dentry *entry, struct iattr *attr)
  {
        struct inode *inode = d_inode(entry);
 -
 -      if (!fuse_allow_current_process(get_fuse_conn(inode)))
 -              return -EACCES;
 -
 -      if (attr->ia_valid & ATTR_FILE)
 -              return fuse_do_setattr(entry, attr, attr->ia_file);
 -      else
 -              return fuse_do_setattr(entry, attr, NULL);
 -}
 -
 -static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
 -                      struct kstat *stat)
 -{
 -      struct inode *inode = d_inode(entry);
        struct fuse_conn *fc = get_fuse_conn(inode);
 +      struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
 +      int ret;
  
 -      if (!fuse_allow_current_process(fc))
 +      if (!fuse_allow_current_process(get_fuse_conn(inode)))
                return -EACCES;
  
 -      return fuse_update_attributes(inode, stat, NULL, NULL);
 -}
 -
 -static int fuse_setxattr(struct dentry *unused, struct inode *inode,
 -                       const char *name, const void *value,
 -                       size_t size, int flags)
 -{
 -      struct fuse_conn *fc = get_fuse_conn(inode);
 -      FUSE_ARGS(args);
 -      struct fuse_setxattr_in inarg;
 -      int err;
 -
 -      if (fc->no_setxattr)
 -              return -EOPNOTSUPP;
 +      if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
 +              attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
 +                                  ATTR_MODE);
  
 -      memset(&inarg, 0, sizeof(inarg));
 -      inarg.size = size;
 -      inarg.flags = flags;
 -      args.in.h.opcode = FUSE_SETXATTR;
 -      args.in.h.nodeid = get_node_id(inode);
 -      args.in.numargs = 3;
 -      args.in.args[0].size = sizeof(inarg);
 -      args.in.args[0].value = &inarg;
 -      args.in.args[1].size = strlen(name) + 1;
 -      args.in.args[1].value = name;
 -      args.in.args[2].size = size;
 -      args.in.args[2].value = value;
 -      err = fuse_simple_request(fc, &args);
 -      if (err == -ENOSYS) {
 -              fc->no_setxattr = 1;
 -              err = -EOPNOTSUPP;
 -      }
 -      if (!err) {
 -              fuse_invalidate_attr(inode);
 -              fuse_update_ctime(inode);
 +              /*
 +               * The only sane way to reliably kill suid/sgid is to do it in
 +               * the userspace filesystem
 +               *
 +               * This should be done on write(), truncate() and chown().
 +               */
 +              if (!fc->handle_killpriv) {
 +                      int kill;
 +
 +                      /*
 +                       * ia_mode calculation may have used stale i_mode.
 +                       * Refresh and recalculate.
 +                       */
 +                      ret = fuse_do_getattr(inode, NULL, file);
 +                      if (ret)
 +                              return ret;
 +
 +                      attr->ia_mode = inode->i_mode;
 +                      kill = should_remove_suid(entry);
 +                      if (kill & ATTR_KILL_SUID) {
 +                              attr->ia_valid |= ATTR_MODE;
 +                              attr->ia_mode &= ~S_ISUID;
 +                      }
 +                      if (kill & ATTR_KILL_SGID) {
 +                              attr->ia_valid |= ATTR_MODE;
 +                              attr->ia_mode &= ~S_ISGID;
 +                      }
 +              }
        }
 -      return err;
 -}
 -
 -static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
 -                           const char *name, void *value, size_t size)
 -{
 -      struct fuse_conn *fc = get_fuse_conn(inode);
 -      FUSE_ARGS(args);
 -      struct fuse_getxattr_in inarg;
 -      struct fuse_getxattr_out outarg;
 -      ssize_t ret;
 +      if (!attr->ia_valid)
 +              return 0;
  
-       ret = fuse_do_setattr(inode, attr, file);
 -      if (fc->no_getxattr)
 -              return -EOPNOTSUPP;
++      ret = fuse_do_setattr(entry, attr, file);
 +      if (!ret) {
 +              /*
 +               * If filesystem supports acls it may have updated acl xattrs in
 +               * the filesystem, so forget cached acls for the inode.
 +               */
 +              if (fc->posix_acl)
 +                      forget_all_cached_acls(inode);
  
 -      memset(&inarg, 0, sizeof(inarg));
 -      inarg.size = size;
 -      args.in.h.opcode = FUSE_GETXATTR;
 -      args.in.h.nodeid = get_node_id(inode);
 -      args.in.numargs = 2;
 -      args.in.args[0].size = sizeof(inarg);
 -      args.in.args[0].value = &inarg;
 -      args.in.args[1].size = strlen(name) + 1;
 -      args.in.args[1].value = name;
 -      /* This is really two different operations rolled into one */
 -      args.out.numargs = 1;
 -      if (size) {
 -              args.out.argvar = 1;
 -              args.out.args[0].size = size;
 -              args.out.args[0].value = value;
 -      } else {
 -              args.out.args[0].size = sizeof(outarg);
 -              args.out.args[0].value = &outarg;
 -      }
 -      ret = fuse_simple_request(fc, &args);
 -      if (!ret && !size)
 -              ret = outarg.size;
 -      if (ret == -ENOSYS) {
 -              fc->no_getxattr = 1;
 -              ret = -EOPNOTSUPP;
 +              /* Directory mode changed, may need to revalidate access */
 +              if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
 +                      fuse_invalidate_entry_cache(entry);
        }
        return ret;
  }
diff --cc fs/fuse/file.c
Simple merge
Simple merge
diff --cc fs/gfs2/inode.c
Simple merge
Simple merge
diff --cc fs/internal.h
Simple merge
diff --cc fs/locks.c
Simple merge
diff --cc fs/namespace.c
Simple merge
Simple merge
diff --cc fs/ocfs2/file.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc fs/proc/base.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/sysctl.c
Simple merge
diff --cc lib/iov_iter.c
Simple merge
diff --cc mm/shmem.c
Simple merge