OSDN Git Service

Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Apr 2018 18:07:08 +0000 (11:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 6 Apr 2018 18:07:08 +0000 (11:07 -0700)
Pull misc vfs updates from Al Viro:
 "Assorted stuff, including Christoph's I_DIRTY patches"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs: move I_DIRTY_INODE to fs.h
  ubifs: fix bogus __mark_inode_dirty(I_DIRTY_SYNC | I_DIRTY_DATASYNC) call
  ntfs: fix bogus __mark_inode_dirty(I_DIRTY_SYNC | I_DIRTY_DATASYNC) call
  gfs2: fix bogus __mark_inode_dirty(I_DIRTY_SYNC | I_DIRTY_DATASYNC) calls
  fs: fold open_check_o_direct into do_dentry_open
  vfs: Replace stray non-ASCII homoglyph characters with their ASCII equivalents
  vfs: make sure struct filename->iname is word-aligned
  get rid of pointless includes of fs_struct.h
  [poll] annotate SAA6588_CMD_POLL users

1  2 
drivers/media/pci/saa7134/saa7134-video.c
fs/ceph/dir.c
fs/ext4/inode.c
fs/internal.h
fs/namei.c
fs/open.c
fs/xfs/xfs_aops.c
include/linux/fs.h

@@@ -1200,7 -1200,7 +1200,7 @@@ static int video_release(struct file *f
        saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
        saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
  
 -      saa_call_all(dev, core, s_power, 0);
 +      saa_call_all(dev, tuner, standby);
        if (vdev->vfl_type == VFL_TYPE_RADIO)
                saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
        mutex_unlock(&dev->lock);
@@@ -1235,12 -1235,12 +1235,12 @@@ static __poll_t radio_poll(struct file 
  
        cmd.instance = file;
        cmd.event_list = wait;
-       cmd.result = 0;
+       cmd.poll_mask = 0;
        mutex_lock(&dev->lock);
        saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
        mutex_unlock(&dev->lock);
  
-       return rc | cmd.result;
+       return rc | cmd.poll_mask;
  }
  
  /* ------------------------------------------------------------------ */
diff --combined fs/ceph/dir.c
@@@ -2,7 -2,6 +2,6 @@@
  #include <linux/ceph/ceph_debug.h>
  
  #include <linux/spinlock.h>
- #include <linux/fs_struct.h>
  #include <linux/namei.h>
  #include <linux/slab.h>
  #include <linux/sched.h>
@@@ -1003,6 -1002,26 +1002,6 @@@ static int ceph_link(struct dentry *old
  }
  
  /*
 - * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps.  If it
 - * looks like the link count will hit 0, drop any other caps (other
 - * than PIN) we don't specifically want (due to the file still being
 - * open).
 - */
 -static int drop_caps_for_unlink(struct inode *inode)
 -{
 -      struct ceph_inode_info *ci = ceph_inode(inode);
 -      int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
 -
 -      spin_lock(&ci->i_ceph_lock);
 -      if (inode->i_nlink == 1) {
 -              drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
 -              ci->i_ceph_flags |= CEPH_I_NODELAY;
 -      }
 -      spin_unlock(&ci->i_ceph_lock);
 -      return drop;
 -}
 -
 -/*
   * rmdir and unlink are differ only by the metadata op code
   */
  static int ceph_unlink(struct inode *dir, struct dentry *dentry)
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 -      req->r_inode_drop = drop_caps_for_unlink(inode);
 +      req->r_inode_drop = ceph_drop_caps_for_unlink(inode);
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (!err && !req->r_reply_info.head->is_dentry)
                d_delete(dentry);
@@@ -1084,10 -1103,8 +1083,10 @@@ static int ceph_rename(struct inode *ol
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        /* release LINK_RDCACHE on source inode (mds will lock it) */
        req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
 -      if (d_really_is_positive(new_dentry))
 -              req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry));
 +      if (d_really_is_positive(new_dentry)) {
 +              req->r_inode_drop =
 +                      ceph_drop_caps_for_unlink(d_inode(new_dentry));
 +      }
        err = ceph_mdsc_do_request(mdsc, old_dir, req);
        if (!err && !req->r_reply_info.head->is_dentry) {
                /*
diff --combined fs/ext4/inode.c
@@@ -2694,6 -2694,15 +2694,6 @@@ out
        return err;
  }
  
 -static int __writepage(struct page *page, struct writeback_control *wbc,
 -                     void *data)
 -{
 -      struct address_space *mapping = data;
 -      int ret = ext4_writepage(page, wbc);
 -      mapping_set_error(mapping, ret);
 -      return ret;
 -}
 -
  static int ext4_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
  {
                goto out_writepages;
  
        if (ext4_should_journal_data(inode)) {
 -              struct blk_plug plug;
 -
 -              blk_start_plug(&plug);
 -              ret = write_cache_pages(mapping, wbc, __writepage, mapping);
 -              blk_finish_plug(&plug);
 +              ret = generic_writepages(mapping, wbc);
                goto out_writepages;
        }
  
@@@ -3511,7 -3524,7 +3511,7 @@@ retry
                iomap->flags |= IOMAP_F_DIRTY;
        iomap->bdev = inode->i_sb->s_bdev;
        iomap->dax_dev = sbi->s_daxdev;
 -      iomap->offset = first_block << blkbits;
 +      iomap->offset = (u64)first_block << blkbits;
        iomap->length = (u64)map.m_len << blkbits;
  
        if (ret == 0) {
@@@ -3656,7 -3669,7 +3656,7 @@@ static ssize_t ext4_direct_IO_write(str
        int orphan = 0;
        handle_t *handle;
  
 -      if (final_size > inode->i_size) {
 +      if (final_size > inode->i_size || final_size > ei->i_disksize) {
                /* Credits for sb + inode write */
                handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
                if (IS_ERR(handle)) {
                        goto out;
                }
                orphan = 1;
 -              ei->i_disksize = inode->i_size;
 +              ext4_update_i_disksize(inode, inode->i_size);
                ext4_journal_stop(handle);
        }
  
                        ext4_orphan_del(handle, inode);
                if (ret > 0) {
                        loff_t end = offset + ret;
 -                      if (end > inode->i_size) {
 -                              ei->i_disksize = end;
 -                              i_size_write(inode, end);
 +                      if (end > inode->i_size || end > ei->i_disksize) {
 +                              ext4_update_i_disksize(inode, end);
 +                              if (end > inode->i_size)
 +                                      i_size_write(inode, end);
                                /*
                                 * We're going to return a positive `ret'
                                 * here due to non-zero-length I/O, so there's
@@@ -4239,6 -4251,7 +4239,6 @@@ int ext4_punch_hole(struct inode *inode
        }
  
        /* Wait all existing dio workers, newcomers will block on i_mutex */
 -      ext4_inode_block_unlocked_dio(inode);
        inode_dio_wait(inode);
  
        /*
@@@ -4311,6 -4324,7 +4311,6 @@@ out_stop
        ext4_journal_stop(handle);
  out_dio:
        up_write(&EXT4_I(inode)->i_mmap_sem);
 -      ext4_inode_resume_unlocked_dio(inode);
  out_mutex:
        inode_unlock(inode);
        return ret;
@@@ -4732,12 -4746,6 +4732,12 @@@ struct inode *ext4_iget(struct super_bl
                goto bad_inode;
        raw_inode = ext4_raw_inode(&iloc);
  
 +      if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
 +              EXT4_ERROR_INODE(inode, "root inode unallocated");
 +              ret = -EFSCORRUPTED;
 +              goto bad_inode;
 +      }
 +
        if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
                ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
                if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
@@@ -5024,12 -5032,12 +5024,12 @@@ static int other_inode_match(struct ino
  
        if ((inode->i_ino != ino) ||
            (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-                              I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
+                              I_DIRTY_INODE)) ||
            ((inode->i_state & I_DIRTY_TIME) == 0))
                return 0;
        spin_lock(&inode->i_lock);
        if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-                               I_DIRTY_SYNC | I_DIRTY_DATASYNC)) == 0) &&
+                               I_DIRTY_INODE)) == 0) &&
            (inode->i_state & I_DIRTY_TIME)) {
                struct ext4_inode_info  *ei = EXT4_I(inode);
  
@@@ -5498,7 -5506,9 +5498,7 @@@ int ext4_setattr(struct dentry *dentry
                 */
                if (orphan) {
                        if (!ext4_should_journal_data(inode)) {
 -                              ext4_inode_block_unlocked_dio(inode);
                                inode_dio_wait(inode);
 -                              ext4_inode_resume_unlocked_dio(inode);
                        } else
                                ext4_wait_for_tail_page_commit(inode);
                }
@@@ -5989,6 -5999,7 +5989,6 @@@ int ext4_change_inode_journal_flag(stru
                return -EROFS;
  
        /* Wait for all existing dio workers */
 -      ext4_inode_block_unlocked_dio(inode);
        inode_dio_wait(inode);
  
        /*
                err = filemap_write_and_wait(inode->i_mapping);
                if (err < 0) {
                        up_write(&EXT4_I(inode)->i_mmap_sem);
 -                      ext4_inode_resume_unlocked_dio(inode);
                        return err;
                }
        }
                if (err < 0) {
                        jbd2_journal_unlock_updates(journal);
                        percpu_up_write(&sbi->s_journal_flag_rwsem);
 -                      ext4_inode_resume_unlocked_dio(inode);
                        return err;
                }
                ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
  
        if (val)
                up_write(&EXT4_I(inode)->i_mmap_sem);
 -      ext4_inode_resume_unlocked_dio(inode);
  
        /* Finally we can mark the inode as dirty. */
  
diff --combined fs/internal.h
@@@ -55,15 -55,7 +55,15 @@@ extern void __init chrdev_init(void)
  extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *);
  extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
                           const char *, unsigned int, struct path *);
 +long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 +              unsigned int dev);
 +long do_mkdirat(int dfd, const char __user *pathname, umode_t mode);
 +long do_rmdir(int dfd, const char __user *pathname);
  long do_unlinkat(int dfd, struct filename *name);
 +long do_symlinkat(const char __user *oldname, int newdfd,
 +                const char __user *newname);
 +int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 +            const char __user *newname, int flags);
  
  /*
   * namespace.c
@@@ -119,13 -111,6 +119,12 @@@ extern struct file *do_filp_open(int df
  extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
                const char *, const struct open_flags *);
  
- extern int open_check_o_direct(struct file *f);
 +long do_sys_ftruncate(unsigned int fd, loff_t length, int small);
 +long do_faccessat(int dfd, const char __user *filename, int mode);
 +int do_fchmodat(int dfd, const char __user *filename, umode_t mode);
 +int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
 +              int flag);
 +
  extern int vfs_open(const struct path *, struct file *, const struct cred *);
  extern struct file *filp_clone_open(struct file *);
  
diff --combined fs/namei.c
@@@ -39,6 -39,7 +39,7 @@@
  #include <linux/bitops.h>
  #include <linux/init_task.h>
  #include <linux/uaccess.h>
+ #include <linux/build_bug.h>
  
  #include "internal.h"
  #include "mount.h"
@@@ -130,6 -131,7 +131,7 @@@ getname_flags(const char __user *filena
        struct filename *result;
        char *kname;
        int len;
+       BUILD_BUG_ON(offsetof(struct filename, iname) % sizeof(long) != 0);
  
        result = audit_reusename(filename);
        if (result)
@@@ -559,10 -561,9 +561,10 @@@ static int __nd_alloc_stack(struct name
  static bool path_connected(const struct path *path)
  {
        struct vfsmount *mnt = path->mnt;
 +      struct super_block *sb = mnt->mnt_sb;
  
 -      /* Only bind mounts can have disconnected paths */
 -      if (mnt->mnt_root == mnt->mnt_sb->s_root)
 +      /* Bind mounts and multi-root filesystems can have disconnected paths */
 +      if (!(sb->s_iflags & SB_I_MULTIROOT) && (mnt->mnt_root == sb->s_root))
                return true;
  
        return is_subdir(path->dentry, mnt->mnt_root);
@@@ -1474,36 -1475,43 +1476,36 @@@ static struct dentry *lookup_dcache(con
  }
  
  /*
 - * Call i_op->lookup on the dentry.  The dentry must be negative and
 - * unhashed.
 - *
 - * dir->d_inode->i_mutex must be held
 + * Parent directory has inode locked exclusive.  This is one
 + * and only case when ->lookup() gets called on non in-lookup
 + * dentries - as the matter of fact, this only gets called
 + * when directory is guaranteed to have no in-lookup children
 + * at all.
   */
 -static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry,
 -                                unsigned int flags)
 -{
 -      struct dentry *old;
 -
 -      /* Don't create child dentry for a dead directory. */
 -      if (unlikely(IS_DEADDIR(dir))) {
 -              dput(dentry);
 -              return ERR_PTR(-ENOENT);
 -      }
 -
 -      old = dir->i_op->lookup(dir, dentry, flags);
 -      if (unlikely(old)) {
 -              dput(dentry);
 -              dentry = old;
 -      }
 -      return dentry;
 -}
 -
  static struct dentry *__lookup_hash(const struct qstr *name,
                struct dentry *base, unsigned int flags)
  {
        struct dentry *dentry = lookup_dcache(name, base, flags);
 +      struct dentry *old;
 +      struct inode *dir = base->d_inode;
  
        if (dentry)
                return dentry;
  
 +      /* Don't create child dentry for a dead directory. */
 +      if (unlikely(IS_DEADDIR(dir)))
 +              return ERR_PTR(-ENOENT);
 +
        dentry = d_alloc(base, name);
        if (unlikely(!dentry))
                return ERR_PTR(-ENOMEM);
  
 -      return lookup_real(base->d_inode, dentry, flags);
 +      old = dir->i_op->lookup(dir, dentry, flags);
 +      if (unlikely(old)) {
 +              dput(dentry);
 +              dentry = old;
 +      }
 +      return dentry;
  }
  
  static int lookup_fast(struct nameidata *nd,
@@@ -3374,9 -3382,7 +3376,7 @@@ finish_open_created
                goto out;
        *opened |= FILE_OPENED;
  opened:
-       error = open_check_o_direct(file);
-       if (!error)
-               error = ima_file_check(file, op->acc_mode, *opened);
+       error = ima_file_check(file, op->acc_mode, *opened);
        if (!error && will_truncate)
                error = handle_truncate(file);
  out:
@@@ -3456,9 -3462,6 +3456,6 @@@ static int do_tmpfile(struct nameidata 
        error = finish_open(file, child, NULL, opened);
        if (error)
                goto out2;
-       error = open_check_o_direct(file);
-       if (error)
-               fput(file);
  out2:
        mnt_drop_write(path.mnt);
  out:
@@@ -3722,8 -3725,8 +3719,8 @@@ static int may_mknod(umode_t mode
        }
  }
  
 -SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 -              unsigned, dev)
 +long do_mknodat(int dfd, const char __user *filename, umode_t mode,
 +              unsigned int dev)
  {
        struct dentry *dentry;
        struct path path;
        return error;
  }
  
 +SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 +              unsigned int, dev)
 +{
 +      return do_mknodat(dfd, filename, mode, dev);
 +}
 +
  SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev)
  {
 -      return sys_mknodat(AT_FDCWD, filename, mode, dev);
 +      return do_mknodat(AT_FDCWD, filename, mode, dev);
  }
  
  int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
  }
  EXPORT_SYMBOL(vfs_mkdir);
  
 -SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 +long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
  {
        struct dentry *dentry;
        struct path path;
@@@ -3828,14 -3825,9 +3825,14 @@@ retry
        return error;
  }
  
 +SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 +{
 +      return do_mkdirat(dfd, pathname, mode);
 +}
 +
  SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
  {
 -      return sys_mkdirat(AT_FDCWD, pathname, mode);
 +      return do_mkdirat(AT_FDCWD, pathname, mode);
  }
  
  int vfs_rmdir(struct inode *dir, struct dentry *dentry)
