Commit 21524046 authored by Linus Torvalds's avatar Linus Torvalds

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
parents e2b745f4 191ce178
...@@ -116,8 +116,16 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -116,8 +116,16 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
goto out; goto out;
} }
ret = file_write_and_wait_range(file, start, end);
if (ret)
return ret;
if (!journal) { if (!journal) {
ret = __generic_file_fsync(file, start, end, datasync); struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL
};
ret = ext4_write_inode(inode, &wbc);
if (!ret) if (!ret)
ret = ext4_sync_parent(inode); ret = ext4_sync_parent(inode);
if (test_opt(inode->i_sb, BARRIER)) 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,9 +133,6 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
goto out; goto out;
} }
ret = file_write_and_wait_range(file, start, end);
if (ret)
return ret;
/* /*
* data=writeback,ordered: * data=writeback,ordered:
* The caller's filemap_fdatawrite()/wait will sync the data. * 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,6 +164,9 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
ret = err; ret = err;
} }
out: out:
err = file_check_and_advance_wb_err(file);
if (ret == 0)
ret = err;
trace_ext4_sync_file_exit(inode, ret); trace_ext4_sync_file_exit(inode, ret);
return ret; return ret;
} }
...@@ -1890,12 +1890,12 @@ int ext4_inline_data_fiemap(struct inode *inode, ...@@ -1890,12 +1890,12 @@ int ext4_inline_data_fiemap(struct inode *inode,
physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data;
physical += offsetof(struct ext4_inode, i_block); physical += offsetof(struct ext4_inode, i_block);
if (physical)
error = fiemap_fill_next_extent(fieinfo, start, physical,
inline_len, flags);
brelse(iloc.bh); brelse(iloc.bh);
out: out:
up_read(&EXT4_I(inode)->xattr_sem); up_read(&EXT4_I(inode)->xattr_sem);
if (physical)
error = fiemap_fill_next_extent(fieinfo, start, physical,
inline_len, flags);
return (error < 0 ? error : 0); return (error < 0 ? error : 0);
} }
......
...@@ -2778,7 +2778,8 @@ static int ext4_writepages(struct address_space *mapping, ...@@ -2778,7 +2778,8 @@ static int ext4_writepages(struct address_space *mapping,
* We may need to convert up to one extent per block in * We may need to convert up to one extent per block in
* the page and we may dirty the inode. * the page and we may dirty the inode.
*/ */
rsv_blocks = 1 + (PAGE_SIZE >> inode->i_blkbits); rsv_blocks = 1 + ext4_chunk_trans_blocks(inode,
PAGE_SIZE >> inode->i_blkbits);
} }
/* /*
...@@ -4833,7 +4834,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ...@@ -4833,7 +4834,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
gid_t i_gid; gid_t i_gid;
projid_t i_projid; projid_t i_projid;
if (((flags & EXT4_IGET_NORMAL) && if ((!(flags & EXT4_IGET_SPECIAL) &&
(ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) ||
(ino < EXT4_ROOT_INO) || (ino < EXT4_ROOT_INO) ||
(ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) {
......
...@@ -4902,7 +4902,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) ...@@ -4902,7 +4902,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
ext4_superblock_csum_set(sb); ext4_superblock_csum_set(sb);
if (sync) if (sync)
lock_buffer(sbh); lock_buffer(sbh);
if (buffer_write_io_error(sbh)) { if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) {
/* /*
* Oh, dear. A previous attempt to write the * Oh, dear. A previous attempt to write the
* superblock failed. This could happen because the * superblock failed. This could happen because the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment