Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Mar 2019 22:03:21 +0000 (15:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Mar 2019 22:03:21 +0000 (15:03 -0700)
Pull ext4 updates from Ted Ts'o:
 "A large number of bug fixes and cleanups.

  One new feature to allow users to more easily find the jbd2 journal
  thread for a particular ext4 file system"

* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (25 commits)
  jbd2: jbd2_get_transaction does not need to return a value
  jbd2: fix invalid descriptor block checksum
  ext4: fix bigalloc cluster freeing when hole punching under load
  ext4: add sysfs attr /sys/fs/ext4/<disk>/journal_task
  ext4: Change debugging support help prefix from EXT4 to Ext4
  ext4: fix compile error when using BUFFER_TRACE
  jbd2: fix compile warning when using JBUFFER_TRACE
  ext4: fix some error pointer dereferences
  ext4: annotate more implicit fall throughs
  ext4: annotate implicit fall throughs
  ext4: don't update s_rev_level if not required
  jbd2: fold jbd2_superblock_csum_{verify,set} into their callers
  jbd2: fix race when writing superblock
  ext4: fix crash during online resizing
  ext4: disallow files with EXT4_JOURNAL_DATA_FL from EXT4_IOC_SWAP_BOOT
  ext4: add mask of ext4 flags to swap
  ext4: update quota information while swapping boot loader inode
  ext4: cleanup pagecache before swap i_data
  ext4: fix check of inode in swap_inode_boot_loader
  ext4: unlock unused_pages timely when doing writeback
  ...

1  2 
fs/ext4/Kconfig
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/ext4/sysfs.c

diff --combined fs/ext4/Kconfig
index 031e5a82d556dbe9d4bd2cff39d1b8c4e162b659,112b475f6981a102a2e6ba9f0c17430c02e712e0..06f77ca7f36ee737018016883df254948b5851e7
@@@ -96,8 -96,23 +96,8 @@@ config EXT4_FS_SECURIT
          If you are not using a security module that requires using
          extended attributes for file security labels, say N.
  
 -config EXT4_ENCRYPTION
 -      bool "Ext4 Encryption"
 -      depends on EXT4_FS
 -      select FS_ENCRYPTION
 -      help
 -        Enable encryption of ext4 files and directories.  This
 -        feature is similar to ecryptfs, but it is more memory
 -        efficient since it avoids caching the encrypted and
 -        decrypted pages in the page cache.
 -
 -config EXT4_FS_ENCRYPTION
 -      bool
 -      default y
 -      depends on EXT4_ENCRYPTION
 -
  config EXT4_DEBUG
-       bool "EXT4 debugging support"
+       bool "Ext4 debugging support"
        depends on EXT4_FS
        help
          Enables run-time debugging support for the ext4 filesystem.
diff --combined fs/ext4/ext4.h
index 5012ddb6daf9fb1561053a304e39d4ec8900262a,b8fde74ff76dfeece14f00f7b77cc157180e926d..82ffdacdc7fac30b63da30a39bac9349a1244717
@@@ -40,6 -40,7 +40,6 @@@
  #include <linux/compat.h>
  #endif
  
 -#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
  #include <linux/fscrypt.h>
  
  #include <linux/compiler.h>
@@@ -425,6 -426,9 +425,9 @@@ struct flex_groups 
  /* Flags that are appropriate for non-directories/regular files. */
  #define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)
  
+ /* The only flags that should be swapped */
+ #define EXT4_FL_SHOULD_SWAP (EXT4_HUGE_FILE_FL | EXT4_EXTENTS_FL)
  /* Mask out flags that are inappropriate for the given type of inode. */
  static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
  {
@@@ -1325,7 -1329,7 +1328,7 @@@ struct ext4_super_block 
  #define EXT4_MF_FS_ABORTED            0x0002  /* Fatal error detected */
  #define EXT4_MF_TEST_DUMMY_ENCRYPTION 0x0004
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  #define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->s_mount_flags & \
                                                EXT4_MF_TEST_DUMMY_ENCRYPTION))
  #else
