]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'xfs-4.11-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 02:05:23 +0000 (18:05 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 02:05:23 +0000 (18:05 -0800)
Pull xfs updates from Darrick Wong:
 "Here are the XFS changes for 4.11. We aren't introducing any major
  features in this release cycle except for this being the first merge
  window I've managed on my own. :)

  Changes since last update:

   - Various cleanups

   - Livelock fixes for eofblocks scanning

   - Improved input verification for on-disk metadata

   - Fix races in the copy on write remap mechanism

   - Fix buffer io error timeout controls

   - Streamlining of directio copy on write

   - Asynchronous discard support

   - Fix asserts when splitting delalloc reservations

   - Don't bloat bmbt when right shifting extents

   - Inode alignment fixes for 32k block sizes"

* tag 'xfs-4.11-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (39 commits)
  xfs: remove XFS_ALLOCTYPE_ANY_AG and XFS_ALLOCTYPE_START_AG
  xfs: simplify xfs_rtallocate_extent
  xfs: tune down agno asserts in the bmap code
  xfs: Use xfs_icluster_size_fsb() to calculate inode chunk alignment
  xfs: don't reserve blocks for right shift transactions
  xfs: fix len comparison in xfs_extent_busy_trim
  xfs: fix uninitialized variable in _reflink_convert_cow
  xfs: split indlen reservations fairly when under reserved
  xfs: handle indlen shortage on delalloc extent merge
  xfs: resurrect debug mode drop buffered writes mechanism
  xfs: clear delalloc and cache on buffered write failure
  xfs: don't block the log commit handler for discards
  xfs: improve busy extent sorting
  xfs: improve handling of busy extents in the low-level allocator
  xfs: don't fail xfs_extent_busy allocation
  xfs: correct null checks and error processing in xfs_initialize_perag
  xfs: update ctime and mtime on clone destinatation inodes
  xfs: allocate direct I/O COW blocks in iomap_begin
  xfs: go straight to real allocations for direct I/O COW writes
  xfs: return the converted extent in __xfs_reflink_convert_cow
  ...

1  2 
fs/dax.c
fs/ext4/ext4.h
fs/ext4/inode.c
fs/iomap.c

