ext4: return ENOMEM if sb_getblk() fails
authorTheodore Ts'o <tytso@mit.edu>
Sat, 12 Jan 2013 21:19:36 +0000 (16:19 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 12 Jan 2013 21:19:36 +0000 (16:19 -0500)
The only reason for sb_getblk() failing is if it can't allocate the
buffer_head.  So ENOMEM is more appropriate than EIO.  In addition,
make sure that the file system is marked as being inconsistent if
sb_getblk() fails.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
fs/ext4/extents.c
fs/ext4/indirect.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/mmp.c
fs/ext4/resize.c
fs/ext4/xattr.c

index 5ae1674ec12f16b7eea6635244f9b68f252d9ba2..d42a8c49ad692a0eaa449e1edf748b77f1f0ee8f 100644 (file)
@@ -725,6 +725,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
        struct ext4_extent_header *eh;
        struct buffer_head *bh;
        short int depth, i, ppos = 0, alloc = 0;
+       int ret;
 
        eh = ext_inode_hdr(inode);
        depth = ext_depth(inode);
@@ -752,12 +753,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
                path[ppos].p_ext = NULL;
 
                bh = sb_getblk(inode->i_sb, path[ppos].p_block);
-               if (unlikely(!bh))
+               if (unlikely(!bh)) {
+                       ret = -ENOMEM;
                        goto err;
+               }
                if (!bh_uptodate_or_lock(bh)) {
                        trace_ext4_ext_load_extent(inode, block,
                                                path[ppos].p_block);
-                       if (bh_submit_read(bh) < 0) {
+                       ret = bh_submit_read(bh);
+                       if (ret < 0) {
                                put_bh(bh);
                                goto err;
                        }
@@ -768,13 +772,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
                        put_bh(bh);
                        EXT4_ERROR_INODE(inode,
                                         "ppos %d > depth %d", ppos, depth);
+                       ret = -EIO;
                        goto err;
                }
                path[ppos].p_bh = bh;
                path[ppos].p_hdr = eh;
                i--;
 
-               if (ext4_ext_check_block(inode, eh, i, bh))
+               ret = ext4_ext_check_block(inode, eh, i, bh);
+               if (ret < 0)
                        goto err;
        }
 
@@ -796,7 +802,7 @@ err:
        ext4_ext_drop_refs(path);
        if (alloc)
                kfree(path);
-       return ERR_PTR(-EIO);
+       return ERR_PTR(ret);
 }
 
 /*
@@ -951,7 +957,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
        }
        bh = sb_getblk(inode->i_sb, newblock);
        if (!bh) {
-               err = -EIO;
+               err = -ENOMEM;
                goto cleanup;
        }
        lock_buffer(bh);
@@ -1024,7 +1030,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                newblock = ablocks[--a];
                bh = sb_getblk(inode->i_sb, newblock);
                if (!bh) {
-                       err = -EIO;
+                       err = -ENOMEM;
                        goto cleanup;
                }
                lock_buffer(bh);
@@ -1136,11 +1142,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
                return err;
 
        bh = sb_getblk(inode->i_sb, newblock);
-       if (!bh) {
-               err = -EIO;
-               ext4_std_error(inode->i_sb, err);
-               return err;
-       }
+       if (!bh)
+               return -ENOMEM;
        lock_buffer(bh);
 
        err = ext4_journal_get_create_access(handle, bh);
index 20862f96e8ae0e79dbf2a031990c68b315260a71..8d83d1e508e4fab8441c4bb09d68f4df503528a2 100644 (file)
@@ -146,6 +146,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
        struct super_block *sb = inode->i_sb;
        Indirect *p = chain;
        struct buffer_head *bh;
+       int ret = -EIO;
 
        *err = 0;
        /* i_data is not going away, no lock needed */