@@@ -1661,6 -1665,8 +1664,8 @@@ static inline void ext4_clear_state_fla
  #define EXT4_FEATURE_INCOMPAT_INLINE_DATA     0x8000 /* data in inode */
  #define EXT4_FEATURE_INCOMPAT_ENCRYPT         0x10000
  
+ extern void ext4_update_dynamic_rev(struct super_block *sb);
  #define EXT4_FEATURE_COMPAT_FUNCS(name, flagname) \
  static inline bool ext4_has_feature_##name(struct super_block *sb) \
  { \
  } \
  static inline void ext4_set_feature_##name(struct super_block *sb) \
  { \
+       ext4_update_dynamic_rev(sb); \
        EXT4_SB(sb)->s_es->s_feature_compat |= \
                cpu_to_le32(EXT4_FEATURE_COMPAT_##flagname); \
  } \
@@@ -1686,6 -1693,7 +1692,7 @@@ static inline bool ext4_has_feature_##n
  } \
  static inline void ext4_set_feature_##name(struct super_block *sb) \
  { \
+       ext4_update_dynamic_rev(sb); \
        EXT4_SB(sb)->s_es->s_feature_ro_compat |= \
                cpu_to_le32(EXT4_FEATURE_RO_COMPAT_##flagname); \
  } \
@@@ -1703,6 -1711,7 +1710,7 @@@ static inline bool ext4_has_feature_##n
  } \
  static inline void ext4_set_feature_##name(struct super_block *sb) \
  { \
+       ext4_update_dynamic_rev(sb); \
        EXT4_SB(sb)->s_es->s_feature_incompat |= \
                cpu_to_le32(EXT4_FEATURE_INCOMPAT_##flagname); \
  } \
@@@ -2050,7 -2059,7 +2058,7 @@@ struct ext4_filename 
        const struct qstr *usr_fname;
        struct fscrypt_str disk_name;
        struct dx_hash_info hinfo;
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
        struct fscrypt_str crypto_buf;
  #endif
  };
@@@ -2278,7 -2287,12 +2286,7 @@@ extern unsigned ext4_free_clusters_afte
                                              struct ext4_group_desc *gdp);
  ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
  
 -static inline bool ext4_encrypted_inode(struct inode *inode)
 -{
 -      return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT);
 -}
 -
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  static inline int ext4_fname_setup_filename(struct inode *dir,
                        const struct qstr *iname,
                        int lookup, struct ext4_filename *fname)
