Merge tag 'for-5.15/io_uring-2021-09-04' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / fs / ext4 / inode.c
index d47a57f..d18852d 100644 (file)
@@ -3957,20 +3957,19 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
        return ret;
 }
 
-static void ext4_wait_dax_page(struct ext4_inode_info *ei)
+static void ext4_wait_dax_page(struct inode *inode)
 {
-       up_write(&ei->i_mmap_sem);
+       filemap_invalidate_unlock(inode->i_mapping);
        schedule();
-       down_write(&ei->i_mmap_sem);
+       filemap_invalidate_lock(inode->i_mapping);
 }
 
 int ext4_break_layouts(struct inode *inode)
 {
-       struct ext4_inode_info *ei = EXT4_I(inode);
        struct page *page;
        int error;
 
-       if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
+       if (WARN_ON_ONCE(!rwsem_is_locked(&inode->i_mapping->invalidate_lock)))
                return -EINVAL;
 
        do {
@@ -3981,7 +3980,7 @@ int ext4_break_layouts(struct inode *inode)
                error = ___wait_var_event(&page->_refcount,
                                atomic_read(&page->_refcount) == 1,
                                TASK_INTERRUPTIBLE, 0, 0,
-                               ext4_wait_dax_page(ei));
+                               ext4_wait_dax_page(inode));
        } while (error == 0);
 
        return error;
@@ -4012,9 +4011,9 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
 
        ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
        if (ext4_has_inline_data(inode)) {
-               down_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_lock(mapping);
                ret = ext4_convert_inline_data(inode);
-               up_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_unlock(mapping);
                if (ret)
                        return ret;
        }
@@ -4065,7 +4064,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
         * Prevent page faults from reinstantiating pages we have released from
         * page cache.
         */
-       down_write(&EXT4_I(inode)->i_mmap_sem);
+       filemap_invalidate_lock(mapping);
 
        ret = ext4_break_layouts(inode);
        if (ret)
@@ -4138,7 +4137,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
 out_stop:
        ext4_journal_stop(handle);
 out_dio:
-       up_write(&EXT4_I(inode)->i_mmap_sem);
+       filemap_invalidate_unlock(mapping);
 out_mutex:
        inode_unlock(inode);
        return ret;