diff --combined fs/dax.c
index e9cf8b4cd2346103b3ef4a76322a47b36e5dd8d6,78b9651576c69b3dc1d7b6c7220b4367059e81b1..99b5b4458a786366a73a442817aaef1d37297267
+++ b/fs/dax.c
@@@ -1031,11 -1031,6 +1031,11 @@@ dax_iomap_actor(struct inode *inode, lo
                struct blk_dax_ctl dax = { 0 };
                ssize_t map_len;
  
 +              if (fatal_signal_pending(current)) {
 +                      ret = -EINTR;
 +                      break;
 +              }
 +
                dax.sector = dax_iomap_sector(iomap, pos);
                dax.size = (length + offset + PAGE_SIZE - 1) & PAGE_MASK;
                map_len = dax_map_atomic(iomap->bdev, &dax);
   */
  ssize_t
  dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        struct address_space *mapping = iocb->ki_filp->f_mapping;
        struct inode *inode = mapping->host;
        loff_t pos = iocb->ki_pos, ret = 0, done = 0;
        unsigned flags = 0;
  
 -      if (iov_iter_rw(iter) == WRITE)
 +      if (iov_iter_rw(iter) == WRITE) {
 +              lockdep_assert_held_exclusive(&inode->i_rwsem);
                flags |= IOMAP_WRITE;
 +      } else {
 +              lockdep_assert_held(&inode->i_rwsem);
 +      }
  
        while (iov_iter_count(iter)) {
                ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops,
@@@ -1127,7 -1118,7 +1127,7 @@@ static int dax_fault_return(int error
   * necessary locking for the page fault to proceed successfully.
   */
  int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
-                       struct iomap_ops *ops)
+                       const struct iomap_ops *ops)
  {
        struct address_space *mapping = vma->vm_file->f_mapping;
        struct inode *inode = mapping->host;
@@@ -1326,7 -1317,7 +1326,7 @@@ static int dax_pmd_load_hole(struct vm_
  }
  
  int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
-               pmd_t *pmd, unsigned int flags, struct iomap_ops *ops)
+               pmd_t *pmd, unsigned int flags, const struct iomap_ops *ops)
  {
        struct address_space *mapping = vma->vm_file->f_mapping;
        unsigned long pmd_addr = address & PMD_MASK;
diff --combined fs/ext4/ext4.h
index 01d52b98f9a766377f7b8fe62f0e2b9f2832a920,ce70403c470703e01c1cdd5c4cc6ebbd691e2abf..cee23b684f4784e5ed067f7bbd4e5fb7d3c57384
  #include <linux/percpu_counter.h>
  #include <linux/ratelimit.h>
  #include <crypto/hash.h>
 -#include <linux/fscrypto.h>
 +#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#include <linux/fscrypt_supp.h>
 +#else
 +#include <linux/fscrypt_notsupp.h>
 +#endif
  #include <linux/falloc.h>
  #include <linux/percpu-rwsem.h>
  #ifdef __KERNEL__
@@@ -683,16 -679,6 +683,16 @@@ struct fsxattr 
  #define EXT4_IOC_FSGETXATTR           FS_IOC_FSGETXATTR
  #define EXT4_IOC_FSSETXATTR           FS_IOC_FSSETXATTR
  
 +#define EXT4_IOC_SHUTDOWN _IOR ('X', 125, __u32)
 +
 +/*
 + * Flags for going down operation
 + */
 +#define EXT4_GOING_FLAGS_DEFAULT              0x0     /* going down */
 +#define EXT4_GOING_FLAGS_LOGFLUSH             0x1     /* flush log but not data */
 +#define EXT4_GOING_FLAGS_NOLOGFLUSH           0x2     /* don't flush log nor data */
 +
 +
  #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
  /*
   * ioctl commands in 32 bit emulation
@@@ -1357,6 -1343,11 +1357,6 @@@ struct ext4_super_block 
  /* Number of quota types we support */
  #define EXT4_MAXQUOTAS 3
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 -#define EXT4_KEY_DESC_PREFIX "ext4:"
 -#define EXT4_KEY_DESC_PREFIX_SIZE 5
 -#endif
 -
  /*
   * fourth extended-fs super-block data in memory
   */
@@@ -1413,7 -1404,8 +1413,7 @@@ struct ext4_sb_info 
        struct journal_s *s_journal;
        struct list_head s_orphan;
        struct mutex s_orphan_lock;
 -      unsigned long s_resize_flags;           /* Flags indicating if there
 -                                                 is a resizer */
 +      unsigned long s_ext4_flags;             /* Ext4 superblock flags */
        unsigned long s_commit_interval;
        u32 s_max_batch_time;
        u32 s_min_batch_time;
  
        /* Barrier between changing inodes' journal flags and writepages ops. */
        struct percpu_rw_semaphore s_journal_flag_rwsem;
 -
 -      /* Encryption support */
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 -      u8 key_prefix[EXT4_KEY_DESC_PREFIX_SIZE];
 -      u8 key_prefix_size;
 -#endif
  };
  
  static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@@ -1846,18 -1844,6 +1846,18 @@@ static inline bool ext4_has_incompat_fe
        return (EXT4_SB(sb)->s_es->s_feature_incompat != 0);
  }
  
 +/*
 + * Superblock flags
 + */
 +#define EXT4_FLAGS_RESIZING   0
 +#define EXT4_FLAGS_SHUTDOWN   1
 +
 +static inline int ext4_forced_shutdown(struct ext4_sb_info *sbi)
 +{
 +      return test_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
 +}
 +
 +
  /*
   * Default values for user and/or group using reserved blocks
   */