@@@ -2666,7 -2680,6 +2674,6 @@@ do {                                                                    
  
  #endif
  
- extern void ext4_update_dynamic_rev(struct super_block *sb);
  extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb,
                                        __u32 compat);
  extern int ext4_update_rocompat_feature(handle_t *handle,
diff --combined fs/ext4/extents.c
index 79d986dbf5af551533dd95d5ec61e4f53ca586fc,4f1d994847bdb0adcc9ec8ad437e95587729c11e..0f89f5190cd7241aa1b6da7d878816d6787a52db
@@@ -2956,14 -2956,17 +2956,17 @@@ again
                        if (err < 0)
                                goto out;
  
-               } else if (sbi->s_cluster_ratio > 1 && end >= ex_end) {
+               } else if (sbi->s_cluster_ratio > 1 && end >= ex_end &&
+                          partial.state == initial) {
                        /*
-                        * If there's an extent to the right its first cluster
-                        * contains the immediate right boundary of the
-                        * truncated/punched region.  Set partial_cluster to
-                        * its negative value so it won't be freed if shared
-                        * with the current extent.  The end < ee_block case
-                        * is handled in ext4_ext_rm_leaf().
+                        * If we're punching, there's an extent to the right.
+                        * If the partial cluster hasn't been set, set it to
+                        * that extent's first cluster and its state to nofree
+                        * so it won't be freed should it contain blocks to be
+                        * removed. If it's already set (tofree/nofree), we're
+                        * retrying and keep the original partial cluster info
+                        * so a cluster marked tofree as a result of earlier
+                        * extent removal is not lost.
                         */
                        lblk = ex_end + 1;
                        err = ext4_ext_search_right(inode, path, &lblk, &pblk,
@@@ -3631,7 -3634,7 +3634,7 @@@ static int ext4_ext_convert_to_initiali
                max_zeroout = sbi->s_extent_max_zeroout_kb >>
                        (inode->i_sb->s_blocksize_bits - 10);
  
 -      if (ext4_encrypted_inode(inode))
 +      if (IS_ENCRYPTED(inode))
                max_zeroout = 0;
  
        /*
@@@ -4048,18 -4051,8 +4051,8 @@@ out
        } else
                allocated = ret;
        map->m_flags |= EXT4_MAP_NEW;
-       /*
-        * if we allocated more blocks than requested
-        * we need to make sure we unmap the extra block
-        * allocated. The actual needed block will get
-        * unmapped later when we find the buffer_head marked
-        * new.
-        */
-       if (allocated > map->m_len) {
-               clean_bdev_aliases(inode->i_sb->s_bdev, newblock + map->m_len,
-                                  allocated - map->m_len);
+       if (allocated > map->m_len)
                allocated = map->m_len;
-       }
        map->m_len = allocated;
  
  map_out:
@@@ -4818,7 -4811,7 +4811,7 @@@ long ext4_fallocate(struct file *file, 
         * leave it disabled for encrypted inodes for now.  This is a
         * bug we should fix....
         */
 -      if (ext4_encrypted_inode(inode) &&
 +      if (IS_ENCRYPTED(inode) &&
            (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE |
                     FALLOC_FL_ZERO_RANGE)))
                return -EOPNOTSUPP;
diff --combined fs/ext4/inode.c
index 4356ef6d728e4019e06742587adba90764caeba3,f84cf62fd2903f9076a67942f727deb644c688b8..b54b261ded36f92076d95197e6c456e5bd17698a
@@@ -391,7 -391,7 +391,7 @@@ void ext4_da_update_reserve_space(struc
         * inode's preallocations.
         */
        if ((ei->i_reserved_data_blocks == 0) &&
-           (atomic_read(&inode->i_writecount) == 0))
+           !inode_is_open_for_write(inode))
                ext4_discard_preallocations(inode);
  }
  
@@@ -415,7 -415,7 +415,7 @@@ int ext4_issue_zeroout(struct inode *in
  {
        int ret;
  
 -      if (ext4_encrypted_inode(inode))
 +      if (IS_ENCRYPTED(inode))
                return fscrypt_zeroout_range(inode, lblk, pblk, len);
  
        ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
@@@ -678,8 -678,6 +678,6 @@@ found
                if (flags & EXT4_GET_BLOCKS_ZERO &&
                    map->m_flags & EXT4_MAP_MAPPED &&
                    map->m_flags & EXT4_MAP_NEW) {
-                       clean_bdev_aliases(inode->i_sb->s_bdev, map->m_pblk,
-                                          map->m_len);
                        ret = ext4_issue_zeroout(inode, map->m_lblk,
                                                 map->m_pblk, map->m_len);
                        if (ret) {
@@@ -1150,7 -1148,7 +1148,7 @@@ int do_journal_get_write_access(handle_
        return ret;
  }
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
                                  get_block_t *get_block)
  {
                        if (err)
                                break;
                        if (buffer_new(bh)) {
-                               clean_bdev_bh_alias(bh);
                                if (PageUptodate(page)) {
                                        clear_buffer_new(bh);
                                        set_buffer_uptodate(bh);
                    (block_start < from || block_end > to)) {
                        ll_rw_block(REQ_OP_READ, 0, 1, &bh);
                        *wait_bh++ = bh;
 -                      decrypt = ext4_encrypted_inode(inode) &&
 -                              S_ISREG(inode->i_mode);
 +                      decrypt = IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
                }
        }
        /*
@@@ -1302,7 -1300,7 +1299,7 @@@ retry_journal
        /* In case writeback began while the page was unlocked */
        wait_for_stable_page(page);
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
        if (ext4_should_dioread_nolock(inode))
                ret = ext4_block_write_begin(page, pos, len,
                                             ext4_get_block_unwritten);
@@@ -2489,10 -2487,6 +2486,6 @@@ static int mpage_map_one_extent(handle_
        }
  
        BUG_ON(map->m_len == 0);
-       if (map->m_flags & EXT4_MAP_NEW) {
-               clean_bdev_aliases(inode->i_sb->s_bdev, map->m_pblk,
-                                  map->m_len);
-       }
        return 0;
  }
  
@@@ -2835,12 -2829,12 +2828,12 @@@ retry
                goto unplug;
        }
        ret = mpage_prepare_extent_to_map(&mpd);
+       /* Unlock pages we didn't use */
+       mpage_release_unused_pages(&mpd, false);
        /* Submit prepared bio */
        ext4_io_submit(&mpd.io_submit);
        ext4_put_io_end_defer(mpd.io_submit.io_end);
        mpd.io_submit.io_end = NULL;
-       /* Unlock pages we didn't use */
-       mpage_release_unused_pages(&mpd, false);
        if (ret < 0)
                goto unplug;
  
                        handle = NULL;
                        mpd.do_map = 0;
                }
-               /* Submit prepared bio */
-               ext4_io_submit(&mpd.io_submit);
                /* Unlock pages we didn't use */
                mpage_release_unused_pages(&mpd, give_up_on_write);
+               /* Submit prepared bio */
+               ext4_io_submit(&mpd.io_submit);
                /*
                 * Drop our io_end reference we got from init. We have
                 * to be careful and use deferred io_end finishing if
@@@ -3104,7 -3099,7 +3098,7 @@@ retry_journal
        /* In case writeback began while the page was unlocked */
        wait_for_stable_page(page);
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
        ret = ext4_block_write_begin(page, pos, len,
                                     ext4_da_get_block_prep);
  #else
@@@ -3879,8 -3874,8 +3873,8 @@@ static ssize_t ext4_direct_IO(struct ki
        loff_t offset = iocb->ki_pos;
        ssize_t ret;
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 -      if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
 +#ifdef CONFIG_FS_ENCRYPTION
 +      if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
                return 0;
  #endif
  
@@@ -4064,7 -4059,8 +4058,7 @@@ static int __ext4_block_zero_page_range
                /* Uhhuh. Read error. Complain and punt. */
                if (!buffer_uptodate(bh))
                        goto unlock;
 -              if (S_ISREG(inode->i_mode) &&
 -                  ext4_encrypted_inode(inode)) {
 +              if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) {
                        /* We expect the key to be set. */
                        BUG_ON(!fscrypt_has_encryption_key(inode));
                        BUG_ON(blocksize != PAGE_SIZE);
@@@ -4140,7 -4136,7 +4134,7 @@@ static int ext4_block_truncate_page(han
        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))
 +      if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode))
                return 0;
  
        blocksize = inode->i_sb->s_blocksize;
@@@ -4720,7 -4716,7 +4714,7 @@@ static bool ext4_should_use_dax(struct 
                return false;
        if (ext4_has_inline_data(inode))
                return false;
 -      if (ext4_encrypted_inode(inode))
 +      if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
                return false;
        return true;
  }
@@@ -5070,7 -5066,7 +5064,7 @@@ struct inode *__ext4_iget(struct super_
                        ret = -EFSCORRUPTED;
                        goto bad_inode;
                }
 -              if (ext4_encrypted_inode(inode)) {
 +              if (IS_ENCRYPTED(inode)) {
                        inode->i_op = &ext4_encrypted_symlink_inode_operations;
                        ext4_set_aops(inode);
                } else if (ext4_inode_is_fast_symlink(inode)) {
@@@ -5349,7 -5345,6 +5343,6 @@@ static int ext4_do_update_inode(handle_
                err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
                if (err)
                        goto out_brelse;
-               ext4_update_dynamic_rev(sb);
                ext4_set_feature_large_file(sb);
                ext4_handle_sync(handle);
                err = ext4_handle_dirty_super(handle, sb);
@@@ -6000,7 -5995,7 +5993,7 @@@ int ext4_expand_extra_isize(struct inod
  
        ext4_write_lock_xattr(inode, &no_expand);
  
-       BUFFER_TRACE(iloc.bh, "get_write_access");
+       BUFFER_TRACE(iloc->bh, "get_write_access");
        error = ext4_journal_get_write_access(handle, iloc->bh);
        if (error) {
                brelse(iloc->bh);
diff --combined fs/ext4/ioctl.c
index d26bcac291bbc0299ad3f85899ebe12f9a9faca0,eb8ca8d80885ad917d9892a26c467dbae6a436e9..3c4f8bb59f8abfd23ceaf36f93c7fceffac0134e
@@@ -63,18 -63,20 +63,20 @@@ static void swap_inode_data(struct inod
        loff_t isize;
        struct ext4_inode_info *ei1;
        struct ext4_inode_info *ei2;
+       unsigned long tmp;
  
        ei1 = EXT4_I(inode1);
        ei2 = EXT4_I(inode2);
  
        swap(inode1->i_version, inode2->i_version);
-       swap(inode1->i_blocks, inode2->i_blocks);
-       swap(inode1->i_bytes, inode2->i_bytes);
        swap(inode1->i_atime, inode2->i_atime);
        swap(inode1->i_mtime, inode2->i_mtime);
  
        memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
-       swap(ei1->i_flags, ei2->i_flags);
+       tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
+       ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) |
+               (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP);
+       ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP);
        swap(ei1->i_disksize, ei2->i_disksize);
        ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
        ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
@@@ -115,28 -117,42 +117,42 @@@ static long swap_inode_boot_loader(stru
        int err;
        struct inode *inode_bl;
        struct ext4_inode_info *ei_bl;
-       if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
-           IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
-           ext4_has_inline_data(inode))
-               return -EINVAL;
-       if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
-           !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
-               return -EPERM;
+       qsize_t size, size_bl, diff;
+       blkcnt_t blocks;
+       unsigned short bytes;
  
        inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
        if (IS_ERR(inode_bl))
                return PTR_ERR(inode_bl);
        ei_bl = EXT4_I(inode_bl);
  
-       filemap_flush(inode->i_mapping);
-       filemap_flush(inode_bl->i_mapping);
        /* Protect orig inodes against a truncate and make sure,
         * that only 1 swap_inode_boot_loader is running. */
        lock_two_nondirectories(inode, inode_bl);
  
+       if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
+           IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
+           (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) ||
+           ext4_has_inline_data(inode)) {
+               err = -EINVAL;
+               goto journal_err_out;
+       }
+       if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
+           !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto journal_err_out;
+       }
+       down_write(&EXT4_I(inode)->i_mmap_sem);
+       err = filemap_write_and_wait(inode->i_mapping);
+       if (err)
+               goto err_out;
+       err = filemap_write_and_wait(inode_bl->i_mapping);
+       if (err)
+               goto err_out;
        /* Wait for all existing dio workers */
        inode_dio_wait(inode);
        inode_dio_wait(inode_bl);
        handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
        if (IS_ERR(handle)) {
                err = -EINVAL;
-               goto journal_err_out;
+               goto err_out;
        }
  
        /* Protect extent tree against block allocations via delalloc */
                        memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
        }
  
+       err = dquot_initialize(inode);
+       if (err)
+               goto err_out1;
+       size = (qsize_t)(inode->i_blocks) * (1 << 9) + inode->i_bytes;
+       size_bl = (qsize_t)(inode_bl->i_blocks) * (1 << 9) + inode_bl->i_bytes;
+       diff = size - size_bl;
        swap_inode_data(inode, inode_bl);
  
        inode->i_ctime = inode_bl->i_ctime = current_time(inode);
  
        err = ext4_mark_inode_dirty(handle, inode);
        if (err < 0) {
+               /* No need to update quota information. */
                ext4_warning(inode->i_sb,
                        "couldn't mark inode #%lu dirty (err %d)",
                        inode->i_ino, err);
                /* Revert all changes: */
                swap_inode_data(inode, inode_bl);
                ext4_mark_inode_dirty(handle, inode);
-       } else {
-               err = ext4_mark_inode_dirty(handle, inode_bl);
-               if (err < 0) {
-                       ext4_warning(inode_bl->i_sb,
-                               "couldn't mark inode #%lu dirty (err %d)",
-                               inode_bl->i_ino, err);
-                       /* Revert all changes: */
-                       swap_inode_data(inode, inode_bl);
-                       ext4_mark_inode_dirty(handle, inode);
-                       ext4_mark_inode_dirty(handle, inode_bl);
-               }
+               goto err_out1;
+       }
+       blocks = inode_bl->i_blocks;
+       bytes = inode_bl->i_bytes;
+       inode_bl->i_blocks = inode->i_blocks;
+       inode_bl->i_bytes = inode->i_bytes;
+       err = ext4_mark_inode_dirty(handle, inode_bl);
+       if (err < 0) {
+               /* No need to update quota information. */
+               ext4_warning(inode_bl->i_sb,
+                       "couldn't mark inode #%lu dirty (err %d)",
+                       inode_bl->i_ino, err);
+               goto revert;
+       }
+       /* Bootloader inode should not be counted into quota information. */
+       if (diff > 0)
+               dquot_free_space(inode, diff);
+       else
+               err = dquot_alloc_space(inode, -1 * diff);
+       if (err < 0) {
+ revert:
+               /* Revert all changes: */
+               inode_bl->i_blocks = blocks;
+               inode_bl->i_bytes = bytes;
+               swap_inode_data(inode, inode_bl);
+               ext4_mark_inode_dirty(handle, inode);
+               ext4_mark_inode_dirty(handle, inode_bl);
        }
+ err_out1:
        ext4_journal_stop(handle);
        ext4_double_up_write_data_sem(inode, inode_bl);
  
+ err_out:
+       up_write(&EXT4_I(inode)->i_mmap_sem);
  journal_err_out:
        unlock_two_nondirectories(inode, inode_bl);
        iput(inode_bl);
        return err;
  }
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  static int uuid_is_zero(__u8 u[16])
  {
        int     i;
@@@ -978,7 -1025,7 +1025,7 @@@ resizefs_out
                return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
  
        case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
                int err, err2;
                struct ext4_sb_info *sbi = EXT4_SB(sb);
                handle_t *handle;
diff --combined fs/ext4/page-io.c
index 6f5305e9a6acccc62c025caed44f47ded8af9947,15599466809b30f3c2213659841580fd9563b2f2..3e9298e6a705a00b80475fdaf173f58a1177ea85
@@@ -63,11 -63,10 +63,11 @@@ static void ext4_finish_bio(struct bio 
  {
        int i;
        struct bio_vec *bvec;
 +      struct bvec_iter_all iter_all;
  
 -      bio_for_each_segment_all(bvec, bio, i) {
 +      bio_for_each_segment_all(bvec, bio, i, iter_all) {
                struct page *page = bvec->bv_page;
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
                struct page *data_page = NULL;
  #endif
                struct buffer_head *bh, *head;
@@@ -79,7 -78,7 +79,7 @@@
                if (!page)
                        continue;
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
                if (!page->mapping) {
                        /* The bounce data pages are unmapped. */
                        data_page = page;
                bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
                local_irq_restore(flags);
                if (!under_io) {
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
                        if (data_page)
                                fscrypt_restore_control_page(data_page);
  #endif
@@@ -468,17 -467,16 +468,15 @@@ int ext4_bio_write_page(struct ext4_io_
                                ext4_io_submit(io);
                        continue;
                }
-               if (buffer_new(bh)) {
+               if (buffer_new(bh))
                        clear_buffer_new(bh);
-                       clean_bdev_bh_alias(bh);
-               }
                set_buffer_async_write(bh);
                nr_to_submit++;
        } while ((bh = bh->b_this_page) != head);
  
        bh = head = page_buffers(page);
  
 -      if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
 -          nr_to_submit) {
 +      if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) {
                gfp_t gfp_flags = GFP_NOFS;
  
        retry_encrypt:
diff --combined fs/ext4/super.c
index 60da0a6e4d8617bc301a43c86530214145f32fd5,6e4cac6463459ce5b1a34bcf20c3534d81f2ba77..f5b828bf1299f1998d7b8ac2696b979c8f303079
@@@ -1232,7 -1232,7 +1232,7 @@@ static int bdev_try_to_free_page(struc
        return try_to_free_buffers(page);
  }
  
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
  {
        return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
@@@ -1922,7 -1922,7 +1922,7 @@@ static int handle_mount_opt(struct supe
                *journal_ioprio =
                        IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
        } else if (token == Opt_test_dummy_encryption) {
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
                sbi->s_mount_flags |= EXT4_MF_TEST_DUMMY_ENCRYPTION;
                ext4_msg(sb, KERN_WARNING,
                         "Test dummy encryption mode enabled");
@@@ -2249,7 -2249,6 +2249,6 @@@ static int ext4_setup_super(struct supe
                es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT);
        le16_add_cpu(&es->s_mnt_count, 1);
        ext4_update_tstamp(es, s_mtime);
-       ext4_update_dynamic_rev(sb);
        if (sbi->s_journal)
                ext4_set_feature_journal_needs_recovery(sb);
  
@@@ -4167,7 -4166,7 +4166,7 @@@ static int ext4_fill_super(struct super
        sb->s_op = &ext4_sops;
        sb->s_export_op = &ext4_export_ops;
        sb->s_xattr = ext4_xattr_handlers;
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
        sb->s_cop = &ext4_cryptops;
  #endif
  #ifdef CONFIG_QUOTA
diff --combined fs/ext4/sysfs.c
index 5e4e78fc0b3a2b342a3db60f5cff747f3b95e259,1748e6362d9796094116aa934bd49d5854e1315f..616c075da062a3fdb0cf5e4c23be1f90e7722d60
@@@ -30,6 -30,7 +30,7 @@@ typedef enum 
        attr_feature,
        attr_pointer_ui,
        attr_pointer_atomic,
+       attr_journal_task,
  } attr_id_t;
  
  typedef enum {
@@@ -125,6 -126,14 +126,14 @@@ static ssize_t trigger_test_error(struc
        return count;
  }
  
+ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
+ {
+       if (!sbi->s_journal)
+               return snprintf(buf, PAGE_SIZE, "<none>\n");
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+                       task_pid_vnr(sbi->s_journal->j_task));
+ }
  #define EXT4_ATTR(_name,_mode,_id)                                    \
  static struct ext4_attr ext4_attr_##_name = {                         \
        .attr = {.name = __stringify(_name), .mode = _mode },           \
@@@ -188,6 -197,7 +197,7 @@@ EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst
  EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
  EXT4_ATTR(first_error_time, 0444, first_error_time);
  EXT4_ATTR(last_error_time, 0444, last_error_time);
+ EXT4_ATTR(journal_task, 0444, journal_task);
  
  static unsigned int old_bump_val = 128;
  EXT4_ATTR_PTR(max_writeback_mb_bump, 0444, pointer_ui, &old_bump_val);
@@@ -217,6 -227,7 +227,7 @@@ static struct attribute *ext4_attrs[] 
        ATTR_LIST(errors_count),
        ATTR_LIST(first_error_time),
        ATTR_LIST(last_error_time),
+       ATTR_LIST(journal_task),
        NULL,
  };
  
  EXT4_ATTR_FEATURE(lazy_itable_init);
  EXT4_ATTR_FEATURE(batched_discard);
  EXT4_ATTR_FEATURE(meta_bg_resize);
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
  EXT4_ATTR_FEATURE(encryption);
  #endif
  EXT4_ATTR_FEATURE(metadata_csum_seed);
@@@ -233,7 -244,7 +244,7 @@@ static struct attribute *ext4_feat_attr
        ATTR_LIST(lazy_itable_init),
        ATTR_LIST(batched_discard),
        ATTR_LIST(meta_bg_resize),
 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
 +#ifdef CONFIG_FS_ENCRYPTION
        ATTR_LIST(encryption),
  #endif
        ATTR_LIST(metadata_csum_seed),
@@@ -304,6 -315,8 +315,8 @@@ static ssize_t ext4_attr_show(struct ko
                return print_tstamp(buf, sbi->s_es, s_first_error_time);
        case attr_last_error_time:
                return print_tstamp(buf, sbi->s_es, s_last_error_time);
+       case attr_journal_task:
+               return journal_task_show(sbi, buf);
        }
  
        return 0;