*
  * called like this: dio->get_blocks(dio->inode, fs_startblk,
  *                                     fs_count, map_bh, dio->rw == WRITE);
- *
- * Note that we never bother to allocate blocks here, and thus ignore the
- * create argument.
  */
 static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
                                     struct buffer_head *bh_result, int create)
 {
        int ret;
+       u32 cpos = 0;
+       int alloc_locked = 0;
        u64 p_blkno, inode_blocks, contig_blocks;
        unsigned int ext_flags;
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
        unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
+       unsigned long len = bh_result->b_size;
+       unsigned int clusters_to_alloc = 0;
+
+       cpos = ocfs2_blocks_to_clusters(inode->i_sb, iblock);
 
        /* This function won't even be called if the request isn't all
         * nicely aligned and of the right size, so there's no need
        /* We should already CoW the refcounted extent in case of create. */
        BUG_ON(create && (ext_flags & OCFS2_EXT_REFCOUNTED));
 
+       /* allocate blocks if no p_blkno is found, and create == 1 */
+       if (!p_blkno && create) {
+               ret = ocfs2_inode_lock(inode, NULL, 1);
+               if (ret < 0) {
+                       mlog_errno(ret);
+                       goto bail;
+               }
+
+               alloc_locked = 1;
+
+               /* fill hole, allocate blocks can't be larger than the size
+                * of the hole */
+               clusters_to_alloc = ocfs2_clusters_for_bytes(inode->i_sb, len);
+               if (clusters_to_alloc > contig_blocks)
+                       clusters_to_alloc = contig_blocks;
+
+               /* allocate extent and insert them into the extent tree */
+               ret = ocfs2_extend_allocation(inode, cpos,
+                               clusters_to_alloc, 0);
+               if (ret < 0) {
+                       mlog_errno(ret);
+                       goto bail;
+               }
+
+               ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno,
+                               &contig_blocks, &ext_flags);
+               if (ret < 0) {
+                       mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
+                                       (unsigned long long)iblock);
+                       ret = -EIO;
+                       goto bail;
+               }
+       }
+
        /*
         * get_more_blocks() expects us to describe a hole by clearing
         * the mapped bit on bh_result().
                contig_blocks = max_blocks;
        bh_result->b_size = contig_blocks << blocksize_bits;
 bail:
+       if (alloc_locked)
+               ocfs2_inode_unlock(inode, 1);
        return ret;
 }