ext4: let ext4_ext_map_blocks return EXT4_MAP_UNWRITTEN flag
[pandora-kernel.git] / fs / ext4 / extents.c
index 391e53a..cae8ae3 100644 (file)
@@ -2656,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);
 
@@ -3528,13 +3528,13 @@ static int ext4_find_delalloc_range(struct inode *inode,
 {
        struct extent_status es;
 
-       es.start = lblk_start;
-       ext4_es_find_extent(inode, &es);
-       if (es.len == 0)
+       ext4_es_find_delayed_extent(inode, lblk_start, &es);
+       if (es.es_len == 0)
                return 0; /* there is no delay extent in this tree */
-       else if (es.start <= lblk_start && lblk_start < es.start + es.len)
+       else if (es.es_lblk <= lblk_start &&
+                lblk_start < es.es_lblk + es.es_len)
                return 1;
-       else if (lblk_start <= es.start && es.start <= lblk_end)
+       else if (lblk_start <= es.es_lblk && es.es_lblk <= lblk_end)
                return 1;
        else
                return 0;
@@ -3659,6 +3659,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
                        ext4_set_io_unwritten_flag(inode, io);
                else
                        ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
+               map->m_flags |= EXT4_MAP_UNWRITTEN;
                if (ext4_should_dioread_nolock(inode))
                        map->m_flags |= EXT4_MAP_UNINIT;
                goto out;
@@ -3680,8 +3681,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
         * repeat fallocate creation request
         * we already have an unwritten extent
         */
-       if (flags & EXT4_GET_BLOCKS_UNINIT_EXT)
+       if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) {
+               map->m_flags |= EXT4_MAP_UNWRITTEN;
                goto map_out;
+       }
 
        /* buffered READ or buffered write_begin() lookup */
        if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
@@ -4111,6 +4114,7 @@ got_allocated_blocks:
        /* Mark uninitialized */
        if (flags & EXT4_GET_BLOCKS_UNINIT_EXT){
                ext4_ext_mark_uninitialized(&newex);
+               map->m_flags |= EXT4_MAP_UNWRITTEN;
                /*
                 * io_end structure was created for every IO write to an
                 * uninitialized extent. To avoid unnecessary conversion,
@@ -4287,7 +4291,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;
 
@@ -4400,13 +4404,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;
@@ -4418,6 +4415,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;
        /*
@@ -4454,7 +4458,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;
@@ -4462,11 +4467,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);
@@ -4532,21 +4537,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 )
@@ -4568,30 +4571,36 @@ static int ext4_find_delayed_extent(struct inode *inode,
                                    struct ext4_ext_cache *newex)
 {
        struct extent_status es;
-       ext4_lblk_t next_del;
+       ext4_lblk_t block, next_del;
 
-       es.start = newex->ec_block;
-       next_del = ext4_es_find_extent(inode, &es);
+       ext4_es_find_delayed_extent(inode, newex->ec_block, &es);
 
        if (newex->ec_start == 0) {
                /*
                 * No extent in extent-tree contains block @newex->ec_start,
                 * then the block may stay in 1)a hole or 2)delayed-extent.
                 */
-               if (es.len == 0)
+               if (es.es_len == 0)
                        /* A hole found. */
                        return 0;
 
-               if (es.start > newex->ec_block) {
+               if (es.es_lblk > newex->ec_block) {
                        /* A hole found. */
-                       newex->ec_len = min(es.start - newex->ec_block,
+                       newex->ec_len = min(es.es_lblk - newex->ec_block,
                                            newex->ec_len);
                        return 0;
                }
 
-               newex->ec_len = es.start + es.len - newex->ec_block;
+               newex->ec_len = es.es_lblk + es.es_len - newex->ec_block;
        }
 
+       block = newex->ec_block + newex->ec_len;
+       ext4_es_find_delayed_extent(inode, block, &es);
+       if (es.es_len == 0)
+               next_del = EXT_MAX_BLOCKS;
+       else
+               next_del = es.es_lblk;
+
        return next_del;
 }
 /* fiemap flags we can handle specified here */
@@ -4712,7 +4721,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;