1 /* vi: set sw=4 ts=4: */
3 * dblist.c -- directory block list functions
5 * Copyright 1997 by Theodore Ts'o
8 * This file may be redistributed under the terms of the GNU Public
24 static int dir_block_cmp(const void *a
, const void *b
);
27 * Returns the number of directories in the filesystem as reported by
28 * the group descriptors. Of course, the group descriptors could be
31 errcode_t
ext2fs_get_num_dirs(ext2_filsys fs
, ext2_ino_t
*ret_num_dirs
)
34 ext2_ino_t num_dirs
, max_dirs
;
36 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
39 max_dirs
= fs
->super
->s_inodes_per_group
;
40 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
41 if (fs
->group_desc
[i
].bg_used_dirs_count
> max_dirs
)
42 num_dirs
+= max_dirs
/ 8;
44 num_dirs
+= fs
->group_desc
[i
].bg_used_dirs_count
;
46 if (num_dirs
> fs
->super
->s_inodes_count
)
47 num_dirs
= fs
->super
->s_inodes_count
;
49 *ret_num_dirs
= num_dirs
;
55 * helper function for making a new directory block list (for
56 * initialize and copy).
58 static errcode_t
make_dblist(ext2_filsys fs
, ext2_ino_t size
, ext2_ino_t count
,
59 struct ext2_db_entry
*list
,
60 ext2_dblist
*ret_dblist
)
66 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
68 if ((ret_dblist
== 0) && fs
->dblist
&&
69 (fs
->dblist
->magic
== EXT2_ET_MAGIC_DBLIST
))
72 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_dblist
), &dblist
);
75 memset(dblist
, 0, sizeof(struct ext2_struct_dblist
));
77 dblist
->magic
= EXT2_ET_MAGIC_DBLIST
;
82 retval
= ext2fs_get_num_dirs(fs
, &dblist
->size
);
85 dblist
->size
= (dblist
->size
* 2) + 12;
87 len
= (size_t) sizeof(struct ext2_db_entry
) * dblist
->size
;
88 dblist
->count
= count
;
89 retval
= ext2fs_get_mem(len
, &dblist
->list
);
94 memcpy(dblist
->list
, list
, len
);
96 memset(dblist
->list
, 0, len
);
103 ext2fs_free_mem(&dblist
);
108 * Initialize a directory block list
110 errcode_t
ext2fs_init_dblist(ext2_filsys fs
, ext2_dblist
*ret_dblist
)
115 retval
= make_dblist(fs
, 0, 0, 0, &dblist
);
121 *ret_dblist
= dblist
;
129 * Copy a directory block list
131 errcode_t
ext2fs_copy_dblist(ext2_dblist src
, ext2_dblist
*dest
)
136 retval
= make_dblist(src
->fs
, src
->size
, src
->count
, src
->list
,
140 dblist
->sorted
= src
->sorted
;
146 * Close a directory block list
148 * (moved to closefs.c)
153 * Add a directory block to the directory block list
155 errcode_t
ext2fs_add_dir_block(ext2_dblist dblist
, ext2_ino_t ino
, blk_t blk
,
158 struct ext2_db_entry
*new_entry
;
160 unsigned long old_size
;
162 EXT2_CHECK_MAGIC(dblist
, EXT2_ET_MAGIC_DBLIST
);
164 if (dblist
->count
>= dblist
->size
) {
165 old_size
= dblist
->size
* sizeof(struct ext2_db_entry
);
167 retval
= ext2fs_resize_mem(old_size
, (size_t) dblist
->size
*
168 sizeof(struct ext2_db_entry
),
175 new_entry
= dblist
->list
+ ( (int) dblist
->count
++);
176 new_entry
->blk
= blk
;
177 new_entry
->ino
= ino
;
178 new_entry
->blockcnt
= blockcnt
;
186 * Change the directory block to the directory block list
188 errcode_t
ext2fs_set_dir_block(ext2_dblist dblist
, ext2_ino_t ino
, blk_t blk
,
193 EXT2_CHECK_MAGIC(dblist
, EXT2_ET_MAGIC_DBLIST
);
195 for (i
=0; i
< dblist
->count
; i
++) {
196 if ((dblist
->list
[i
].ino
!= ino
) ||
197 (dblist
->list
[i
].blockcnt
!= blockcnt
))
199 dblist
->list
[i
].blk
= blk
;
203 return EXT2_ET_DB_NOT_FOUND
;
206 void ext2fs_dblist_sort(ext2_dblist dblist
,
207 int (*sortfunc
)(const void *,
211 sortfunc
= dir_block_cmp
;
212 qsort(dblist
->list
, (size_t) dblist
->count
,
213 sizeof(struct ext2_db_entry
), sortfunc
);
218 * This function iterates over the directory block list
220 errcode_t
ext2fs_dblist_iterate(ext2_dblist dblist
,
221 int (*func
)(ext2_filsys fs
,
222 struct ext2_db_entry
*db_info
,
229 EXT2_CHECK_MAGIC(dblist
, EXT2_ET_MAGIC_DBLIST
);
232 ext2fs_dblist_sort(dblist
, 0);
233 for (i
=0; i
< dblist
->count
; i
++) {
234 ret
= (*func
)(dblist
->fs
, &dblist
->list
[(int)i
], priv_data
);
235 if (ret
& DBLIST_ABORT
)
241 static int dir_block_cmp(const void *a
, const void *b
)
243 const struct ext2_db_entry
*db_a
=
244 (const struct ext2_db_entry
*) a
;
245 const struct ext2_db_entry
*db_b
=
246 (const struct ext2_db_entry
*) b
;
248 if (db_a
->blk
!= db_b
->blk
)
249 return (int) (db_a
->blk
- db_b
->blk
);
251 if (db_a
->ino
!= db_b
->ino
)
252 return (int) (db_a
->ino
- db_b
->ino
);
254 return (int) (db_a
->blockcnt
- db_b
->blockcnt
);
257 int ext2fs_dblist_count(ext2_dblist dblist
)
259 return (int) dblist
->count
;