aboutsummaryrefslogtreecommitdiff
path: root/lib/ext2fs/alloc.c
diff options
context:
space:
mode:
authorSami Liedes <sami.liedes@iki.fi>2012-03-10 22:36:12 +0200
committerTheodore Ts'o <tytso@mit.edu>2012-03-25 18:55:14 -0400
commitc1a1e7fc24d6e37f931bbb8eeb29c90243f0a55d (patch)
treecea143dad327453bd99166d501e077121df77155 /lib/ext2fs/alloc.c
parent5f7c04972fefa8198c34f231a9e8a5430705b4ab (diff)
downloade2fsprogs-c1a1e7fc24d6e37f931bbb8eeb29c90243f0a55d.tar.gz
libext2fs: Implement ext2fs_find_first_zero_generic_bmap().
This function searches a bitmap for the first zero bit within a range. It checks if there is a bitmap backend specific implementation available (if the relevant field in bitmap_ops is non-NULL). If not, it uses a generic and slow method by repeatedly calling test_bmap() in a loop. Also change ext2fs_new_inode() to use this new function. This change in itself does not result in a large speedup, rather it refactors the code in preparation for the introduction of a faster find_first_zero() for bitarray based bitmaps. Signed-off-by: Sami Liedes <sami.liedes@iki.fi> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'lib/ext2fs/alloc.c')
-rw-r--r--lib/ext2fs/alloc.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index bcdc2d44..752c4da1 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -106,10 +106,10 @@ 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)
{
- ext2_ino_t dir_group = 0;
- ext2_ino_t i;
- ext2_ino_t start_inode;
- ext2_ino_t ino_in_group;
+ ext2_ino_t start_inode = 0;
+ ext2_ino_t i, ino_in_group, upto, first_zero;
+ errcode_t retval;
+ dgrp_t group;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -118,31 +118,37 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir,
if (!map)
return EXT2_ET_NO_INODE_BITMAP;
- if (dir > 0)
- dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
-
- start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
+ if (dir > 0) {
+ group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
+ start_inode = (group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
+ }
if (start_inode < EXT2_FIRST_INODE(fs->super))
start_inode = EXT2_FIRST_INODE(fs->super);
if (start_inode > fs->super->s_inodes_count)
return EXT2_ET_INODE_ALLOC_FAIL;
i = start_inode;
- ino_in_group = (i - 1) % EXT2_INODES_PER_GROUP(fs->super);
-
do {
- if (ino_in_group == 0)
- check_inode_uninit(fs, map, (i - 1) /
- EXT2_INODES_PER_GROUP(fs->super));
-
- if (!ext2fs_fast_test_inode_bitmap2(map, i))
+ ino_in_group = (i - 1) % EXT2_INODES_PER_GROUP(fs->super);
+ group = (i - 1) / EXT2_INODES_PER_GROUP(fs->super);
+
+ check_inode_uninit(fs, map, group);
+ upto = i + (EXT2_INODES_PER_GROUP(fs->super) - ino_in_group);
+ if (i < start_inode && upto >= start_inode)
+ upto = start_inode - 1;
+ if (upto > fs->super->s_inodes_count)
+ upto = fs->super->s_inodes_count;
+
+ retval = ext2fs_find_first_zero_inode_bitmap2(map, i, upto,
+ &first_zero);
+ if (retval == 0) {
+ i = first_zero;
break;
- if (++ino_in_group == EXT2_INODES_PER_GROUP(fs->super))
- ino_in_group = 0;
- if (++i > fs->super->s_inodes_count) {
- i = EXT2_FIRST_INODE(fs->super);
- ino_in_group = ((i - 1) %
- EXT2_INODES_PER_GROUP(fs->super));
}
+ if (retval != ENOENT)
+ return EXT2_ET_INODE_ALLOC_FAIL;
+ i = upto + 1;
+ if (i > fs->super->s_inodes_count)
+ i = EXT2_FIRST_INODE(fs->super);
} while (i != start_inode);
if (ext2fs_test_inode_bitmap2(map, i))