@@ -4337,101 +4336,93 @@ static int __ext4_get_inode_loc(struct super_block *sb, unsigned long ino,
        bh = sb_getblk(sb, block);
        if (unlikely(!bh))
                return -ENOMEM;
-       if (ext4_simulate_fail(sb, EXT4_SIM_INODE_EIO))
-               goto simulate_eio;
-       if (!buffer_uptodate(bh)) {
-               lock_buffer(bh);
-
-               if (ext4_buffer_uptodate(bh)) {
-                       /* someone brought it uptodate while we waited */
-                       unlock_buffer(bh);
-                       goto has_buffer;
-               }
+       if (ext4_buffer_uptodate(bh))
+               goto has_buffer;
 
-               /*
-                * If we have all information of the inode in memory and this
-                * is the only valid inode in the block, we need not read the
-                * block.
-                */
-               if (in_mem) {
-                       struct buffer_head *bitmap_bh;
-                       int i, start;
+       lock_buffer(bh);
+       /*
+        * If we have all information of the inode in memory and this
+        * is the only valid inode in the block, we need not read the
+        * block.
+        */
+       if (in_mem) {
+               struct buffer_head *bitmap_bh;
+               int i, start;
 
-                       start = inode_offset & ~(inodes_per_block - 1);
+               start = inode_offset & ~(inodes_per_block - 1);
 
-                       /* Is the inode bitmap in cache? */
-                       bitmap_bh = sb_getblk(sb, ext4_inode_bitmap(sb, gdp));
-                       if (unlikely(!bitmap_bh))
-                               goto make_io;
+               /* Is the inode bitmap in cache? */
+               bitmap_bh = sb_getblk(sb, ext4_inode_bitmap(sb, gdp));
+               if (unlikely(!bitmap_bh))
+                       goto make_io;
 
-                       /*
-                        * If the inode bitmap isn't in cache then the
-                        * optimisation may end up performing two reads instead
-                        * of one, so skip it.
-                        */
-                       if (!buffer_uptodate(bitmap_bh)) {
-                               brelse(bitmap_bh);
-                               goto make_io;
-                       }
-                       for (i = start; i < start + inodes_per_block; i++) {
-                               if (i == inode_offset)
-                                       continue;
-                               if (ext4_test_bit(i, bitmap_bh->b_data))
-                                       break;
-                       }
+               /*
+                * If the inode bitmap isn't in cache then the
+                * optimisation may end up performing two reads instead
+                * of one, so skip it.
+                */
+               if (!buffer_uptodate(bitmap_bh)) {
                        brelse(bitmap_bh);
-                       if (i == start + inodes_per_block) {
-                               /* all other inodes are free, so skip I/O */
-                               memset(bh->b_data, 0, bh->b_size);
-                               set_buffer_uptodate(bh);
-                               unlock_buffer(bh);
-                               goto has_buffer;
-                       }
+                       goto make_io;
+               }
+               for (i = start; i < start + inodes_per_block; i++) {
+                       if (i == inode_offset)
+                               continue;
+                       if (ext4_test_bit(i, bitmap_bh->b_data))
+                               break;
+               }
+               brelse(bitmap_bh);
+               if (i == start + inodes_per_block) {
+                       /* all other inodes are free, so skip I/O */
+                       memset(bh->b_data, 0, bh->b_size);
+                       set_buffer_uptodate(bh);
+                       unlock_buffer(bh);
+                       goto has_buffer;
                }
+       }
 
 make_io:
-               /*
-                * If we need to do any I/O, try to pre-readahead extra
-                * blocks from the inode table.
-                */
-               blk_start_plug(&plug);
-               if (EXT4_SB(sb)->s_inode_readahead_blks) {
-                       ext4_fsblk_t b, end, table;
-                       unsigned num;
-                       __u32 ra_blks = EXT4_SB(sb)->s_inode_readahead_blks;
-
-                       table = ext4_inode_table(sb, gdp);
-                       /* s_inode_readahead_blks is always a power of 2 */
-                       b = block & ~((ext4_fsblk_t) ra_blks - 1);
-                       if (table > b)
-                               b = table;
-                       end = b + ra_blks;
-                       num = EXT4_INODES_PER_GROUP(sb);
-                       if (ext4_has_group_desc_csum(sb))
-                               num -= ext4_itable_unused_count(sb, gdp);
-                       table += num / inodes_per_block;
-                       if (end > table)
-                               end = table;
-                       while (b <= end)
-                               ext4_sb_breadahead_unmovable(sb, b++);
-               }
+       /*
+        * If we need to do any I/O, try to pre-readahead extra
+        * blocks from the inode table.
+        */
+       blk_start_plug(&plug);
+       if (EXT4_SB(sb)->s_inode_readahead_blks) {
+               ext4_fsblk_t b, end, table;
+               unsigned num;
+               __u32 ra_blks = EXT4_SB(sb)->s_inode_readahead_blks;
+
+               table = ext4_inode_table(sb, gdp);
+               /* s_inode_readahead_blks is always a power of 2 */
+               b = block & ~((ext4_fsblk_t) ra_blks - 1);
+               if (table > b)
+                       b = table;
+               end = b + ra_blks;
+               num = EXT4_INODES_PER_GROUP(sb);
+               if (ext4_has_group_desc_csum(sb))
+                       num -= ext4_itable_unused_count(sb, gdp);
+               table += num / inodes_per_block;
+               if (end > table)
+                       end = table;
+               while (b <= end)
+                       ext4_sb_breadahead_unmovable(sb, b++);
+       }
 
-               /*
-                * There are other valid inodes in the buffer, this inode
-                * has in-inode xattrs, or we don't have this inode in memory.
-                * Read the block from disk.
-                */
-               trace_ext4_load_inode(sb, ino);
-               ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, NULL);
-               blk_finish_plug(&plug);
-               wait_on_buffer(bh);
-               if (!buffer_uptodate(bh)) {
-               simulate_eio:
-                       if (ret_block)
-                               *ret_block = block;
-                       brelse(bh);
-                       return -EIO;
-               }
+       /*
+        * There are other valid inodes in the buffer, this inode
+        * has in-inode xattrs, or we don't have this inode in memory.
+        * Read the block from disk.
+        */
+       trace_ext4_load_inode(sb, ino);
+       ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, NULL);
+       blk_finish_plug(&plug);
+       wait_on_buffer(bh);
+       ext4_simulate_fail_bh(sb, bh, EXT4_SIM_INODE_EIO);
+       if (!buffer_uptodate(bh)) {
+               if (ret_block)
+                       *ret_block = block;
+               brelse(bh);
+               return -EIO;
        }
 has_buffer:
        iloc->bh = bh;
@@ -4624,7 +4615,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
             ((ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) ||
              ino == le32_to_cpu(es->s_usr_quota_inum) ||
              ino == le32_to_cpu(es->s_grp_quota_inum) ||
-             ino == le32_to_cpu(es->s_prj_quota_inum))) ||
+             ino == le32_to_cpu(es->s_prj_quota_inum) ||
+             ino == le32_to_cpu(es->s_orphan_file_inum))) ||
            (ino < EXT4_ROOT_INO) ||
            (ino > le32_to_cpu(es->s_inodes_count))) {
                if (flags & EXT4_IGET_HANDLE)
@@ -4939,8 +4931,14 @@ static int ext4_inode_blocks_set(handle_t *handle,
                ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE);
                return 0;
        }
