Commit 9c94b395 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 updates from Ted Ts'o:

 - Replace ext4's bmap and iopoll implementations to use iomap.

 - Clean up extent tree handling.

 - Other cleanups and miscellaneous bug fixes

* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (31 commits)
  ext4: save all error info in save_error_info() and drop ext4_set_errno()
  ext4: fix incorrect group count in ext4_fill_super error message
  ext4: fix incorrect inodes per group in error message
  ext4: don't set dioread_nolock by default for blocksize < pagesize
  ext4: disable dioread_nolock whenever delayed allocation is disabled
  ext4: do not commit super on read-only bdev
  ext4: avoid ENOSPC when avoiding to reuse recently deleted inodes
  ext4: unregister sysfs path before destroying jbd2 journal
  ext4: check for non-zero journal inum in ext4_calculate_overhead
  ext4: remove map_from_cluster from ext4_ext_map_blocks
  ext4: clean up ext4_ext_insert_extent() call in ext4_ext_map_blocks()
  ext4: mark block bitmap corrupted when found instead of BUGON
  ext4: use flexible-array member for xattr structs
  ext4: use flexible-array member in struct fname
  Documentation: correct the description of FIEMAP_EXTENT_LAST
  ext4: move ext4_fiemap to use iomap framework
  ext4: make ext4_ind_map_blocks work with fiemap
  ext4: move ext4 bmap to use iomap infrastructure
  ext4: optimize ext4_ext_precache for 0 depth
  ext4: add IOMAP_F_MERGED for non-extent based mapping
  ...
