FAILED: patch "[PATCH] ext4: add ext4_sb_bread() to disambiguate ENOMEM cases" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From fb265c9cb49e2074ddcdd4de99728aefdd3b3592 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <[email protected]>
Date: Sun, 25 Nov 2018 17:20:31 -0500
Subject: [PATCH] ext4: add ext4_sb_bread() to disambiguate ENOMEM cases
Today, when sb_bread() returns NULL, this can either be because of an I/O error or because the system failed to allocate the buffer. Since it's an old interface, changing would require changing many call sites.
So instead we create our own ext4_sb_bread(), which also allows us to set the REQ_META flag.
Also fixed a problem in the xattr code where a NULL return in a function could also mean that the xattr was not found, which could lead to the wrong error getting returned to userspace.
fs/ext4/ext4.h +2 -0
@@ -2538,6 +2538,8 @@ extern int ext4_group_extend(struct super_block *sb,extern int ext4_resize_fs (struct super_block *sb,ext4_fsblk_t n_blocks_count);/* super.c */ +extern struct buffer_head *ext4_sb_bread (struct super_block *sb, +sector_t block,int op_flags);extern int ext4_seq_options_show (struct seq_file *seq,void *offset);extern int ext4_calculate_overhead (struct super_block *sb);extern void ext4_superblock_csum_set (struct super_block *sb);
fs/ext4/migrate.c +18 -18
@@ -116,9 +116,9 @@ static int update_ind_extent_range(handle_t *handle, struct inode *inode,int i, retval =0 ;unsigned long max_entries = inode->i_sb->s_blocksize >>2 ; - bh =sb_bread (inode->i_sb, pblock); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb, pblock,0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); i_data = (__le32 *)bh->b_data;for (i =0 ; i < max_entries; i++) {
@@ -145,9 +145,9 @@ static int update_dind_extent_range(handle_t *handle, struct inode *inode,int i, retval =0 ;unsigned long max_entries = inode->i_sb->s_blocksize >>2 ; - bh =sb_bread (inode->i_sb, pblock); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb, pblock,0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); i_data = (__le32 *)bh->b_data;for (i =0 ; i < max_entries; i++) {
@@ -175,9 +175,9 @@ static int update_tind_extent_range(handle_t *handle, struct inode *inode,int i, retval =0 ;unsigned long max_entries = inode->i_sb->s_blocksize >>2 ; - bh =sb_bread (inode->i_sb, pblock); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb, pblock,0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); i_data = (__le32 *)bh->b_data;for (i =0 ; i < max_entries; i++) {
@@ -224,9 +224,9 @@ static int free_dind_blocks(handle_t *handle,struct buffer_head *bh;unsigned long max_entries = inode->i_sb->s_blocksize >>2 ; - bh =sb_bread (inode->i_sb,le32_to_cpu (i_data)); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb,le32_to_cpu (i_data),0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); tmp_idata = (__le32 *)bh->b_data;for (i =0 ; i < max_entries; i++) {
@@ -254,9 +254,9 @@ static int free_tind_blocks(handle_t *handle,struct buffer_head *bh;unsigned long max_entries = inode->i_sb->s_blocksize >>2 ; - bh =sb_bread (inode->i_sb,le32_to_cpu (i_data)); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb,le32_to_cpu (i_data),0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); tmp_idata = (__le32 *)bh->b_data;for (i =0 ; i < max_entries; i++) {
@@ -382,9 +382,9 @@ static int free_ext_idx(handle_t *handle, struct inode *inode,struct ext4_extent_header *eh; block =ext4_idx_pblock (ix); - bh =sb_bread (inode->i_sb, block); -if (!bh) -return -EIO ; + bh =ext4_sb_bread (inode->i_sb, block,0 ); +if (IS_ERR (bh)) +return PTR_ERR (bh); eh = (struct ext4_extent_header *)bh->b_data;if (eh->eh_depth !=0 ) {
fs/ext4/resize.c +36 -36
167 lines not on this page · raw message
fs/ext4/super.c +23 -0
@@ -140,6 +140,29 @@ MODULE_ALIAS_FS("ext3");MODULE_ALIAS ("ext3" );#define IS_EXT3_SB (sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) +/* +* This works like sb_bread() except it uses ERR_PTR for error +* returns. Currently with sb_bread it's impossible to distinguish +* between ENOMEM and EIO situations (since both result in a NULL +* return. +*/ +struct buffer_head * +ext4_sb_bread (struct super_block *sb,sector_t block,int op_flags) +{ +struct buffer_head *bh =sb_getblk (sb, block); + +if (bh ==NULL ) +return ERR_PTR (-ENOMEM ); +if (buffer_uptodate (bh)) +return bh; +ll_rw_block (REQ_OP_READ ,REQ_META | op_flags,1 , &bh); +wait_on_buffer (bh); +if (buffer_uptodate (bh)) +return bh; +put_bh (bh); +return ERR_PTR (-EIO ); +} +static int ext4_verify_csum_type (struct super_block *sb,struct ext4_super_block *es) {
fs/ext4/xattr.c +36 -40
152 lines not on this page · raw message