@@ -154,8 +155,10 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
                goto no_block;
        while (--depth) {
                bh = sb_getblk(sb, le32_to_cpu(p->key));
-               if (unlikely(!bh))
+               if (unlikely(!bh)) {
+                       ret = -ENOMEM;
                        goto failure;
+               }
 
                if (!bh_uptodate_or_lock(bh)) {
                        if (bh_submit_read(bh) < 0) {
@@ -177,7 +180,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
        return NULL;
 
 failure:
-       *err = -EIO;
+       *err = ret;
 no_block:
        return p;
 }
@@ -471,7 +474,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
                 */
                bh = sb_getblk(inode->i_sb, new_blocks[n-1]);
                if (unlikely(!bh)) {
-                       err = -EIO;
+                       err = -ENOMEM;
                        goto failed;
                }
 
index 387c47c6cda9f529302602ac69d9878feb75689c..93a3408fc89b1202150a272e7ac084ca81d546e0 100644 (file)
@@ -1188,7 +1188,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
 
        data_bh = sb_getblk(inode->i_sb, map.m_pblk);
        if (!data_bh) {
-               error = -EIO;
+               error = -ENOMEM;
                goto out_restore;
        }
 
index cbfe13bf5b2aa3f39b4845fe4fce4f45a02b5f43..9ccc140b82d2e73ba677cb2f1576e008081de4a9 100644 (file)
@@ -714,7 +714,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
 
        bh = sb_getblk(inode->i_sb, map.m_pblk);
        if (!bh) {
-               *errp = -EIO;
+               *errp = -ENOMEM;
                return NULL;
        }
        if (map.m_flags & EXT4_MAP_NEW) {
@@ -3660,11 +3660,8 @@ static int __ext4_get_inode_loc(struct inode *inode,
        iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
 
        bh = sb_getblk(sb, block);
-       if (!bh) {
-               EXT4_ERROR_INODE_BLOCK(inode, block,
-                                      "unable to read itable block");
-               return -EIO;
-       }
+       if (!bh)
+               return -ENOMEM;
        if (!buffer_uptodate(bh)) {
                lock_buffer(bh);
 
index fe7c63f4717e09616b92f7d3b4850ab99671cff6..44734f1ca55466e28d1d4129cb094b17dae55897 100644 (file)
@@ -80,6 +80,8 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh,
         * is not blocked in the elevator. */
        if (!*bh)
                *bh = sb_getblk(sb, mmp_block);
+       if (!*bh)
+               return -ENOMEM;
        if (*bh) {
                get_bh(*bh);
                lock_buffer(*bh);
index d99387b89eddae77a2aa3a7b147f6fc7c9aa858e..02824dc2ff3bc52c53cbe291f78b30ef8e5b32c6 100644 (file)
@@ -334,7 +334,7 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
 
        bh = sb_getblk(sb, blk);
        if (!bh)
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-ENOMEM);
        if ((err = ext4_journal_get_write_access(handle, bh))) {
                brelse(bh);
                bh = ERR_PTR(err);
@@ -411,7 +411,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
 
                bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap);
                if (!bh)
-                       return -EIO;
+                       return -ENOMEM;
 
                err = ext4_journal_get_write_access(handle, bh);
                if (err)
@@ -501,7 +501,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
 
                        gdb = sb_getblk(sb, block);
                        if (!gdb) {
-                               err = -EIO;
+                               err = -ENOMEM;
                                goto out;
                        }
 
@@ -1065,7 +1065,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data,
 
                bh = sb_getblk(sb, backup_block);
                if (!bh) {
-                       err = -EIO;
+                       err = -ENOMEM;
                        break;
                }
                ext4_debug("update metadata backup %llu(+%llu)\n",
index 3a91ebc2b66fa6fd2177671146c8c6fdd2e54078..07d684a4e52306cde7fbb4c829d0f936dcfe45c2 100644 (file)
@@ -887,16 +887,17 @@ inserted:
 
                        new_bh = sb_getblk(sb, block);
                        if (!new_bh) {
+                               error = -ENOMEM;
 getblk_failed:
                                ext4_free_blocks(handle, inode, NULL, block, 1,
                                                 EXT4_FREE_BLOCKS_METADATA);
-                               error = -EIO;
                                goto cleanup;
                        }
                        lock_buffer(new_bh);
                        error = ext4_journal_get_create_access(handle, new_bh);
                        if (error) {
                                unlock_buffer(new_bh);
+                               error = -EIO;
                                goto getblk_failed;
                        }
                        memcpy(new_bh->b_data, s->base, new_bh->b_size);