@@@ -2334,6 -2320,28 +2334,6 @@@ static inline int ext4_fname_setup_file
  }
  static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
  
 -#define fscrypt_set_d_op(i)
 -#define fscrypt_get_ctx                       fscrypt_notsupp_get_ctx
 -#define fscrypt_release_ctx           fscrypt_notsupp_release_ctx
 -#define fscrypt_encrypt_page          fscrypt_notsupp_encrypt_page
 -#define fscrypt_decrypt_page          fscrypt_notsupp_decrypt_page
 -#define fscrypt_decrypt_bio_pages     fscrypt_notsupp_decrypt_bio_pages
 -#define fscrypt_pullback_bio_page     fscrypt_notsupp_pullback_bio_page
 -#define fscrypt_restore_control_page  fscrypt_notsupp_restore_control_page
 -#define fscrypt_zeroout_range         fscrypt_notsupp_zeroout_range
 -#define fscrypt_ioctl_set_policy      fscrypt_notsupp_ioctl_set_policy
 -#define fscrypt_ioctl_get_policy      fscrypt_notsupp_ioctl_get_policy
 -#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
 -#define fscrypt_inherit_context               fscrypt_notsupp_inherit_context
 -#define fscrypt_get_encryption_info   fscrypt_notsupp_get_encryption_info
 -#define fscrypt_put_encryption_info   fscrypt_notsupp_put_encryption_info
 -#define fscrypt_setup_filename                fscrypt_notsupp_setup_filename
 -#define fscrypt_free_filename         fscrypt_notsupp_free_filename
 -#define fscrypt_fname_encrypted_size  fscrypt_notsupp_fname_encrypted_size
 -#define fscrypt_fname_alloc_buffer    fscrypt_notsupp_fname_alloc_buffer
 -#define fscrypt_fname_free_buffer     fscrypt_notsupp_fname_free_buffer
 -#define fscrypt_fname_disk_to_usr     fscrypt_notsupp_fname_disk_to_usr
 -#define fscrypt_fname_usr_to_disk     fscrypt_notsupp_fname_usr_to_disk
  #endif
  
  /* dir.c */
@@@ -3026,7 -3034,7 +3026,7 @@@ extern int ext4_inline_data_fiemap(stru
  extern int ext4_try_to_evict_inline_data(handle_t *handle,
                                         struct inode *inode,
                                         int needed);
 -extern void ext4_inline_data_truncate(struct inode *inode, int *has_inline);
 +extern int ext4_inline_data_truncate(struct inode *inode, int *has_inline);
  
  extern int ext4_convert_inline_data(struct inode *inode);
  
@@@ -3220,6 -3228,7 +3220,6 @@@ static inline void ext4_inode_resume_un
                                            EXT4_WQ_HASH_SZ])
  extern wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
  
 -#define EXT4_RESIZING 0
  extern int ext4_resize_begin(struct super_block *sb);
  extern void ext4_resize_end(struct super_block *sb);
  
@@@ -3244,7 -3253,7 +3244,7 @@@ static inline void ext4_clear_io_unwrit
        }
  }
  
- extern struct iomap_ops ext4_iomap_ops;
+ extern const struct iomap_ops ext4_iomap_ops;
  
  #endif        /* __KERNEL__ */
  
diff --combined fs/ext4/inode.c
index f622d4a577e35d88f52e6e31dfe5791d34a905b8,96c2e12cc5d6865ba6fa29f4d9bce0e06c6bcb06..75212a6e69f8e7ceb05e1ac38ab46f9d71e0f7ce
@@@ -1189,9 -1189,6 +1189,9 @@@ static int ext4_write_begin(struct fil
        pgoff_t index;
        unsigned from, to;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        trace_ext4_write_begin(inode, pos, len, flags);
        /*
         * Reserve one block more for addition to orphan list in case
@@@ -1333,11 -1330,8 +1333,11 @@@ static int ext4_write_end(struct file *
        if (ext4_has_inline_data(inode)) {
                ret = ext4_write_inline_data_end(inode, pos, len,
                                                 copied, page);
 -              if (ret < 0)
 +              if (ret < 0) {
 +                      unlock_page(page);
 +                      put_page(page);
                        goto errout;
 +              }
                copied = ret;
        } else
                copied = block_write_end(file, mapping, pos,
@@@ -1391,9 -1385,7 +1391,9 @@@ errout
   * set the buffer to be dirty, since in data=journalled mode we need
   * to call ext4_handle_dirty_metadata() instead.
   */
 -static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
 +static void ext4_journalled_zero_new_buffers(handle_t *handle,
 +                                          struct page *page,
 +                                          unsigned from, unsigned to)
  {
        unsigned int block_start = 0, block_end;
        struct buffer_head *head, *bh;
                                        size = min(to, block_end) - start;
  
                                        zero_user(page, start, size);
 -                                      set_buffer_uptodate(bh);
 +                                      write_end_fn(handle, bh);
                                }
                                clear_buffer_new(bh);
                        }