+
+       /*
+        * This should never happen since sb->s_maxbytes should not have
+        * allowed this, sb->s_maxbytes was set according to the huge_file
+        * feature in ext4_fill_super().
+        */
        if (!ext4_has_feature_huge_file(sb))
-               return -EFBIG;
+               return -EFSCORRUPTED;
 
        if (i_blocks <= 0xffffffffffffULL) {
                /*
@@ -5043,16 +5041,14 @@ static int ext4_do_update_inode(handle_t *handle,
 
        spin_lock(&ei->i_raw_lock);
 
-       /* For fields not tracked in the in-memory inode,
-        * initialise them to zero for new inodes. */
+       /*
+        * For fields not tracked in the in-memory inode, initialise them
+        * to zero for new inodes.
+        */
        if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
                memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
 
        err = ext4_inode_blocks_set(handle, raw_inode, ei);
-       if (err) {
-               spin_unlock(&ei->i_raw_lock);
-               goto out_brelse;
-       }
 
        raw_inode->i_mode = cpu_to_le16(inode->i_mode);
        i_uid = i_uid_read(inode);
@@ -5061,10 +5057,11 @@ static int ext4_do_update_inode(handle_t *handle,
        if (!(test_opt(inode->i_sb, NO_UID32))) {
                raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
                raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
-/*
- * Fix up interoperability with old kernels. Otherwise, old inodes get
- * re-used with the upper 16 bits of the uid/gid intact
- */
+               /*
+                * Fix up interoperability with old kernels. Otherwise,
+                * old inodes get re-used with the upper 16 bits of the
+                * uid/gid intact.
+                */
                if (ei->i_dtime && list_empty(&ei->i_orphan)) {
                        raw_inode->i_uid_high = 0;
                        raw_inode->i_gid_high = 0;
@@ -5133,8 +5130,9 @@ static int ext4_do_update_inode(handle_t *handle,
                }
        }
 
-       BUG_ON(!ext4_has_feature_project(inode->i_sb) &&
-              i_projid != EXT4_DEF_PROJID);
+       if (i_projid != EXT4_DEF_PROJID &&
+           !ext4_has_feature_project(inode->i_sb))
+               err = err ?: -EFSCORRUPTED;
 
        if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
            EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))
@@ -5142,6 +5140,11 @@ static int ext4_do_update_inode(handle_t *handle,
 
        ext4_inode_csum_set(inode, raw_inode, ei);
        spin_unlock(&ei->i_raw_lock);
+       if (err) {
+               EXT4_ERROR_INODE(inode, "corrupted inode contents");
+               goto out_brelse;
+       }
+
        if (inode->i_sb->s_flags & SB_LAZYTIME)
                ext4_update_other_inodes_time(inode->i_sb, inode->i_ino,
                                              bh->b_data);
@@ -5149,7 +5152,7 @@ static int ext4_do_update_inode(handle_t *handle,
        BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
        err = ext4_handle_dirty_metadata(handle, NULL, bh);
        if (err)
-               goto out_brelse;
+               goto out_error;
        ext4_clear_inode_state(inode, EXT4_STATE_NEW);
        if (set_large_file) {
                BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access");
@@ -5157,7 +5160,7 @@ static int ext4_do_update_inode(handle_t *handle,
                                                    EXT4_SB(sb)->s_sbh,
                                                    EXT4_JTR_NONE);
                if (err)
-                       goto out_brelse;
+                       goto out_error;
                lock_buffer(EXT4_SB(sb)->s_sbh);
                ext4_set_feature_large_file(sb);
                ext4_superblock_csum_set(sb);
@@ -5167,9 +5170,10 @@ static int ext4_do_update_inode(handle_t *handle,
                                                 EXT4_SB(sb)->s_sbh);
        }
        ext4_update_inode_fsync_trans(handle, inode, need_datasync);
+out_error:
+       ext4_std_error(inode->i_sb, err);
 out_brelse:
        brelse(bh);
-       ext4_std_error(inode->i_sb, err);
        return err;
 }
 
@@ -5439,11 +5443,11 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
                        inode_dio_wait(inode);
                }
 
-               down_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_lock(inode->i_mapping);
 
                rc = ext4_break_layouts(inode);
                if (rc) {
-                       up_write(&EXT4_I(inode)->i_mmap_sem);
+                       filemap_invalidate_unlock(inode->i_mapping);
                        goto err_out;
                }
 
@@ -5519,7 +5523,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
                                error = rc;
                }
 out_mmap_sem:
-               up_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_unlock(inode->i_mapping);
        }
 
        if (!error) {
@@ -5998,10 +6002,10 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
         * data (and journalled aops don't know how to handle these cases).
         */
        if (val) {
-               down_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_lock(inode->i_mapping);
                err = filemap_write_and_wait(inode->i_mapping);
                if (err < 0) {
-                       up_write(&EXT4_I(inode)->i_mmap_sem);
+                       filemap_invalidate_unlock(inode->i_mapping);
                        return err;
                }
        }
@@ -6034,7 +6038,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
        percpu_up_write(&sbi->s_writepages_rwsem);
 
        if (val)
-               up_write(&EXT4_I(inode)->i_mmap_sem);
+               filemap_invalidate_unlock(inode->i_mapping);
 
        /* Finally we can mark the inode as dirty. */
 
@@ -6079,7 +6083,7 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf)
        sb_start_pagefault(inode->i_sb);
        file_update_time(vma->vm_file);
 
-       down_read(&EXT4_I(inode)->i_mmap_sem);
+       filemap_invalidate_lock_shared(mapping);
 
        err = ext4_convert_inline_data(inode);
        if (err)
@@ -6194,7 +6198,7 @@ retry_alloc:
 out_ret:
        ret = block_page_mkwrite_return(err);
 out:
-       up_read(&EXT4_I(inode)->i_mmap_sem);
+       filemap_invalidate_unlock_shared(mapping);
        sb_end_pagefault(inode->i_sb);
        return ret;
 out_error:
@@ -6202,15 +6206,3 @@ out_error:
        ext4_journal_stop(handle);
        goto out;
 }
-
-vm_fault_t ext4_filemap_fault(struct vm_fault *vmf)
-{
-       struct inode *inode = file_inode(vmf->vma->vm_file);
-       vm_fault_t ret;
-
-       down_read(&EXT4_I(inode)->i_mmap_sem);
-       ret = filemap_fault(vmf);
-       up_read(&EXT4_I(inode)->i_mmap_sem);
-
-       return ret;
-}