@@@ -3877,7 -3869,7 +3874,7 @@@ out
  }
  EXPORT_SYMBOL(vfs_rmdir);
  
 -static long do_rmdir(int dfd, const char __user *pathname)
 +long do_rmdir(int dfd, const char __user *pathname)
  {
        int error = 0;
        struct filename *name;
@@@ -4113,8 -4105,8 +4110,8 @@@ int vfs_symlink(struct inode *dir, stru
  }
  EXPORT_SYMBOL(vfs_symlink);
  
 -SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 -              int, newdfd, const char __user *, newname)
 +long do_symlinkat(const char __user *oldname, int newdfd,
 +                const char __user *newname)
  {
        int error;
        struct filename *from;
@@@ -4144,15 -4136,9 +4141,15 @@@ out_putname
        return error;
  }
  
 +SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 +              int, newdfd, const char __user *, newname)
 +{
 +      return do_symlinkat(oldname, newdfd, newname);
 +}
 +
  SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
  {
 -      return sys_symlinkat(oldname, AT_FDCWD, newname);
 +      return do_symlinkat(oldname, AT_FDCWD, newname);
  }
  
  /**
@@@ -4244,8 -4230,8 +4241,8 @@@ EXPORT_SYMBOL(vfs_link)
   * with linux 2.0, and to avoid hard-linking to directories
   * and other special files.  --ADM
   */
 -SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 -              int, newdfd, const char __user *, newname, int, flags)
 +int do_linkat(int olddfd, const char __user *oldname, int newdfd,
 +            const char __user *newname, int flags)
  {
        struct dentry *new_dentry;
        struct path old_path, new_path;
        return error;
  }
  
 +SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 +              int, newdfd, const char __user *, newname, int, flags)
 +{
 +      return do_linkat(olddfd, oldname, newdfd, newname, flags);
 +}
 +
  SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
  {
 -      return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 +      return do_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
  }
  
  /**
@@@ -4495,8 -4475,8 +4492,8 @@@ out
  }
  EXPORT_SYMBOL(vfs_rename);
  
 -SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
 -              int, newdfd, const char __user *, newname, unsigned int, flags)
 +static int do_renameat2(int olddfd, const char __user *oldname, int newdfd,
 +                      const char __user *newname, unsigned int flags)
  {
        struct dentry *old_dentry, *new_dentry;
        struct dentry *trap;
@@@ -4638,21 -4618,15 +4635,21 @@@ exit
        return error;
  }
  
 +SYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
 +              int, newdfd, const char __user *, newname, unsigned int, flags)
 +{
 +      return do_renameat2(olddfd, oldname, newdfd, newname, flags);
 +}
 +
  SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)
  {
 -      return sys_renameat2(olddfd, oldname, newdfd, newname, 0);
 +      return do_renameat2(olddfd, oldname, newdfd, newname, 0);
  }
  
  SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
  {
 -      return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
 +      return do_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
  }
  
  int vfs_whiteout(struct inode *dir, struct dentry *dentry)
diff --combined fs/open.c
+++ b/fs/open.c
@@@ -128,7 -128,7 +128,7 @@@ out
  }
  EXPORT_SYMBOL_GPL(vfs_truncate);
  
 -static long do_sys_truncate(const char __user *pathname, loff_t length)
 +long do_sys_truncate(const char __user *pathname, loff_t length)
  {
        unsigned int lookup_flags = LOOKUP_FOLLOW;
        struct path path;
@@@ -162,7 -162,7 +162,7 @@@ COMPAT_SYSCALL_DEFINE2(truncate, const 
  }
  #endif
  
 -static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 +long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
  {
        struct inode *inode;
        struct dentry *dentry;
@@@ -333,7 -333,7 +333,7 @@@ int vfs_fallocate(struct file *file, in
  }
  EXPORT_SYMBOL_GPL(vfs_fallocate);
  
 -SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
 +int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
  {
        struct fd f = fdget(fd);
        int error = -EBADF;
        return error;
  }
  
 +SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
 +{
 +      return ksys_fallocate(fd, mode, offset, len);
 +}
 +
  /*
   * access() needs to use the real uid/gid, not the effective uid/gid.
   * We do this by temporarily clearing all FS-related capabilities and
   * switching the fsuid/fsgid around to the real ones.
   */
 -SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 +long do_faccessat(int dfd, const char __user *filename, int mode)
  {
        const struct cred *old_cred;
        struct cred *override_cred;
@@@ -431,17 -426,12 +431,17 @@@ out
        return res;
  }
  
 +SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 +{
 +      return do_faccessat(dfd, filename, mode);
 +}
 +
  SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
  {
 -      return sys_faccessat(AT_FDCWD, filename, mode);
 +      return do_faccessat(AT_FDCWD, filename, mode);
  }
  
 -SYSCALL_DEFINE1(chdir, const char __user *, filename)
 +int ksys_chdir(const char __user *filename)
  {
        struct path path;
        int error;
@@@ -467,11 -457,6 +467,11 @@@ out
        return error;
  }
  
 +SYSCALL_DEFINE1(chdir, const char __user *, filename)
 +{
 +      return ksys_chdir(filename);
 +}
 +
  SYSCALL_DEFINE1(fchdir, unsigned int, fd)
  {
        struct fd f = fdget_raw(fd);
@@@ -494,7 -479,7 +494,7 @@@ out
        return error;
  }
  
 -SYSCALL_DEFINE1(chroot, const char __user *, filename)
 +int ksys_chroot(const char __user *filename)
  {
        struct path path;
        int error;
@@@ -527,11 -512,6 +527,11 @@@ out
        return error;
  }
  
 +SYSCALL_DEFINE1(chroot, const char __user *, filename)
 +{
 +      return ksys_chroot(filename);
 +}
 +
  static int chmod_common(const struct path *path, umode_t mode)
  {
        struct inode *inode = path->dentry->d_inode;
@@@ -561,7 -541,7 +561,7 @@@ out_unlock
        return error;
  }
  
 -SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
 +int ksys_fchmod(unsigned int fd, umode_t mode)
  {
        struct fd f = fdget(fd);
        int err = -EBADF;
        return err;
  }
  
 -SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
 +SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
 +{
 +      return ksys_fchmod(fd, mode);
 +}
 +
 +int do_fchmodat(int dfd, const char __user *filename, umode_t mode)
  {
        struct path path;
        int error;
@@@ -597,15 -572,9 +597,15 @@@ retry
        return error;
  }
  
 +SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,
 +              umode_t, mode)
 +{
 +      return do_fchmodat(dfd, filename, mode);
 +}
 +
  SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
  {
 -      return sys_fchmodat(AT_FDCWD, filename, mode);
 +      return do_fchmodat(AT_FDCWD, filename, mode);
  }
  
  static int chown_common(const struct path *path, uid_t user, gid_t group)
