diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-06 15:19:23 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-06 15:19:23 -0500 |
| commit | 215240462a9672db771bb60adcc1c4fdf40e8ec4 (patch) | |
| tree | 0dddb216e9a4e9af2c7d1e004004f689f013219f | |
| parent | e2b745f469ec0f3165ba5ffaee3ce40f98d77878 (diff) | |
| parent | 191ce17876c9367819c4b0a25b503c0f6d9054d8 (diff) | |
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bug fixes from Ted Ts'o:
"Fix a number of ext4 bugs"
* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: fix special inode number checks in __ext4_iget()
ext4: track writeback errors using the generic tracking infrastructure
ext4: use ext4_write_inode() when fsyncing w/o a journal
ext4: avoid kernel warning when writing the superblock to a dead device
ext4: fix a potential fiemap/page fault deadlock w/ inline_data
ext4: make sure enough credits are reserved for dioread_nolock writes
| -rw-r--r-- | fs/ext4/fsync.c | 16 | ||||
| -rw-r--r-- | fs/ext4/inline.c | 6 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 5 | ||||
| -rw-r--r-- | fs/ext4/super.c | 2 |
4 files changed, 19 insertions, 10 deletions
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 26a7fe5c4fd3..712f00995390 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
| @@ -116,8 +116,16 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 116 | goto out; | 116 | goto out; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | ret = file_write_and_wait_range(file, start, end); | ||
| 120 | if (ret) | ||
| 121 | return ret; | ||
| 122 | |||
| 119 | if (!journal) { | 123 | if (!journal) { |
| 120 | ret = __generic_file_fsync(file, start, end, datasync); | 124 | struct writeback_control wbc = { |
| 125 | .sync_mode = WB_SYNC_ALL | ||
| 126 | }; | ||
| 127 | |||
| 128 | ret = ext4_write_inode(inode, &wbc); | ||
| 121 | if (!ret) | 129 | if (!ret) |
| 122 | ret = ext4_sync_parent(inode); | 130 | ret = ext4_sync_parent(inode); |
| 123 | if (test_opt(inode->i_sb, BARRIER)) | 131 | if (test_opt(inode->i_sb, BARRIER)) |
| @@ -125,9 +133,6 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 125 | goto out; | 133 | goto out; |
| 126 | } | 134 | } |
| 127 | 135 | ||
| 128 | ret = file_write_and_wait_range(file, start, end); | ||
| 129 | if (ret) | ||
| 130 | return ret; | ||
| 131 | /* | 136 | /* |
| 132 | * data=writeback,ordered: | 137 | * data=writeback,ordered: |
| 133 | * The caller's filemap_fdatawrite()/wait will sync the data. | 138 | * The caller's filemap_fdatawrite()/wait will sync the data. |
| @@ -159,6 +164,9 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 159 | ret = err; | 164 | ret = err; |
| 160 | } | 165 | } |
| 161 | out: | 166 | out: |
| 167 | err = file_check_and_advance_wb_err(file); | ||
| 168 | if (ret == 0) | ||
| 169 | ret = err; | ||
| 162 | trace_ext4_sync_file_exit(inode, ret); | 170 | trace_ext4_sync_file_exit(inode, ret); |
| 163 | return ret; | 171 | return ret; |
| 164 | } | 172 | } |
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 27373d88b5f0..56f6e1782d5f 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
| @@ -1890,12 +1890,12 @@ int ext4_inline_data_fiemap(struct inode *inode, | |||
| 1890 | physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; | 1890 | physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; |
| 1891 | physical += offsetof(struct ext4_inode, i_block); | 1891 | physical += offsetof(struct ext4_inode, i_block); |
| 1892 | 1892 | ||
| 1893 | if (physical) | ||
| 1894 | error = fiemap_fill_next_extent(fieinfo, start, physical, | ||
| 1895 | inline_len, flags); | ||
| 1896 | brelse(iloc.bh); | 1893 | brelse(iloc.bh); |
| 1897 | out: | 1894 | out: |
| 1898 | up_read(&EXT4_I(inode)->xattr_sem); | 1895 | up_read(&EXT4_I(inode)->xattr_sem); |
| 1896 | if (physical) | ||
| 1897 | error = fiemap_fill_next_extent(fieinfo, start, physical, | ||
| 1898 | inline_len, flags); | ||
| 1899 | return (error < 0 ? error : 0); | 1899 | return (error < 0 ? error : 0); |
| 1900 | } | 1900 | } |
| 1901 | 1901 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9affabd07682..34d7e0703cc6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -2778,7 +2778,8 @@ static int ext4_writepages(struct address_space *mapping, | |||
| 2778 | * We may need to convert up to one extent per block in | 2778 | * We may need to convert up to one extent per block in |
| 2779 | * the page and we may dirty the inode. | 2779 | * the page and we may dirty the inode. |
| 2780 | */ | 2780 | */ |
| 2781 | rsv_blocks = 1 + (PAGE_SIZE >> inode->i_blkbits); | 2781 | rsv_blocks = 1 + ext4_chunk_trans_blocks(inode, |
| 2782 | PAGE_SIZE >> inode->i_blkbits); | ||
| 2782 | } | 2783 | } |
| 2783 | 2784 | ||
| 2784 | /* | 2785 | /* |
| @@ -4833,7 +4834,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, | |||
| 4833 | gid_t i_gid; | 4834 | gid_t i_gid; |
| 4834 | projid_t i_projid; | 4835 | projid_t i_projid; |
| 4835 | 4836 | ||
| 4836 | if (((flags & EXT4_IGET_NORMAL) && | 4837 | if ((!(flags & EXT4_IGET_SPECIAL) && |
| 4837 | (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || | 4838 | (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || |
| 4838 | (ino < EXT4_ROOT_INO) || | 4839 | (ino < EXT4_ROOT_INO) || |
| 4839 | (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { | 4840 | (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d6c142d73d99..fb12d3c17c1b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -4902,7 +4902,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
| 4902 | ext4_superblock_csum_set(sb); | 4902 | ext4_superblock_csum_set(sb); |
| 4903 | if (sync) | 4903 | if (sync) |
| 4904 | lock_buffer(sbh); | 4904 | lock_buffer(sbh); |
| 4905 | if (buffer_write_io_error(sbh)) { | 4905 | if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) { |
| 4906 | /* | 4906 | /* |
| 4907 | * Oh, dear. A previous attempt to write the | 4907 | * Oh, dear. A previous attempt to write the |
| 4908 | * superblock failed. This could happen because the | 4908 | * superblock failed. This could happen because the |