@@@ -1439,25 -1431,18 +1439,25 @@@ static int ext4_journalled_write_end(st
  
        BUG_ON(!ext4_handle_valid(handle));
  
 -      if (ext4_has_inline_data(inode))
 -              copied = ext4_write_inline_data_end(inode, pos, len,
 -                                                  copied, page);
 -      else {
 -              if (copied < len) {
 -                      if (!PageUptodate(page))
 -                              copied = 0;
 -                      zero_new_buffers(page, from+copied, to);
 +      if (ext4_has_inline_data(inode)) {
 +              ret = ext4_write_inline_data_end(inode, pos, len,
 +                                               copied, page);
 +              if (ret < 0) {
 +                      unlock_page(page);
 +                      put_page(page);
 +                      goto errout;
                }
 -
 +              copied = ret;
 +      } else if (unlikely(copied < len) && !PageUptodate(page)) {
 +              copied = 0;
 +              ext4_journalled_zero_new_buffers(handle, page, from, to);
 +      } else {
 +              if (unlikely(copied < len))
 +                      ext4_journalled_zero_new_buffers(handle, page,
 +                                                       from + copied, to);
                ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
 -                                           to, &partial, write_end_fn);
 +                                           from + copied, &partial,
 +                                           write_end_fn);
                if (!partial)
                        SetPageUptodate(page);
        }
                 */
                ext4_orphan_add(handle, inode);
  
 +errout:
        ret2 = ext4_journal_stop(handle);
        if (!ret)
                ret = ret2;
@@@ -2050,12 -2034,6 +2050,12 @@@ static int ext4_writepage(struct page *
        struct ext4_io_submit io_submit;
        bool keep_towrite = false;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) {
 +              ext4_invalidatepage(page, 0, PAGE_SIZE);
 +              unlock_page(page);
 +              return -EIO;
 +      }
 +
        trace_ext4_writepage(page);
        size = i_size_read(inode);
        if (page->index == size >> PAGE_SHIFT)
@@@ -2431,8 -2409,7 +2431,8 @@@ static int mpage_map_and_submit_extent(
                if (err < 0) {
                        struct super_block *sb = inode->i_sb;
  
 -                      if (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED)
 +                      if (ext4_forced_shutdown(EXT4_SB(sb)) ||
 +                          EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED)
                                goto invalidate_dirty_pages;
                        /*
                         * Let the uper layers retry transient errors.
@@@ -2487,8 -2464,8 +2487,8 @@@ update_disksize
                        disksize = i_size;
                if (disksize > EXT4_I(inode)->i_disksize)
                        EXT4_I(inode)->i_disksize = disksize;
 -              err2 = ext4_mark_inode_dirty(handle, inode);
                up_write(&EXT4_I(inode)->i_data_sem);
 +              err2 = ext4_mark_inode_dirty(handle, inode);
                if (err2)
                        ext4_error(inode->i_sb,
                                   "Failed to mark inode %lu dirty",
@@@ -2654,9 -2631,6 +2654,9 @@@ static int ext4_writepages(struct addre
        struct blk_plug plug;
        bool give_up_on_write = false;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        percpu_down_read(&sbi->s_journal_flag_rwsem);
        trace_ext4_writepages(inode, wbc);
  
         * *never* be called, so if that ever happens, we would want
         * the stack trace.
         */
 -      if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) {
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(mapping->host->i_sb)) ||
 +                   sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) {
                ret = -EROFS;
                goto out_writepages;
        }
@@@ -2919,9 -2892,6 +2919,9 @@@ static int ext4_da_write_begin(struct f
        struct inode *inode = mapping->host;
        handle_t *handle;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        index = pos >> PAGE_SHIFT;
  
        if (ext4_nonda_switch(inode->i_sb) ||
@@@ -3450,7 -3420,7 +3450,7 @@@ orphan_del
        return ret;
  }
  
- struct iomap_ops ext4_iomap_ops = {
const struct iomap_ops ext4_iomap_ops = {
        .iomap_begin            = ext4_iomap_begin,
        .iomap_end              = ext4_iomap_end,
  };
@@@ -3944,10 -3914,6 +3944,10 @@@ static int ext4_block_truncate_page(han
        unsigned blocksize;
        struct inode *inode = mapping->host;
  
 +      /* If we are processing an encrypted inode during orphan list handling */
 +      if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
 +              return 0;
 +
        blocksize = inode->i_sb->s_blocksize;
        length = blocksize - (offset & (blocksize - 1));
  
@@@ -4256,9 -4222,7 +4256,9 @@@ int ext4_truncate(struct inode *inode
        if (ext4_has_inline_data(inode)) {
                int has_inline = 1;
  
 -              ext4_inline_data_truncate(inode, &has_inline);
 +              err = ext4_inline_data_truncate(inode, &has_inline);
 +              if (err)
 +                      return err;
                if (has_inline)
                        return 0;
        }
@@@ -5233,9 -5197,6 +5233,9 @@@ int ext4_setattr(struct dentry *dentry
        int orphan = 0;
        const unsigned int ia_valid = attr->ia_valid;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        error = setattr_prepare(dentry, attr);
        if (error)
                return error;
@@@ -5522,9 -5483,6 +5522,9 @@@ int ext4_mark_iloc_dirty(handle_t *hand
  {
        int err = 0;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        if (IS_I_VERSION(inode))
                inode_inc_iversion(inode);
  
@@@ -5548,9 -5506,6 +5548,9 @@@ ext4_reserve_inode_write(handle_t *hand
  {
        int err;
  
 +      if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
 +              return -EIO;
 +
        err = ext4_get_inode_loc(inode, iloc);
        if (!err) {
                BUFFER_TRACE(iloc->bh, "get_write_access");
diff --combined fs/iomap.c
index a51cb4c07d4d8cd3a09715361c84126cecae2ca2,7f08ca03d95d3512df13f7e0920246e56553939b..d89f70bbb952f0d9b72a54f02a5d76c76f0a8888
@@@ -41,7 -41,7 +41,7 @@@
   */
  loff_t
  iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags,
-               struct iomap_ops *ops, void *data, iomap_actor_t actor)
+               const struct iomap_ops *ops, void *data, iomap_actor_t actor)
  {
        struct iomap iomap = { 0 };
        loff_t written = 0, ret;
@@@ -114,9 -114,6 +114,9 @@@ iomap_write_begin(struct inode *inode, 
  
        BUG_ON(pos + len > iomap->offset + iomap->length);
  
 +      if (fatal_signal_pending(current))
 +              return -EINTR;
 +
        page = grab_cache_page_write_begin(inode->i_mapping, index, flags);
        if (!page)
                return -ENOMEM;
@@@ -235,7 -232,7 +235,7 @@@ again
  
  ssize_t
  iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *iter,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        struct inode *inode = iocb->ki_filp->f_mapping->host;
        loff_t pos = iocb->ki_pos, ret = 0, written = 0;
@@@ -318,7 -315,7 +318,7 @@@ iomap_dirty_actor(struct inode *inode, 
  
  int
  iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        loff_t ret;
  
@@@ -398,7 -395,7 +398,7 @@@ iomap_zero_range_actor(struct inode *in
  
  int
  iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        loff_t ret;
  
@@@ -418,7 -415,7 +418,7 @@@ EXPORT_SYMBOL_GPL(iomap_zero_range)
  
  int
  iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        unsigned blocksize = (1 << inode->i_blkbits);
        unsigned off = pos & (blocksize - 1);
@@@ -446,7 -443,7 +446,7 @@@ iomap_page_mkwrite_actor(struct inode *
  }
  
  int iomap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
-               struct iomap_ops *ops)
+               const struct iomap_ops *ops)
  {
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vma->vm_file);
@@@ -545,7 -542,7 +545,7 @@@ iomap_fiemap_actor(struct inode *inode
  }
  
  int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
-               loff_t start, loff_t len, struct iomap_ops *ops)
+               loff_t start, loff_t len, const struct iomap_ops *ops)
  {
        struct fiemap_ctx ctx;
        loff_t ret;
@@@ -839,8 -836,8 +839,8 @@@ iomap_dio_actor(struct inode *inode, lo
  }
  
  ssize_t
- iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, struct iomap_ops *ops,
-               iomap_dio_end_io_t end_io)
+ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
+               const struct iomap_ops *ops, iomap_dio_end_io_t end_io)
  {
        struct address_space *mapping = iocb->ki_filp->f_mapping;
        struct inode *inode = file_inode(iocb->ki_filp);