@@@ -650,8 -619,8 +650,8 @@@ retry_deleg
        return error;
  }
  
 -SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 -              gid_t, group, int, flag)
 +int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
 +              int flag)
  {
        struct path path;
        int error = -EINVAL;
@@@ -682,24 -651,18 +682,24 @@@ out
        return error;
  }
  
 +SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 +              gid_t, group, int, flag)
 +{
 +      return do_fchownat(dfd, filename, user, group, flag);
 +}
 +
  SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
  {
 -      return sys_fchownat(AT_FDCWD, filename, user, group, 0);
 +      return do_fchownat(AT_FDCWD, filename, user, group, 0);
  }
  
  SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
  {
 -      return sys_fchownat(AT_FDCWD, filename, user, group,
 -                          AT_SYMLINK_NOFOLLOW);
 +      return do_fchownat(AT_FDCWD, filename, user, group,
 +                         AT_SYMLINK_NOFOLLOW);
  }
  
 -SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
 +int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
  {
        struct fd f = fdget(fd);
        int error = -EBADF;
@@@ -719,21 -682,6 +719,11 @@@ out
        return error;
  }
  
- int open_check_o_direct(struct file *f)
- {
-       /* NB: we're sure to have correct a_ops only after f_op->open */
-       if (f->f_flags & O_DIRECT) {
-               if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
-                       return -EINVAL;
-       }
-       return 0;
- }
 +SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
 +{
 +      return ksys_fchown(fd, user, group);
 +}
 +
  static int do_dentry_open(struct file *f,
                          struct inode *inode,
                          int (*open)(struct inode *, struct file *),
        if (unlikely(f->f_flags & O_PATH)) {
                f->f_mode = FMODE_PATH;
                f->f_op = &empty_fops;
-               return 0;
+               goto done;
        }
  
        if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
        f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
  
        file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
+ done:
+       /* NB: we're sure to have correct a_ops only after f_op->open */
+       error = -EINVAL;
+       if ((f->f_flags & O_DIRECT) &&
+           (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO))
+               goto out_fput;
        return 0;
  
  cleanup_all:
@@@ -823,6 -776,9 +818,9 @@@ cleanup_file
        f->f_path.dentry = NULL;
        f->f_inode = NULL;
        return error;
+ out_fput:
+       fput(f);
+       return error;
  }
  
  /**
@@@ -920,20 -876,14 +918,14 @@@ struct file *dentry_open(const struct p
        BUG_ON(!path->mnt);
  
        f = get_empty_filp();
-       if (!IS_ERR(f)) {
-               f->f_flags = flags;
-               error = vfs_open(path, f, cred);
-               if (!error) {
-                       /* from now on we need fput() to dispose of f */
-                       error = open_check_o_direct(f);
-                       if (error) {
-                               fput(f);
-                               f = ERR_PTR(error);
-                       }
-               } else { 
-                       put_filp(f);
-                       f = ERR_PTR(error);
-               }
+       if (IS_ERR(f))
+               return f;
+       f->f_flags = flags;
+       error = vfs_open(path, f, cred);
+       if (error) {
+               put_filp(f);
+               return ERR_PTR(error);
        }
        return f;
  }