parents 34761956 54d3adbc
...@@ -115,8 +115,10 @@ data. Note that the opposite is not true - it would be valid for ...@@ -115,8 +115,10 @@ data. Note that the opposite is not true - it would be valid for
FIEMAP_EXTENT_NOT_ALIGNED to appear alone. FIEMAP_EXTENT_NOT_ALIGNED to appear alone.
* FIEMAP_EXTENT_LAST * FIEMAP_EXTENT_LAST
This is the last extent in the file. A mapping attempt past this This is generally the last extent in the file. A mapping attempt past
extent will return nothing. this extent may return nothing. Some implementations set this flag to
indicate this extent is the last one in the range queried by the user
(via fiemap->fm_length).
* FIEMAP_EXTENT_UNKNOWN * FIEMAP_EXTENT_UNKNOWN
The location of this extent is currently unknown. This may indicate The location of this extent is currently unknown. This may indicate
......
...@@ -516,10 +516,9 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group, ...@@ -516,10 +516,9 @@ int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
wait_on_buffer(bh); wait_on_buffer(bh);
ext4_simulate_fail_bh(sb, bh, EXT4_SIM_BBITMAP_EIO); ext4_simulate_fail_bh(sb, bh, EXT4_SIM_BBITMAP_EIO);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
ext4_set_errno(sb, EIO); ext4_error_err(sb, EIO, "Cannot read block bitmap - "
ext4_error(sb, "Cannot read block bitmap - " "block_group = %u, block_bitmap = %llu",
"block_group = %u, block_bitmap = %llu", block_group, (unsigned long long) bh->b_blocknr);
block_group, (unsigned long long) bh->b_blocknr);
ext4_mark_group_bitmap_corrupted(sb, block_group, ext4_mark_group_bitmap_corrupted(sb, block_group,
EXT4_GROUP_INFO_BBITMAP_CORRUPT); EXT4_GROUP_INFO_BBITMAP_CORRUPT);
return -EIO; return -EIO;
......
...@@ -166,10 +166,8 @@ static int ext4_data_block_valid_rcu(struct ext4_sb_info *sbi, ...@@ -166,10 +166,8 @@ static int ext4_data_block_valid_rcu(struct ext4_sb_info *sbi,
if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
(start_blk + count < start_blk) || (start_blk + count < start_blk) ||
(start_blk + count > ext4_blocks_count(sbi->s_es))) { (start_blk + count > ext4_blocks_count(sbi->s_es)))
sbi->s_es->s_last_error_block = cpu_to_le64(start_blk);
return 0; return 0;
}
if (system_blks == NULL) if (system_blks == NULL)
return 1; return 1;
...@@ -181,10 +179,8 @@ static int ext4_data_block_valid_rcu(struct ext4_sb_info *sbi, ...@@ -181,10 +179,8 @@ static int ext4_data_block_valid_rcu(struct ext4_sb_info *sbi,
n = n->rb_left; n = n->rb_left;
else if (start_blk >= (entry->start_blk + entry->count)) else if (start_blk >= (entry->start_blk + entry->count))
n = n->rb_right; n = n->rb_right;
else { else
sbi->s_es->s_last_error_block = cpu_to_le64(start_blk);
return 0; return 0;
}
} }
return 1; return 1;
} }
...@@ -220,10 +216,12 @@ static int ext4_protect_reserved_inode(struct super_block *sb, ...@@ -220,10 +216,12 @@ static int ext4_protect_reserved_inode(struct super_block *sb,
} else { } else {
if (!ext4_data_block_valid_rcu(sbi, system_blks, if (!ext4_data_block_valid_rcu(sbi, system_blks,
map.m_pblk, n)) { map.m_pblk, n)) {
ext4_error(sb, "blocks %llu-%llu from inode %u "
"overlap system zone", map.m_pblk,
map.m_pblk + map.m_len - 1, ino);
err = -EFSCORRUPTED; err = -EFSCORRUPTED;
__ext4_error(sb, __func__, __LINE__, -err,
map.m_pblk, "blocks %llu-%llu "
"from inode %u overlap system zone",
map.m_pblk,
map.m_pblk + map.m_len - 1, ino);
break; break;
} }
err = add_system_zone(system_blks, map.m_pblk, n); err = add_system_zone(system_blks, map.m_pblk, n);
...@@ -365,7 +363,6 @@ int ext4_data_block_valid(struct ext4_sb_info *sbi, ext4_fsblk_t start_blk, ...@@ -365,7 +363,6 @@ int ext4_data_block_valid(struct ext4_sb_info *sbi, ext4_fsblk_t start_blk,
int ext4_check_blockref(const char *function, unsigned int line, int ext4_check_blockref(const char *function, unsigned int line,
struct inode *inode, __le32 *p, unsigned int max) struct inode *inode, __le32 *p, unsigned int max)
{ {
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
__le32 *bref = p; __le32 *bref = p;
unsigned int blk; unsigned int blk;
...@@ -379,7 +376,6 @@ int ext4_check_blockref(const char *function, unsigned int line, ...@@ -379,7 +376,6 @@ int ext4_check_blockref(const char *function, unsigned int line,
if (blk && if (blk &&
unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb), unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb),
blk, 1))) { blk, 1))) {
es->s_last_error_block = cpu_to_le64(blk);
ext4_error_inode(inode, function, line, blk, ext4_error_inode(inode, function, line, blk,
"invalid block"); "invalid block");
return -EFSCORRUPTED; return -EFSCORRUPTED;
......
...@@ -392,7 +392,7 @@ struct fname { ...@@ -392,7 +392,7 @@ struct fname {
__u32 inode; __u32 inode;
__u8 name_len; __u8 name_len;
__u8 file_type; __u8 file_type;
char name[0]; char name[];
}; };
/* /*
......
...@@ -414,7 +414,7 @@ struct flex_groups { ...@@ -414,7 +414,7 @@ struct flex_groups {
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
#define EXT4_VERITY_FL 0x00100000 /* Verity protected inode */ #define EXT4_VERITY_FL 0x00100000 /* Verity protected inode */
#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */ #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
#define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */ /* 0x00400000 was formerly EXT4_EOFBLOCKS_FL */
#define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */ #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
#define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */ #define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
#define EXT4_CASEFOLD_FL 0x40000000 /* Casefolded file */ #define EXT4_CASEFOLD_FL 0x40000000 /* Casefolded file */
...@@ -487,7 +487,7 @@ enum { ...@@ -487,7 +487,7 @@ enum {
EXT4_INODE_EXTENTS = 19, /* Inode uses extents */ EXT4_INODE_EXTENTS = 19, /* Inode uses extents */
EXT4_INODE_VERITY = 20, /* Verity protected inode */ EXT4_INODE_VERITY = 20, /* Verity protected inode */
EXT4_INODE_EA_INODE = 21, /* Inode used for large EA */ EXT4_INODE_EA_INODE = 21, /* Inode used for large EA */
EXT4_INODE_EOFBLOCKS = 22, /* Blocks allocated beyond EOF */ /* 22 was formerly EXT4_INODE_EOFBLOCKS */
EXT4_INODE_INLINE_DATA = 28, /* Data in inode. */ EXT4_INODE_INLINE_DATA = 28, /* Data in inode. */
EXT4_INODE_PROJINHERIT = 29, /* Create with parents projid */ EXT4_INODE_PROJINHERIT = 29, /* Create with parents projid */
EXT4_INODE_RESERVED = 31, /* reserved for ext4 lib */ EXT4_INODE_RESERVED = 31, /* reserved for ext4 lib */
...@@ -533,7 +533,6 @@ static inline void ext4_check_flag_values(void) ...@@ -533,7 +533,6 @@ static inline void ext4_check_flag_values(void)
CHECK_FLAG_VALUE(EXTENTS); CHECK_FLAG_VALUE(EXTENTS);
CHECK_FLAG_VALUE(VERITY); CHECK_FLAG_VALUE(VERITY);
CHECK_FLAG_VALUE(EA_INODE); CHECK_FLAG_VALUE(EA_INODE);
CHECK_FLAG_VALUE(EOFBLOCKS);
CHECK_FLAG_VALUE(INLINE_DATA); CHECK_FLAG_VALUE(INLINE_DATA);
CHECK_FLAG_VALUE(PROJINHERIT); CHECK_FLAG_VALUE(PROJINHERIT);
CHECK_FLAG_VALUE(RESERVED); CHECK_FLAG_VALUE(RESERVED);
...@@ -2771,21 +2770,20 @@ extern const char *ext4_decode_error(struct super_block *sb, int errno, ...@@ -2771,21 +2770,20 @@ extern const char *ext4_decode_error(struct super_block *sb, int errno,
extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb, extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb,
ext4_group_t block_group, ext4_group_t block_group,
unsigned int flags); unsigned int flags);
extern void ext4_set_errno(struct super_block *sb, int err);
extern __printf(4, 5) extern __printf(6, 7)
void __ext4_error(struct super_block *, const char *, unsigned int, void __ext4_error(struct super_block *, const char *, unsigned int, int, __u64,
const char *, ...); const char *, ...);
extern __printf(5, 6) extern __printf(6, 7)
void __ext4_error_inode(struct inode *, const char *, unsigned int, ext4_fsblk_t, void __ext4_error_inode(struct inode *, const char *, unsigned int,
const char *, ...); ext4_fsblk_t, int, const char *, ...);
extern __printf(5, 6) extern __printf(5, 6)
void __ext4_error_file(struct file *, const char *, unsigned int, ext4_fsblk_t, void __ext4_error_file(struct file *, const char *, unsigned int, ext4_fsblk_t,
const char *, ...); const char *, ...);
extern void __ext4_std_error(struct super_block *, const char *, extern void __ext4_std_error(struct super_block *, const char *,
unsigned int, int); unsigned int, int);
extern __printf(4, 5) extern __printf(5, 6)
void __ext4_abort(struct super_block *, const char *, unsigned int, void __ext4_abort(struct super_block *, const char *, unsigned int, int,
const char *, ...); const char *, ...);
extern __printf(4, 5) extern __printf(4, 5)
void __ext4_warning(struct super_block *, const char *, unsigned int, void __ext4_warning(struct super_block *, const char *, unsigned int,
...@@ -2806,8 +2804,12 @@ void __ext4_grp_locked_error(const char *, unsigned int, ...@@ -2806,8 +2804,12 @@ void __ext4_grp_locked_error(const char *, unsigned int,
#define EXT4_ERROR_INODE(inode, fmt, a...) \ #define EXT4_ERROR_INODE(inode, fmt, a...) \
ext4_error_inode((inode), __func__, __LINE__, 0, (fmt), ## a) ext4_error_inode((inode), __func__, __LINE__, 0, (fmt), ## a)
#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \ #define EXT4_ERROR_INODE_ERR(inode, err, fmt, a...) \
ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a) __ext4_error_inode((inode), __func__, __LINE__, 0, (err), (fmt), ## a)
#define ext4_error_inode_block(inode, block, err, fmt, a...) \
__ext4_error_inode((inode), __func__, __LINE__, (block), (err), \
(fmt), ## a)
#define EXT4_ERROR_FILE(file, block, fmt, a...) \ #define EXT4_ERROR_FILE(file, block, fmt, a...) \
ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a) ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
...@@ -2815,13 +2817,18 @@ void __ext4_grp_locked_error(const char *, unsigned int, ...@@ -2815,13 +2817,18 @@ void __ext4_grp_locked_error(const char *, unsigned int,
#ifdef CONFIG_PRINTK #ifdef CONFIG_PRINTK
#define ext4_error_inode(inode, func, line, block, fmt, ...) \ #define ext4_error_inode(inode, func, line, block, fmt, ...) \
__ext4_error_inode(inode, func, line, block, fmt, ##__VA_ARGS__) __ext4_error_inode(inode, func, line, block, 0, fmt, ##__VA_ARGS__)
#define ext4_error_inode_err(inode, func, line, block, err, fmt, ...) \
__ext4_error_inode((inode), (func), (line), (block), \
(err), (fmt), ##__VA_ARGS__)
#define ext4_error_file(file, func, line, block, fmt, ...) \ #define ext4_error_file(file, func, line, block, fmt, ...) \
__ext4_error_file(file, func, line, block, fmt, ##__VA_ARGS__) __ext4_error_file(file, func, line, block, fmt, ##__VA_ARGS__)
#define ext4_error(sb, fmt, ...) \ #define ext4_error(sb, fmt, ...) \
__ext4_error(sb, __func__, __LINE__, fmt, ##__VA_ARGS__) __ext4_error((sb), __func__, __LINE__, 0, 0, (fmt), ##__VA_ARGS__)
#define ext4_abort(sb, fmt, ...) \ #define ext4_error_err(sb, err, fmt, ...) \
__ext4_abort(sb, __func__, __LINE__, fmt, ##__VA_ARGS__) __ext4_error((sb), __func__, __LINE__, (err), 0, (fmt), ##__VA_ARGS__)
#define ext4_abort(sb, err, fmt, ...) \
__ext4_abort((sb), __func__, __LINE__, (err), (fmt), ##__VA_ARGS__)
#define ext4_warning(sb, fmt, ...) \ #define ext4_warning(sb, fmt, ...) \
__ext4_warning(sb, __func__, __LINE__, fmt, ##__VA_ARGS__) __ext4_warning(sb, __func__, __LINE__, fmt, ##__VA_ARGS__)
#define ext4_warning_inode(inode, fmt, ...) \ #define ext4_warning_inode(inode, fmt, ...) \
...@@ -2839,7 +2846,12 @@ void __ext4_grp_locked_error(const char *, unsigned int, ...@@ -2839,7 +2846,12 @@ void __ext4_grp_locked_error(const char *, unsigned int,
#define ext4_error_inode(inode, func, line, block, fmt, ...) \ #define ext4_error_inode(inode, func, line, block, fmt, ...) \
do { \ do { \
no_printk(fmt, ##__VA_ARGS__); \ no_printk(fmt, ##__VA_ARGS__); \
__ext4_error_inode(inode, "", 0, block, " "); \ __ext4_error_inode(inode, "", 0, block, 0, " "); \
} while (0)
#define ext4_error_inode_err(inode, func, line, block, err, fmt, ...) \
do { \
no_printk(fmt, ##__VA_ARGS__); \
__ext4_error_inode(inode, "", 0, block, err, " "); \
} while (0) } while (0)
#define ext4_error_file(file, func, line, block, fmt, ...) \ #define ext4_error_file(file, func, line, block, fmt, ...) \
do { \ do { \
...@@ -2849,12 +2861,17 @@ do { \ ...@@ -2849,12 +2861,17 @@ do { \
#define ext4_error(sb, fmt, ...) \ #define ext4_error(sb, fmt, ...) \
do { \ do { \
no_printk(fmt, ##__VA_ARGS__); \ no_printk(fmt, ##__VA_ARGS__); \
__ext4_error(sb, "", 0, " "); \ __ext4_error(sb, "", 0, 0, 0, " "); \
} while (0)
#define ext4_error_err(sb, err, fmt, ...) \
do { \
no_printk(fmt, ##__VA_ARGS__); \
__ext4_error(sb, "", 0, err, 0, " "); \
} while (0) } while (0)
#define ext4_abort(sb, fmt, ...) \ #define ext4_abort(sb, err, fmt, ...) \
do { \ do { \
no_printk(fmt, ##__VA_ARGS__); \ no_printk(fmt, ##__VA_ARGS__); \
__ext4_abort(sb, "", 0, " "); \ __ext4_abort(sb, "", 0, err, " "); \
} while (0) } while (0)
#define ext4_warning(sb, fmt, ...) \ #define ext4_warning(sb, fmt, ...) \
do { \ do { \
......
...@@ -80,8 +80,7 @@ static int ext4_journal_check_start(struct super_block *sb) ...@@ -80,8 +80,7 @@ static int ext4_journal_check_start(struct super_block *sb)
* take the FS itself readonly cleanly. * take the FS itself readonly cleanly.
*/ */
if (journal && is_journal_aborted(journal)) { if (journal && is_journal_aborted(journal)) {
ext4_set_errno(sb, -journal->j_errno); ext4_abort(sb, -journal->j_errno, "Detected aborted journal");
ext4_abort(sb, "Detected aborted journal");
return -EROFS; return -EROFS;
} }
return 0; return 0;
...@@ -272,8 +271,7 @@ int __ext4_forget(const char *where, unsigned int line, handle_t *handle, ...@@ -272,8 +271,7 @@ int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
if (err) { if (err) {
ext4_journal_abort_handle(where, line, __func__, ext4_journal_abort_handle(where, line, __func__,
bh, handle, err); bh, handle, err);
ext4_set_errno(inode->i_sb, -err); __ext4_abort(inode->i_sb, where, line, -err,
__ext4_abort(inode->i_sb, where, line,
"error %d when attempting revoke", err); "error %d when attempting revoke", err);
} }
BUFFER_TRACE(bh, "exit"); BUFFER_TRACE(bh, "exit");
...@@ -332,6 +330,7 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, ...@@ -332,6 +330,7 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
err); err);
} }
} else { } else {
set_buffer_uptodate(bh);
if (inode) if (inode)
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(bh, inode);
else else
...@@ -342,11 +341,8 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, ...@@ -342,11 +341,8 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
struct ext4_super_block *es; struct ext4_super_block *es;
es = EXT4_SB(inode->i_sb)->s_es; es = EXT4_SB(inode->i_sb)->s_es;
es->s_last_error_block = ext4_error_inode_err(inode, where, line,
cpu_to_le64(bh->b_blocknr); bh->b_blocknr, EIO,
ext4_set_errno(inode->i_sb, EIO);
ext4_error_inode(inode, where, line,
bh->b_blocknr,
"IO error syncing itable block"); "IO error syncing itable block");
err = -EIO; err = -EIO;
} }
......
...@@ -512,6 +512,9 @@ static inline int ext4_should_dioread_nolock(struct inode *inode) ...@@ -512,6 +512,9 @@ static inline int ext4_should_dioread_nolock(struct inode *inode)
return 0; return 0;
if (ext4_should_journal_data(inode)) if (ext4_should_journal_data(inode))
return 0; return 0;
/* temporary fix to prevent generic/422 test failures */
if (!test_opt(inode->i_sb, DELALLOC))
return 0;
return 1; return 1;
} }
......
This diff is collapsed.
...@@ -872,6 +872,7 @@ const struct file_operations ext4_file_operations = { ...@@ -872,6 +872,7 @@ const struct file_operations ext4_file_operations = {
.llseek = ext4_llseek, .llseek = ext4_llseek,
.read_iter = ext4_file_read_iter, .read_iter = ext4_file_read_iter,
.write_iter = ext4_file_write_iter, .write_iter = ext4_file_write_iter,
.iopoll = iomap_dio_iopoll,
.unlocked_ioctl = ext4_ioctl, .unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = ext4_compat_ioctl, .compat_ioctl = ext4_compat_ioctl,
......
...@@ -196,10 +196,9 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) ...@@ -196,10 +196,9 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
ext4_simulate_fail_bh(sb, bh, EXT4_SIM_IBITMAP_EIO); ext4_simulate_fail_bh(sb, bh, EXT4_SIM_IBITMAP_EIO);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
put_bh(bh); put_bh(bh);
ext4_set_errno(sb, EIO); ext4_error_err(sb, EIO, "Cannot read inode bitmap - "
ext4_error(sb, "Cannot read inode bitmap - " "block_group = %u, inode_bitmap = %llu",
"block_group = %u, inode_bitmap = %llu", block_group, bitmap_blk);
block_group, bitmap_blk);
ext4_mark_group_bitmap_corrupted(sb, block_group, ext4_mark_group_bitmap_corrupted(sb, block_group,
EXT4_GROUP_INFO_IBITMAP_CORRUPT); EXT4_GROUP_INFO_IBITMAP_CORRUPT);
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
...@@ -712,21 +711,34 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino) ...@@ -712,21 +711,34 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
static int find_inode_bit(struct super_block *sb, ext4_group_t group, static int find_inode_bit(struct super_block *sb, ext4_group_t group,
struct buffer_head *bitmap, unsigned long *ino) struct buffer_head *bitmap, unsigned long *ino)
{ {
bool check_recently_deleted = EXT4_SB(sb)->s_journal == NULL;
unsigned long recently_deleted_ino = EXT4_INODES_PER_GROUP(sb);
next: next:
*ino = ext4_find_next_zero_bit((unsigned long *) *ino = ext4_find_next_zero_bit((unsigned long *)
bitmap->b_data, bitmap->b_data,
EXT4_INODES_PER_GROUP(sb), *ino); EXT4_INODES_PER_GROUP(sb), *ino);
if (*ino >= EXT4_INODES_PER_GROUP(sb)) if (*ino >= EXT4_INODES_PER_GROUP(sb))
return 0; goto not_found;
if ((EXT4_SB(sb)->s_journal == NULL) && if (check_recently_deleted && recently_deleted(sb, group, *ino)) {
recently_deleted(sb, group, *ino)) { recently_deleted_ino = *ino;
*ino = *ino + 1; *ino = *ino + 1;
if (*ino < EXT4_INODES_PER_GROUP(sb)) if (*ino < EXT4_INODES_PER_GROUP(sb))
goto next; goto next;
return 0; goto not_found;
} }
return 1;
not_found:
if (recently_deleted_ino >= EXT4_INODES_PER_GROUP(sb))
return 0;
/*
* Not reusing recently deleted inodes is mostly a preference. We don't
* want to report ENOSPC or skew allocation patterns because of that.
* So return even recently deleted inode if we could find better in the
* given range.
*/
*ino = recently_deleted_ino;
return 1; return 1;
} }
...@@ -1231,9 +1243,9 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) ...@@ -1231,9 +1243,9 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
err = PTR_ERR(inode); err = PTR_ERR(inode);
ext4_set_errno(sb, -err); ext4_error_err(sb, -err,
ext4_error(sb, "couldn't read orphan inode %lu (err %d)", "couldn't read orphan inode %lu (err %d)",
ino, err); ino, err);
return inode; return inode;
} }
......
...@@ -1019,7 +1019,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, ...@@ -1019,7 +1019,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
* (should be rare). * (should be rare).
*/ */
if (!bh) { if (!bh) {
EXT4_ERROR_INODE_BLOCK(inode, nr, ext4_error_inode_block(inode, nr, EIO,
"Read failure"); "Read failure");
continue; continue;
} }
......
...@@ -98,10 +98,9 @@ int ext4_get_max_inline_size(struct inode *inode) ...@@ -98,10 +98,9 @@ int ext4_get_max_inline_size(struct inode *inode)
error = ext4_get_inode_loc(inode, &iloc); error = ext4_get_inode_loc(inode, &iloc);
if (error) { if (error) {
ext4_set_errno(inode->i_sb, -error); ext4_error_inode_err(inode, __func__, __LINE__, 0, -error,
ext4_error_inode(inode, __func__, __LINE__, 0, "can't get inode location %lu",
"can't get inode location %lu", inode->i_ino);
inode->i_ino);
return 0; return 0;
} }
...@@ -1762,9 +1761,9 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data) ...@@ -1762,9 +1761,9 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
err = ext4_get_inode_loc(dir, &iloc); err = ext4_get_inode_loc(dir, &iloc);
if (err) { if (err) {
ext4_set_errno(dir->i_sb, -err); EXT4_ERROR_INODE_ERR(dir, -err,
EXT4_ERROR_INODE(dir, "error %d getting inode %lu block", "error %d getting inode %lu block",
err, dir->i_ino); err, dir->i_ino);
return true; return true;
} }
...@@ -1857,47 +1856,6 @@ int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap) ...@@ -1857,47 +1856,6 @@ int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap)
return error; return error;
} }
int ext4_inline_data_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo,
int *has_inline, __u64 start, __u64 len)
{
__u64 physical = 0;
__u64 inline_len;
__u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
FIEMAP_EXTENT_LAST;
int error = 0;
struct ext4_iloc iloc;
down_read(&EXT4_I(inode)->xattr_sem);
if (!ext4_has_inline_data(inode)) {
*has_inline = 0;
goto out;
}
inline_len = min_t(size_t, ext4_get_inline_size(inode),
i_size_read(inode));
if (start >= inline_len)
goto out;
if (start + len < inline_len)
inline_len = start + len;
inline_len -= start;
error = ext4_get_inode_loc(inode, &iloc);
if (error)
goto out;
physical = (__u64)iloc.bh->b_blocknr << inode->i_sb->s_blocksize_bits;
physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data;
physical += offsetof(struct ext4_inode, i_block);
brelse(iloc.bh);
out:
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);
}
int ext4_inline_data_truncate(struct inode *inode, int *has_inline) int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
{ {
handle_t *handle; handle_t *handle;
......
...@@ -269,10 +269,9 @@ void ext4_evict_inode(struct inode *inode) ...@@ -269,10 +269,9 @@ void ext4_evict_inode(struct inode *inode)
if (inode->i_blocks) { if (inode->i_blocks) {
err = ext4_truncate(inode); err = ext4_truncate(inode);
if (err) { if (err) {
ext4_set_errno(inode->i_sb, -err); ext4_error_err(inode->i_sb, -err,
ext4_error(inode->i_sb, "couldn't truncate inode %lu (err %d)",
"couldn't truncate inode %lu (err %d)", inode->i_ino, err);
inode->i_ino, err);
goto stop_handle; goto stop_handle;
} }
} }
...@@ -2478,10 +2477,9 @@ static int mpage_map_and_submit_extent(handle_t *handle, ...@@ -2478,10 +2477,9 @@ static int mpage_map_and_submit_extent(handle_t *handle,
up_write(&EXT4_I(inode)->i_data_sem); up_write(&EXT4_I(inode)->i_data_sem);
err2 = ext4_mark_inode_dirty(handle, inode); err2 = ext4_mark_inode_dirty(handle, inode);
if (err2) { if (err2) {
ext4_set_errno(inode->i_sb, -err2); ext4_error_err(inode->i_sb, -err2,
ext4_error(inode->i_sb, "Failed to mark inode %lu dirty",
"Failed to mark inode %lu dirty", inode->i_ino);
inode->i_ino);
} }
if (!err) if (!err)
err = err2; err = err2;
...@@ -3212,7 +3210,7 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) ...@@ -3212,7 +3210,7 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
return 0; return 0;
} }
return generic_block_bmap(mapping, block, ext4_get_block); return iomap_bmap(mapping, block, &ext4_iomap_ops);
} }
static int ext4_readpage(struct file *file, struct page *page) static int ext4_readpage(struct file *file, struct page *page)
...@@ -3333,6 +3331,10 @@ static void ext4_set_iomap(struct inode *inode, struct iomap *iomap, ...@@ -3333,6 +3331,10 @@ static void ext4_set_iomap(struct inode *inode, struct iomap *iomap,
iomap->offset = (u64) map->m_lblk << blkbits; iomap->offset = (u64) map->m_lblk << blkbits;
iomap->length = (u64) map->m_len << blkbits; iomap->length = (u64) map->m_len << blkbits;
if ((map->m_flags & EXT4_MAP_MAPPED) &&
!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
iomap->flags |= IOMAP_F_MERGED;
/* /*
* Flags passed to ext4_map_blocks() for direct I/O writes can result * Flags passed to ext4_map_blocks() for direct I/O writes can result
* in m_flags having both EXT4_MAP_MAPPED and EXT4_MAP_UNWRITTEN bits * in m_flags having both EXT4_MAP_MAPPED and EXT4_MAP_UNWRITTEN bits
...@@ -3542,12 +3544,28 @@ static int ext4_iomap_begin_report(struct inode *inode, loff_t offset, ...@@ -3542,12 +3544,28 @@ static int ext4_iomap_begin_report(struct inode *inode, loff_t offset,
map.m_len = min_t(loff_t, (offset + length - 1) >> blkbits, map.m_len = min_t(loff_t, (offset + length - 1) >> blkbits,
EXT4_MAX_LOGICAL_BLOCK) - map.m_lblk + 1; EXT4_MAX_LOGICAL_BLOCK) - map.m_lblk + 1;
/*
* Fiemap callers may call for offset beyond s_bitmap_maxbytes.
* So handle it here itself instead of querying ext4_map_blocks().
* Since ext4_map_blocks() will warn about it and will return
* -EIO error.
*/
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
if (offset >= sbi->s_bitmap_maxbytes) {
map.m_flags = 0;
goto set_iomap;
}
}
ret = ext4_map_blocks(NULL, inode, &map, 0); ret = ext4_map_blocks(NULL, inode, &map, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret == 0) if (ret == 0)
delalloc = ext4_iomap_is_delalloc(inode, &map); delalloc = ext4_iomap_is_delalloc(inode, &map);
set_iomap:
ext4_set_iomap(inode, iomap, &map, offset, length); ext4_set_iomap(inode, iomap, &map, offset, length);
if (delalloc && iomap->type == IOMAP_HOLE) if (delalloc && iomap->type == IOMAP_HOLE)
iomap->type = IOMAP_DELALLOC; iomap->type = IOMAP_DELALLOC;
...@@ -4144,8 +4162,6 @@ int ext4_truncate(struct inode *inode) ...@@ -4144,8 +4162,6 @@ int ext4_truncate(struct inode *inode)
if (!ext4_can_truncate(inode)) if (!ext4_can_truncate(inode))
return 0; return 0;
ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE); ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
...@@ -4364,8 +4380,7 @@ static int __ext4_get_inode_loc(struct inode *inode, ...@@ -4364,8 +4380,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
simulate_eio: simulate_eio:
ext4_set_errno(inode->i_sb, EIO); ext4_error_inode_block(inode, block, EIO,
EXT4_ERROR_INODE_BLOCK(inode, block,
"unable to read itable block"); "unable to read itable block");
brelse(bh); brelse(bh);
return -EIO; return -EIO;
...@@ -4517,7 +4532,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ...@@ -4517,7 +4532,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long 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))) {
if (flags & EXT4_IGET_HANDLE) if (flags & EXT4_IGET_HANDLE)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
__ext4_error(sb, function, line, __ext4_error(sb, function, line, EFSCORRUPTED, 0,
"inode #%lu: comm %s: iget: illegal inode #", "inode #%lu: comm %s: iget: illegal inode #",
ino, current->comm); ino, current->comm);
return ERR_PTR(-EFSCORRUPTED); return ERR_PTR(-EFSCORRUPTED);
...@@ -4580,9 +4595,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ...@@ -4580,9 +4595,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
if (!ext4_inode_csum_verify(inode, raw_inode, ei) || if (!ext4_inode_csum_verify(inode, raw_inode, ei) ||
ext4_simulate_fail(sb, EXT4_SIM_INODE_CRC)) { ext4_simulate_fail(sb, EXT4_SIM_INODE_CRC)) {
ext4_set_errno(inode->i_sb, EFSBADCRC); ext4_error_inode_err(inode, function, line, 0, EFSBADCRC,
ext4_error_inode(inode, function, line, 0, "iget: checksum invalid");
"iget: checksum invalid");
ret = -EFSBADCRC; ret = -EFSBADCRC;
goto bad_inode; goto bad_inode;
} }
...@@ -4812,7 +4826,7 @@ static int ext4_inode_blocks_set(handle_t *handle, ...@@ -4812,7 +4826,7 @@ static int ext4_inode_blocks_set(handle_t *handle,
struct ext4_inode_info *ei) struct ext4_inode_info *ei)
{ {
struct inode *inode = &(ei->vfs_inode); struct inode *inode = &(ei->vfs_inode);
u64 i_blocks = inode->i_blocks; u64 i_blocks = READ_ONCE(inode->i_blocks);
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
if (i_blocks <= ~0U) { if (i_blocks <= ~0U) {
...@@ -4982,7 +4996,7 @@ static int ext4_do_update_inode(handle_t *handle, ...@@ -4982,7 +4996,7 @@ static int ext4_do_update_inode(handle_t *handle,
raw_inode->i_file_acl_high = raw_inode->i_file_acl_high =
cpu_to_le16(ei->i_file_acl >> 32); cpu_to_le16(ei->i_file_acl >> 32);
raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl); raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
if (ei->i_disksize != ext4_isize(inode->i_sb, raw_inode)) { if (READ_ONCE(ei->i_disksize) != ext4_isize(inode->i_sb, raw_inode)) {
ext4_isize_set(raw_inode, ei->i_disksize); ext4_isize_set(raw_inode, ei->i_disksize);
need_datasync = 1; need_datasync = 1;
} }
...@@ -5131,9 +5145,8 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -5131,9 +5145,8 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync) if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync)
sync_dirty_buffer(iloc.bh); sync_dirty_buffer(iloc.bh);
if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
ext4_set_errno(inode->i_sb, EIO); ext4_error_inode_block(inode, iloc.bh->b_blocknr, EIO,
EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr, "IO error syncing inode");
"IO error syncing inode");
err = -EIO; err = -EIO;
} }
brelse(iloc.bh); brelse(iloc.bh);
......
...@@ -327,18 +327,6 @@ static int ext4_ioctl_setflags(struct inode *inode, ...@@ -327,18 +327,6 @@ static int ext4_ioctl_setflags(struct inode *inode,
if ((flags ^ oldflags) & EXT4_EXTENTS_FL) if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
migrate = 1; migrate = 1;
if (flags & EXT4_EOFBLOCKS_FL) {
/* we don't support adding EOFBLOCKS flag */
if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
err = -EOPNOTSUPP;
goto flags_out;
}
} else if (oldflags & EXT4_EOFBLOCKS_FL) {
err = ext4_truncate(inode);
if (err)
goto flags_out;
}
if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) { if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) {
if (!ext4_has_feature_casefold(sb)) { if (!ext4_has_feature_casefold(sb)) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
......
...@@ -1901,8 +1901,15 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, ...@@ -1901,8 +1901,15 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
BUG_ON(buddy == NULL); BUG_ON(buddy == NULL);
k = mb_find_next_zero_bit(buddy, max, 0); k = mb_find_next_zero_bit(buddy, max, 0);
BUG_ON(k >= max); if (k >= max) {
ext4_grp_locked_error(ac->ac_sb, e4b->bd_group, 0, 0,
"%d free clusters of order %d. But found 0",
grp->bb_counters[i], i);
ext4_mark_group_bitmap_corrupted(ac->ac_sb,
e4b->bd_group,
EXT4_GROUP_INFO_BBITMAP_CORRUPT);
break;
}
ac->ac_found++; ac->ac_found++;
ac->ac_b_ex.fe_len = 1 << i; ac->ac_b_ex.fe_len = 1 << i;
...@@ -3914,9 +3921,9 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, ...@@ -3914,9 +3921,9 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
bitmap_bh = ext4_read_block_bitmap(sb, group); bitmap_bh = ext4_read_block_bitmap(sb, group);
if (IS_ERR(bitmap_bh)) { if (IS_ERR(bitmap_bh)) {
err = PTR_ERR(bitmap_bh); err = PTR_ERR(bitmap_bh);
ext4_set_errno(sb, -err); ext4_error_err(sb, -err,
ext4_error(sb, "Error %d reading block bitmap for %u", "Error %d reading block bitmap for %u",
err, group); err, group);
return 0; return 0;
} }
...@@ -4083,18 +4090,16 @@ void ext4_discard_preallocations(struct inode *inode) ...@@ -4083,18 +4090,16 @@ void ext4_discard_preallocations(struct inode *inode)
err = ext4_mb_load_buddy_gfp(sb, group, &e4b, err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
GFP_NOFS|__GFP_NOFAIL); GFP_NOFS|__GFP_NOFAIL);
if (err) { if (err) {
ext4_set_errno(sb, -err); ext4_error_err(sb, -err, "Error %d loading buddy information for %u",
ext4_error(sb, "Error %d loading buddy information for %u", err, group);
err, group);
continue; continue;
} }
bitmap_bh = ext4_read_block_bitmap(sb, group); bitmap_bh = ext4_read_block_bitmap(sb, group);
if (IS_ERR(bitmap_bh)) { if (IS_ERR(bitmap_bh)) {
err = PTR_ERR(bitmap_bh); err = PTR_ERR(bitmap_bh);
ext4_set_errno(sb, -err); ext4_error_err(sb, -err, "Error %d reading block bitmap for %u",
ext4_error(sb, "Error %d reading block bitmap for %u", err, group);
err, group);
ext4_mb_unload_buddy(&e4b); ext4_mb_unload_buddy(&e4b);
continue; continue;
} }
...@@ -4302,7 +4307,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, ...@@ -4302,7 +4307,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
spin_lock(&lg->lg_prealloc_lock); spin_lock(&lg->lg_prealloc_lock);
list_for_each_entry_rcu(pa, &lg->lg_prealloc_list[order], list_for_each_entry_rcu(pa, &lg->lg_prealloc_list[order],
pa_inode_list) { pa_inode_list,
lockdep_is_held(&lg->lg_prealloc_lock)) {
spin_lock(&pa->pa_lock); spin_lock(&pa->pa_lock);
if (atomic_read(&pa->pa_count)) { if (atomic_read(&pa->pa_count)) {
/* /*
...@@ -4347,9 +4353,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, ...@@ -4347,9 +4353,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
err = ext4_mb_load_buddy_gfp(sb, group, &e4b, err = ext4_mb_load_buddy_gfp(sb, group, &e4b,
GFP_NOFS|__GFP_NOFAIL); GFP_NOFS|__GFP_NOFAIL);
if (err) { if (err) {
ext4_set_errno(sb, -err); ext4_error_err(sb, -err, "Error %d loading buddy information for %u",
ext4_error(sb, "Error %d loading buddy information for %u", err, group);
err, group);
continue; continue;
} }
ext4_lock_group(sb, group); ext4_lock_group(sb, group);
...@@ -4386,7 +4391,8 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac) ...@@ -4386,7 +4391,8 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
/* Add the prealloc space to lg */ /* Add the prealloc space to lg */
spin_lock(&lg->lg_prealloc_lock); spin_lock(&lg->lg_prealloc_lock);
list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order], list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order],
pa_inode_list) { pa_inode_list,
lockdep_is_held(&lg->lg_prealloc_lock)) {
spin_lock(&tmp_pa->pa_lock); spin_lock(&tmp_pa->pa_lock);
if (tmp_pa->pa_deleted) { if (tmp_pa->pa_deleted) {
spin_unlock(&tmp_pa->pa_lock); spin_unlock(&tmp_pa->pa_lock);
......
...@@ -175,8 +175,8 @@ static int kmmpd(void *data) ...@@ -175,8 +175,8 @@ static int kmmpd(void *data)
*/ */
if (retval) { if (retval) {
if ((failed_writes % 60) == 0) { if ((failed_writes % 60) == 0) {
ext4_set_errno(sb, -retval); ext4_error_err(sb, -retval,
ext4_error(sb, "Error writing to MMP block"); "Error writing to MMP block");
} }
failed_writes++; failed_writes++;
} }
...@@ -208,9 +208,9 @@ static int kmmpd(void *data) ...@@ -208,9 +208,9 @@ static int kmmpd(void *data)
retval = read_mmp_block(sb, &bh_check, mmp_block); retval = read_mmp_block(sb, &bh_check, mmp_block);
if (retval) { if (retval) {
ext4_set_errno(sb, -retval); ext4_error_err(sb, -retval,
ext4_error(sb, "error reading MMP data: %d", "error reading MMP data: %d",
retval); retval);
goto exit_thread; goto exit_thread;
} }
...@@ -222,8 +222,7 @@ static int kmmpd(void *data) ...@@ -222,8 +222,7 @@ static int kmmpd(void *data)
"Error while updating MMP info. " "Error while updating MMP info. "
"The filesystem seems to have been" "The filesystem seems to have been"
" multiply mounted."); " multiply mounted.");
ext4_set_errno(sb, EBUSY); ext4_error_err(sb, EBUSY, "abort");
ext4_error(sb, "abort");
put_bh(bh_check); put_bh(bh_check);
retval = -EBUSY; retval = -EBUSY;
goto exit_thread; goto exit_thread;
......
...@@ -422,8 +422,8 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, ...@@ -422,8 +422,8 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
block_len_in_page, 0, &err2); block_len_in_page, 0, &err2);
ext4_double_up_write_data_sem(orig_inode, donor_inode); ext4_double_up_write_data_sem(orig_inode, donor_inode);
if (replaced_count != block_len_in_page) { if (replaced_count != block_len_in_page) {
EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset), ext4_error_inode_block(orig_inode, (sector_t)(orig_blk_offset),
"Unable to copy data block," EIO, "Unable to copy data block,"
" data will be lost."); " data will be lost.");
*err = -EIO; *err = -EIO;
} }
......
...@@ -160,9 +160,9 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, ...@@ -160,9 +160,9 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
!ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC)) !ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC))
set_buffer_verified(bh); set_buffer_verified(bh);
else { else {
ext4_set_errno(inode->i_sb, EFSBADCRC); ext4_error_inode_err(inode, func, line, block,
ext4_error_inode(inode, func, line, block, EFSBADCRC,
"Directory index failed checksum"); "Directory index failed checksum");
brelse(bh); brelse(bh);
return ERR_PTR(-EFSBADCRC); return ERR_PTR(-EFSBADCRC);
} }
...@@ -172,9 +172,9 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, ...@@ -172,9 +172,9 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
!ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC)) !ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_CRC))
set_buffer_verified(bh); set_buffer_verified(bh);
else { else {
ext4_set_errno(inode->i_sb, EFSBADCRC); ext4_error_inode_err(inode, func, line, block,
ext4_error_inode(inode, func, line, block, EFSBADCRC,
"Directory block failed checksum"); "Directory block failed checksum");
brelse(bh); brelse(bh);
return ERR_PTR(-EFSBADCRC); return ERR_PTR(-EFSBADCRC);
} }
...@@ -233,13 +233,13 @@ struct dx_root ...@@ -233,13 +233,13 @@ struct dx_root
u8 unused_flags; u8 unused_flags;
} }
info; info;
struct dx_entry entries[0]; struct dx_entry entries[];
}; };
struct dx_node struct dx_node
{ {
struct fake_dirent fake; struct fake_dirent fake;
struct dx_entry entries[0]; struct dx_entry entries[];
}; };
...@@ -1532,9 +1532,9 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, ...@@ -1532,9 +1532,9 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir,
goto next; goto next;
wait_on_buffer(bh); wait_on_buffer(bh);
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh)) {
ext4_set_errno(sb, EIO); EXT4_ERROR_INODE_ERR(dir, EIO,
EXT4_ERROR_INODE(dir, "reading directory lblock %lu", "reading directory lblock %lu",
(unsigned long) block); (unsigned long) block);
brelse(bh); brelse(bh);
ret = ERR_PTR(-EIO); ret = ERR_PTR(-EIO);
goto cleanup_and_exit; goto cleanup_and_exit;
...@@ -1543,9 +1543,9 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, ...@@ -1543,9 +1543,9 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir,
!is_dx_internal_node(dir, block, !is_dx_internal_node(dir, block,
(struct ext4_dir_entry *)bh->b_data) && (struct ext4_dir_entry *)bh->b_data) &&
!ext4_dirblock_csum_verify(dir, bh)) { !ext4_dirblock_csum_verify(dir, bh)) {
ext4_set_errno(sb, EFSBADCRC); EXT4_ERROR_INODE_ERR(dir, EFSBADCRC,
EXT4_ERROR_INODE(dir, "checksumming directory " "checksumming directory "
"block %lu", (unsigned long)block); "block %lu", (unsigned long)block);
brelse(bh); brelse(bh);
ret = ERR_PTR(-EFSBADCRC); ret = ERR_PTR(-EFSBADCRC);
goto cleanup_and_exit; goto cleanup_and_exit;
......
This diff is collapsed.
...@@ -245,7 +245,7 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, ...@@ -245,7 +245,7 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
bh->b_data); bh->b_data);
errout: errout:
if (error) if (error)
__ext4_error_inode(inode, function, line, 0, __ext4_error_inode(inode, function, line, 0, -error,
"corrupted xattr block %llu", "corrupted xattr block %llu",
(unsigned long long) bh->b_blocknr); (unsigned long long) bh->b_blocknr);
else else
...@@ -269,7 +269,7 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, ...@@ -269,7 +269,7 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
error = ext4_xattr_check_entries(IFIRST(header), end, IFIRST(header)); error = ext4_xattr_check_entries(IFIRST(header), end, IFIRST(header));
errout: errout:
if (error) if (error)
__ext4_error_inode(inode, function, line, 0, __ext4_error_inode(inode, function, line, 0, -error,
"corrupted in-inode xattr"); "corrupted in-inode xattr");
return error; return error;
} }
...@@ -2880,9 +2880,9 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, ...@@ -2880,9 +2880,9 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
if (IS_ERR(bh)) { if (IS_ERR(bh)) {
error = PTR_ERR(bh); error = PTR_ERR(bh);
if (error == -EIO) { if (error == -EIO) {
ext4_set_errno(inode->i_sb, EIO); EXT4_ERROR_INODE_ERR(inode, EIO,
EXT4_ERROR_INODE(inode, "block %llu read error", "block %llu read error",
EXT4_I(inode)->i_file_acl); EXT4_I(inode)->i_file_acl);
} }
bh = NULL; bh = NULL;
goto cleanup; goto cleanup;
......
...@@ -48,7 +48,7 @@ struct ext4_xattr_entry { ...@@ -48,7 +48,7 @@ struct ext4_xattr_entry {
__le32 e_value_inum; /* inode in which the value is stored */ __le32 e_value_inum; /* inode in which the value is stored */
__le32 e_value_size; /* size of attribute value */ __le32 e_value_size; /* size of attribute value */
__le32 e_hash; /* hash value of name and value */ __le32 e_hash; /* hash value of name and value */
char e_name[0]; /* attribute name */ char e_name[]; /* attribute name */
}; };
#define EXT4_XATTR_PAD_BITS 2 #define EXT4_XATTR_PAD_BITS 2
...@@ -118,7 +118,7 @@ struct ext4_xattr_ibody_find { ...@@ -118,7 +118,7 @@ struct ext4_xattr_ibody_find {
struct ext4_xattr_inode_array { struct ext4_xattr_inode_array {
unsigned int count; /* # of used items in the array */ unsigned int count; /* # of used items in the array */
struct inode *inodes[0]; struct inode *inodes[];
}; };
extern const struct xattr_handler ext4_xattr_user_handler; extern const struct xattr_handler ext4_xattr_user_handler;
......
...@@ -997,9 +997,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) ...@@ -997,9 +997,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
* journalled data) we need to unmap buffer and clear * journalled data) we need to unmap buffer and clear
* more bits. We also need to be careful about the check * more bits. We also need to be careful about the check
* because the data page mapping can get cleared under * because the data page mapping can get cleared under
* out hands, which alse need not to clear more bits * our hands. Note that if mapping == NULL, we don't
* because the page and buffers will be freed and can * need to make buffer unmapped because the page is
* never be reused once we are done with them. * already detached from the mapping and buffers cannot
* get reused.
*/ */
mapping = READ_ONCE(bh->b_page->mapping); mapping = READ_ONCE(bh->b_page->mapping);
if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) { if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) {
......
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