ext4: pass context information to jbd2__journal_start()
[deliverable/linux.git] / fs / ext4 / extents.c
index 26af22832a846d43d94c20e67e92a2ab825d835c..b6b54d658dc2271209f920d51f8e6522c30e211f 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);
 }
 
 /*
@@ -950,8 +956,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                goto cleanup;
        }
        bh = sb_getblk(inode->i_sb, newblock);
-       if (!bh) {
-               err = -EIO;
+       if (unlikely(!bh)) {
+               err = -ENOMEM;
                goto cleanup;
        }
        lock_buffer(bh);
@@ -1023,8 +1029,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
                oldblock = newblock;
                newblock = ablocks[--a];
                bh = sb_getblk(inode->i_sb, newblock);
-               if (!bh) {
-                       err = -EIO;
+               if (unlikely(!bh)) {
+                       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 (unlikely(!bh))
+               return -ENOMEM;
        lock_buffer(bh);
 
        err = ext4_journal_get_create_access(handle, bh);
@@ -2226,13 +2229,14 @@ errout:
  * removes index from the index block.
  */
 static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
-                       struct ext4_ext_path *path)
+                       struct ext4_ext_path *path, int depth)
 {
        int err;
        ext4_fsblk_t leaf;
 
        /* free index block */
-       path--;
+       depth--;
+       path = path + depth;
        leaf = ext4_idx_pblock(path->p_idx);
        if (unlikely(path->p_hdr->eh_entries == 0)) {
                EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
@@ -2257,6 +2261,19 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
 
        ext4_free_blocks(handle, inode, NULL, leaf, 1,
                         EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
+
+       while (--depth >= 0) {
+               if (path->p_idx != EXT_FIRST_INDEX(path->p_hdr))
+                       break;
+               path--;
+               err = ext4_ext_get_access(handle, inode, path);
+               if (err)
+                       break;
+               path->p_idx->ei_block = (path+1)->p_idx->ei_block;
+               err = ext4_ext_dirty(handle, inode, path);
+               if (err)
+                       break;
+       }
        return err;
 }
 
@@ -2599,7 +2616,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
        /* if this leaf is free, then we should
         * remove it from index block above */
        if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
-               err = ext4_ext_rm_idx(handle, inode, path + depth);
+               err = ext4_ext_rm_idx(handle, inode, path, depth);
 
 out:
        return err;
@@ -2639,7 +2656,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
        ext_debug("truncate since %u to %u\n", start, end);
 
        /* probably first extent we're gonna free will be last in block */
-       handle = ext4_journal_start(inode, depth + 1);
+       handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, depth + 1);
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
@@ -2802,7 +2819,7 @@ again:
                                /* index is empty, remove it;
                                 * handle must be already prepared by the
                                 * truncatei_leaf() */
-                               err = ext4_ext_rm_idx(handle, inode, path + i);
+                               err = ext4_ext_rm_idx(handle, inode, path, i);
                        }
                        /* root level has p_bh == NULL, brelse() eats this */
                        brelse(path[i].p_bh);
@@ -4270,7 +4287,7 @@ void ext4_ext_truncate(struct inode *inode)
         * probably first extent we're gonna free will be last in block
         */
        err = ext4_writepage_trans_blocks(inode);
-       handle = ext4_journal_start(inode, err);
+       handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, err);
        if (IS_ERR(handle))
                return;
 
@@ -4383,13 +4400,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        struct ext4_map_blocks map;
        unsigned int credits, blkbits = inode->i_blkbits;
 
-       /*
-        * currently supporting (pre)allocate mode for extent-based
-        * files _only_
-        */
-       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-               return -EOPNOTSUPP;
-
        /* Return error if mode is not supported */
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
@@ -4401,6 +4411,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
+       /*
+        * currently supporting (pre)allocate mode for extent-based
+        * files _only_
+        */
+       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+               return -EOPNOTSUPP;
+
        trace_ext4_fallocate_enter(inode, offset, len, mode);
        map.m_lblk = offset >> blkbits;
        /*
@@ -4437,7 +4454,8 @@ retry:
        while (ret >= 0 && ret < max_blocks) {
                map.m_lblk = map.m_lblk + ret;
                map.m_len = max_blocks = max_blocks - ret;
-               handle = ext4_journal_start(inode, credits);
+               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
+                                           credits);
                if (IS_ERR(handle)) {
                        ret = PTR_ERR(handle);
                        break;
@@ -4445,11 +4463,11 @@ retry:
                ret = ext4_map_blocks(handle, inode, &map, flags);
                if (ret <= 0) {
 #ifdef EXT4FS_DEBUG
-                       WARN_ON(ret <= 0);
-                       printk(KERN_ERR "%s: ext4_ext_map_blocks "
-                                   "returned error inode#%lu, block=%u, "
-                                   "max_blocks=%u", __func__,
-                                   inode->i_ino, map.m_lblk, max_blocks);
+                       ext4_warning(inode->i_sb,
+                                    "inode #%lu: block %u: len %u: "
+                                    "ext4_ext_map_blocks returned %d",
+                                    inode->i_ino, map.m_lblk,
+                                    map.m_len, ret);
 #endif
                        ext4_mark_inode_dirty(handle, inode);
                        ret2 = ext4_journal_stop(handle);
@@ -4515,21 +4533,19 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
        while (ret >= 0 && ret < max_blocks) {
                map.m_lblk += ret;
                map.m_len = (max_blocks -= ret);
-               handle = ext4_journal_start(inode, credits);
+               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits);
                if (IS_ERR(handle)) {
                        ret = PTR_ERR(handle);
                        break;
                }
                ret = ext4_map_blocks(handle, inode, &map,
                                      EXT4_GET_BLOCKS_IO_CONVERT_EXT);
-               if (ret <= 0) {
-                       WARN_ON(ret <= 0);
-                       ext4_msg(inode->i_sb, KERN_ERR,
-                                "%s:%d: inode #%lu: block %u: len %u: "
-                                "ext4_ext_map_blocks returned %d",
-                                __func__, __LINE__, inode->i_ino, map.m_lblk,
-                                map.m_len, ret);
-               }
+               if (ret <= 0)
+                       ext4_warning(inode->i_sb,
+                                    "inode #%lu: block %u: len %u: "
+                                    "ext4_ext_map_blocks returned %d",
+                                    inode->i_ino, map.m_lblk,
+                                    map.m_len, ret);
                ext4_mark_inode_dirty(handle, inode);
                ret2 = ext4_journal_stop(handle);
                if (ret <= 0 || ret2 )
@@ -4695,7 +4711,7 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
        inode_dio_wait(inode);
 
        credits = ext4_writepage_trans_blocks(inode);
-       handle = ext4_journal_start(inode, credits);
+       handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
        if (IS_ERR(handle)) {
                err = PTR_ERR(handle);
                goto out_dio;
This page took 0.030634 seconds and 5 git commands to generate.