Whamcloud - gitweb
libext2fs: Add callback functions for _alloc_block() and _block_alloc_stats()
[tools/e2fsprogs.git] / lib / ext2fs / alloc.c
index ecff171..f8d8a5f 100644 (file)
@@ -14,7 +14,6 @@
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#include <stdlib.h>
 #include <time.h>
 #include <string.h>
 #if HAVE_SYS_STAT_H
@@ -24,8 +23,7 @@
 #include <sys/types.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
+#include "ext2_fs.h"
 #include "ext2fs.h"
 
 /*
  *
  * Should have a special policy for directories.
  */
-errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
-                          ext2fs_inode_bitmap map, ino_t *ret)
+errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, 
+                          int mode EXT2FS_ATTR((unused)),
+                          ext2fs_inode_bitmap map, ext2_ino_t *ret)
 {
-       ino_t   dir_group = 0;
-       ino_t   i;
-       ino_t   start_inode;
+       ext2_ino_t      dir_group = 0;
+       ext2_ino_t      i;
+       ext2_ino_t      start_inode;
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
        
@@ -57,7 +56,7 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
        i = start_inode;
 
        do {
-               if (!ext2fs_test_inode_bitmap(map, i))
+               if (!ext2fs_fast_test_inode_bitmap(map, i))
                        break;
                i++;
                if (i > fs->super->s_inodes_count)
@@ -65,7 +64,7 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
        } while (i != start_inode);
        
        if (ext2fs_test_inode_bitmap(map, i))
-               return EXT2_INODE_ALLOC_FAIL;
+               return EXT2_ET_INODE_ALLOC_FAIL;
        *ret = i;
        return 0;
 }
@@ -89,7 +88,7 @@ errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
                goal = fs->super->s_first_data_block;
        i = goal;
        do {
-               if (!ext2fs_test_block_bitmap(map, i)) {
+               if (!ext2fs_fast_test_block_bitmap(map, i)) {
                        *ret = i;
                        return 0;
                }
@@ -97,7 +96,7 @@ errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
                if (i >= fs->super->s_blocks_count)
                        i = fs->super->s_first_data_block;
        } while (i != goal);
-       return EXT2_BLOCK_ALLOC_FAIL;
+       return EXT2_ET_BLOCK_ALLOC_FAIL;
 }
 
 /*
@@ -109,43 +108,45 @@ errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
 {
        errcode_t       retval;
        blk_t           block;
-       int             group;
        char            *buf = 0;
 
        if (!block_buf) {
-               buf = malloc(fs->blocksize);
-               if (!buf)
-                       return EXT2_NO_MEMORY;
+               retval = ext2fs_get_mem(fs->blocksize, &buf);
+               if (retval)
+                       return retval;
                block_buf = buf;
        }
        memset(block_buf, 0, fs->blocksize);
 
-       if (!fs->block_map) {
-               retval = ext2fs_read_block_bitmap(fs);
+       if (fs->get_alloc_block) {
+               blk64_t new;
+
+               retval = (fs->get_alloc_block)(fs, (blk64_t) goal, &new);
                if (retval)
                        goto fail;
-       }
+               block = (blk_t) new;
+       } else {
+               if (!fs->block_map) {
+                       retval = ext2fs_read_block_bitmap(fs);
+                       if (retval)
+                               goto fail;
+               }
 
-       retval = ext2fs_new_block(fs, goal, 0, &block);
-       if (retval)
-               goto fail;
+               retval = ext2fs_new_block(fs, goal, 0, &block);
+               if (retval)
+                       goto fail;
+       }
 
        retval = io_channel_write_blk(fs->io, block, 1, block_buf);
        if (retval)
                goto fail;
        
-       fs->super->s_free_blocks_count--;
-       group = ext2fs_group_of_blk(fs, block);
-       fs->group_desc[group].bg_free_blocks_count--;
-       ext2fs_mark_block_bitmap(fs->block_map, block);
-       ext2fs_mark_super_dirty(fs);
-       ext2fs_mark_bb_dirty(fs);
+       ext2fs_block_alloc_stats(fs, block, +1);
        *ret = block;
-       return 0;
 
 fail:
        if (buf)
-               free(buf);
+               ext2fs_free_mem(&buf);
        return retval;
 }
 
@@ -175,6 +176,22 @@ errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
                }
                b++;
        } while (b != finish);
-       return EXT2_BLOCK_ALLOC_FAIL;
+       return EXT2_ET_BLOCK_ALLOC_FAIL;
 }
 
+void ext2fs_set_alloc_block_callback(ext2_filsys fs, 
+                                    errcode_t (*func)(ext2_filsys fs,
+                                                      blk64_t goal,
+                                                      blk64_t *ret),
+                                    errcode_t (**old)(ext2_filsys fs,
+                                                      blk64_t goal,
+                                                      blk64_t *ret))
+{
+       if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
+               return;
+
+       if (old)
+               *old = fs->get_alloc_block;
+
+       fs->get_alloc_block = func;
+}