@@@ -1156,7 -1106,7 +1148,7 @@@ COMPAT_SYSCALL_DEFINE4(openat, int, dfd
   */
  SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
  {
 -      return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
 +      return ksys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
  }
  
  #endif
@@@ -1205,6 -1155,7 +1197,6 @@@ SYSCALL_DEFINE1(close, unsigned int, fd
  
        return retval;
  }
 -EXPORT_SYMBOL(sys_close);
  
  /*
   * This routine simulates a hangup on the tty, to arrange that users
diff --combined fs/xfs/xfs_aops.c
@@@ -209,8 -209,7 +209,8 @@@ xfs_setfilesize_trans_alloc
        struct xfs_trans        *tp;
        int                     error;
  
 -      error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
 +      error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0,
 +                              XFS_TRANS_NOFS, &tp);
        if (error)
                return error;
  
@@@ -1331,20 -1330,21 +1331,20 @@@ xfs_get_blocks
        end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
        offset_fsb = XFS_B_TO_FSBT(mp, offset);
  
 -      error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
 -                              &imap, &nimaps, XFS_BMAPI_ENTIRE);
 +      error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
 +                      &nimaps, 0);
        if (error)
                goto out_unlock;
 -
 -      if (nimaps) {
 -              trace_xfs_get_blocks_found(ip, offset, size,
 -                      imap.br_state == XFS_EXT_UNWRITTEN ?
 -                              XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, &imap);
 -              xfs_iunlock(ip, lockmode);
 -      } else {
 +      if (!nimaps) {
                trace_xfs_get_blocks_notfound(ip, offset, size);
                goto out_unlock;
        }
  
 +      trace_xfs_get_blocks_found(ip, offset, size,
 +              imap.br_state == XFS_EXT_UNWRITTEN ?
 +                      XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, &imap);
 +      xfs_iunlock(ip, lockmode);
 +
        /* trim mapping down to size requested */
        xfs_map_trim_size(inode, iblock, bh_result, &imap, offset, size);
  
@@@ -1390,7 -1390,7 +1390,7 @@@ xfs_vm_bmap
  
        /*
         * The swap code (ab-)uses ->bmap to get a block mapping and then
-        * bypasseѕ the file system for actual I/O.  We really can't allow
+        * bypasses the file system for actual I/O.  We really can't allow
         * that on reflinks inodes, so we have to skip out here.  And yes,
         * 0 is the magic code for a bmap error.
         *
diff --combined include/linux/fs.h
@@@ -1317,7 -1317,6 +1317,7 @@@ extern int send_sigurg(struct fown_stru
  #define SB_I_CGROUPWB 0x00000001      /* cgroup-aware writeback enabled */
  #define SB_I_NOEXEC   0x00000002      /* Ignore executables on this fs */
  #define SB_I_NODEV    0x00000004      /* Ignore devices on this fs */
 +#define SB_I_MULTIROOT        0x00000008      /* Multiple roots to the dentry tree */
  
  /* sb->s_iflags to limit user namespace mounts */
  #define SB_I_USERNS_VISIBLE           0x00000010 /* fstype already mounted */
@@@ -2015,7 -2014,8 +2015,8 @@@ static inline void init_sync_kiocb(stru
  #define I_WB_SWITCH           (1 << 13)
  #define I_OVL_INUSE                   (1 << 14)
  
- #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
+ #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
+ #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
  #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
  
  extern void __mark_inode_dirty(struct inode *, int);
@@@ -2381,8 -2381,8 +2382,8 @@@ struct audit_names
  struct filename {
        const char              *name;  /* pointer to actual string */
        const __user char       *uptr;  /* original userland pointer */
-       struct audit_names      *aname;
        int                     refcnt;
+       struct audit_names      *aname;
        const char              iname[];
  };
  
@@@ -2977,6 -2977,12 +2978,6 @@@ enum 
  
        /* filesystem does not support filling holes */
        DIO_SKIP_HOLES  = 0x02,
 -
 -      /* filesystem can handle aio writes beyond i_size */
 -      DIO_ASYNC_EXTEND = 0x04,
 -
 -      /* inode/fs/bdev does not need truncate protection */
 -      DIO_SKIP_DIO_COUNT = 0x08,
  };
  
  void dio_end_io(struct bio *bio);
@@@ -3193,7 -3199,7 +3194,7 @@@ static inline bool vma_is_fsdax(struct 
        if (!vma_is_dax(vma))
                return false;
        inode = file_inode(vma->vm_file);
 -      if (inode->i_mode == S_IFCHR)
 +      if (S_ISCHR(inode->i_mode))
                return false; /* device-dax */
        return true;
  }