dblist.c revision ab13b5a9795a8c20f1d6da8fe1da340f545ec0e0
148486893f46d2e12e926682a3ecb908716bc66c4Chris Lattner/* 2b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * dblist.c -- directory block list functions 3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * 4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * Copyright 1997 by Theodore Ts'o 5b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * 6b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * %Begin-Header% 7b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * This file may be redistributed under the terms of the GNU Library 8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell * General Public License, version 2. 9589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner * %End-Header% 10589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner */ 11589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 12589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include <stdio.h> 13589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#if HAVE_UNISTD_H 14589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include <unistd.h> 15589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#endif 16589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include <string.h> 17589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include <time.h> 18589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 197e70829632f82de15db187845666aaca6e04b792Chris Lattner#include "ext2_fs.h" 20589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#include "ext2fsP.h" 21589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 227e70829632f82de15db187845666aaca6e04b792Chris Lattnerstatic EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b); 237e70829632f82de15db187845666aaca6e04b792Chris Lattnerstatic EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b); 247e70829632f82de15db187845666aaca6e04b792Chris Lattnerstatic EXT2_QSORT_TYPE (*sortfunc32)(const void *a, const void *b); 257e70829632f82de15db187845666aaca6e04b792Chris Lattner 267e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 277e70829632f82de15db187845666aaca6e04b792Chris Lattner * Returns the number of directories in the filesystem as reported by 287e70829632f82de15db187845666aaca6e04b792Chris Lattner * the group descriptors. Of course, the group descriptors could be 297e70829632f82de15db187845666aaca6e04b792Chris Lattner * wrong! 307e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 317e70829632f82de15db187845666aaca6e04b792Chris Lattnererrcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs) 327e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 337e70829632f82de15db187845666aaca6e04b792Chris Lattner dgrp_t i; 347e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_ino_t num_dirs, max_dirs; 357e70829632f82de15db187845666aaca6e04b792Chris Lattner 367e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 377e70829632f82de15db187845666aaca6e04b792Chris Lattner 387e70829632f82de15db187845666aaca6e04b792Chris Lattner num_dirs = 0; 397e70829632f82de15db187845666aaca6e04b792Chris Lattner max_dirs = fs->super->s_inodes_per_group; 407e70829632f82de15db187845666aaca6e04b792Chris Lattner for (i = 0; i < fs->group_desc_count; i++) { 417e70829632f82de15db187845666aaca6e04b792Chris Lattner if (ext2fs_bg_used_dirs_count(fs, i) > max_dirs) 427e70829632f82de15db187845666aaca6e04b792Chris Lattner num_dirs += max_dirs / 8; 43589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner else 44589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner num_dirs += ext2fs_bg_used_dirs_count(fs, i); 45589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner } 467e70829632f82de15db187845666aaca6e04b792Chris Lattner if (num_dirs > fs->super->s_inodes_count) 477e70829632f82de15db187845666aaca6e04b792Chris Lattner num_dirs = fs->super->s_inodes_count; 487e70829632f82de15db187845666aaca6e04b792Chris Lattner 497e70829632f82de15db187845666aaca6e04b792Chris Lattner *ret_num_dirs = num_dirs; 507e70829632f82de15db187845666aaca6e04b792Chris Lattner 517e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 527e70829632f82de15db187845666aaca6e04b792Chris Lattner} 537e70829632f82de15db187845666aaca6e04b792Chris Lattner 547e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 557e70829632f82de15db187845666aaca6e04b792Chris Lattner * helper function for making a new directory block list (for 567e70829632f82de15db187845666aaca6e04b792Chris Lattner * initialize and copy). 577e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 587e70829632f82de15db187845666aaca6e04b792Chris Lattnerstatic errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, 597e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_ino_t count, 607e70829632f82de15db187845666aaca6e04b792Chris Lattner struct ext2_db_entry2 *list, 617e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_dblist *ret_dblist) 627e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 637e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_dblist dblist; 647e70829632f82de15db187845666aaca6e04b792Chris Lattner errcode_t retval; 657e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_ino_t num_dirs; 667e70829632f82de15db187845666aaca6e04b792Chris Lattner size_t len; 677e70829632f82de15db187845666aaca6e04b792Chris Lattner 687e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 697e70829632f82de15db187845666aaca6e04b792Chris Lattner 707e70829632f82de15db187845666aaca6e04b792Chris Lattner if ((ret_dblist == 0) && fs->dblist && 717e70829632f82de15db187845666aaca6e04b792Chris Lattner (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST)) 72776f776838d6e2f83d899bc99452dc83779c341bChris Lattner return 0; 73589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 747e70829632f82de15db187845666aaca6e04b792Chris Lattner retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist); 757e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) 767e70829632f82de15db187845666aaca6e04b792Chris Lattner return retval; 777e70829632f82de15db187845666aaca6e04b792Chris Lattner memset(dblist, 0, sizeof(struct ext2_struct_dblist)); 787e70829632f82de15db187845666aaca6e04b792Chris Lattner 795a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner dblist->magic = EXT2_ET_MAGIC_DBLIST; 807e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->fs = fs; 817e70829632f82de15db187845666aaca6e04b792Chris Lattner if (size) 827e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->size = size; 837e70829632f82de15db187845666aaca6e04b792Chris Lattner else { 847e70829632f82de15db187845666aaca6e04b792Chris Lattner retval = ext2fs_get_num_dirs(fs, &num_dirs); 857e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) 867e70829632f82de15db187845666aaca6e04b792Chris Lattner goto cleanup; 877e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->size = (num_dirs * 2) + 12; 887e70829632f82de15db187845666aaca6e04b792Chris Lattner } 897e70829632f82de15db187845666aaca6e04b792Chris Lattner len = (size_t) sizeof(struct ext2_db_entry2) * dblist->size; 907e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->count = count; 917e70829632f82de15db187845666aaca6e04b792Chris Lattner retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry2), 927e70829632f82de15db187845666aaca6e04b792Chris Lattner &dblist->list); 937e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) 947e70829632f82de15db187845666aaca6e04b792Chris Lattner goto cleanup; 957e70829632f82de15db187845666aaca6e04b792Chris Lattner 967e70829632f82de15db187845666aaca6e04b792Chris Lattner if (list) 977e70829632f82de15db187845666aaca6e04b792Chris Lattner memcpy(dblist->list, list, len); 987e70829632f82de15db187845666aaca6e04b792Chris Lattner else 997e70829632f82de15db187845666aaca6e04b792Chris Lattner memset(dblist->list, 0, len); 1007e70829632f82de15db187845666aaca6e04b792Chris Lattner if (ret_dblist) 1017e70829632f82de15db187845666aaca6e04b792Chris Lattner *ret_dblist = dblist; 1027e70829632f82de15db187845666aaca6e04b792Chris Lattner else 1037e70829632f82de15db187845666aaca6e04b792Chris Lattner fs->dblist = dblist; 1047e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 1057e70829632f82de15db187845666aaca6e04b792Chris Lattnercleanup: 1067e70829632f82de15db187845666aaca6e04b792Chris Lattner if (dblist) 1077e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2fs_free_mem(&dblist); 1087e70829632f82de15db187845666aaca6e04b792Chris Lattner return retval; 1097e70829632f82de15db187845666aaca6e04b792Chris Lattner} 110589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 1117e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 1127e70829632f82de15db187845666aaca6e04b792Chris Lattner * Initialize a directory block list 113589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner */ 114589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnererrcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist) 1157e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 1167e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_dblist dblist; 1177e70829632f82de15db187845666aaca6e04b792Chris Lattner errcode_t retval; 1187e70829632f82de15db187845666aaca6e04b792Chris Lattner 1197e70829632f82de15db187845666aaca6e04b792Chris Lattner retval = make_dblist(fs, 0, 0, 0, &dblist); 1207e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) 1217e70829632f82de15db187845666aaca6e04b792Chris Lattner return retval; 1227e70829632f82de15db187845666aaca6e04b792Chris Lattner 1237e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->sorted = 1; 1247e70829632f82de15db187845666aaca6e04b792Chris Lattner if (ret_dblist) 1257e70829632f82de15db187845666aaca6e04b792Chris Lattner *ret_dblist = dblist; 1267e70829632f82de15db187845666aaca6e04b792Chris Lattner else 1277e70829632f82de15db187845666aaca6e04b792Chris Lattner fs->dblist = dblist; 1287e70829632f82de15db187845666aaca6e04b792Chris Lattner 1297e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 1307e70829632f82de15db187845666aaca6e04b792Chris Lattner} 1317e70829632f82de15db187845666aaca6e04b792Chris Lattner 1327e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 1337e70829632f82de15db187845666aaca6e04b792Chris Lattner * Copy a directory block list 1347e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 1357e70829632f82de15db187845666aaca6e04b792Chris Lattnererrcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest) 1367e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 1377e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2_dblist dblist; 1387e70829632f82de15db187845666aaca6e04b792Chris Lattner errcode_t retval; 1397e70829632f82de15db187845666aaca6e04b792Chris Lattner 1407e70829632f82de15db187845666aaca6e04b792Chris Lattner retval = make_dblist(src->fs, src->size, src->count, src->list, 1417e70829632f82de15db187845666aaca6e04b792Chris Lattner &dblist); 1427e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) 1437e70829632f82de15db187845666aaca6e04b792Chris Lattner return retval; 1447e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->sorted = src->sorted; 1457e70829632f82de15db187845666aaca6e04b792Chris Lattner *dest = dblist; 1467e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 1477e70829632f82de15db187845666aaca6e04b792Chris Lattner} 1487e70829632f82de15db187845666aaca6e04b792Chris Lattner 1497e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 1507e70829632f82de15db187845666aaca6e04b792Chris Lattner * Close a directory block list 1517e70829632f82de15db187845666aaca6e04b792Chris Lattner * 1527e70829632f82de15db187845666aaca6e04b792Chris Lattner * (moved to closefs.c) 1537e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 1547e70829632f82de15db187845666aaca6e04b792Chris Lattner 1557e70829632f82de15db187845666aaca6e04b792Chris Lattner 1567e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 1577e70829632f82de15db187845666aaca6e04b792Chris Lattner * Add a directory block to the directory block list 1587e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 1597e70829632f82de15db187845666aaca6e04b792Chris Lattnererrcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino, 1607e70829632f82de15db187845666aaca6e04b792Chris Lattner blk64_t blk, e2_blkcnt_t blockcnt) 1615a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner{ 1627e70829632f82de15db187845666aaca6e04b792Chris Lattner struct ext2_db_entry2 *new_entry; 1637e70829632f82de15db187845666aaca6e04b792Chris Lattner errcode_t retval; 1647e70829632f82de15db187845666aaca6e04b792Chris Lattner unsigned long old_size; 1657e70829632f82de15db187845666aaca6e04b792Chris Lattner 1667e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 1677e70829632f82de15db187845666aaca6e04b792Chris Lattner 1687e70829632f82de15db187845666aaca6e04b792Chris Lattner if (dblist->count >= dblist->size) { 1695a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner old_size = dblist->size * sizeof(struct ext2_db_entry2); 1707e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->size += dblist->size > 200 ? dblist->size / 2 : 100; 1715a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner retval = ext2fs_resize_mem(old_size, (size_t) dblist->size * 1727e70829632f82de15db187845666aaca6e04b792Chris Lattner sizeof(struct ext2_db_entry2), 1737e70829632f82de15db187845666aaca6e04b792Chris Lattner &dblist->list); 1747e70829632f82de15db187845666aaca6e04b792Chris Lattner if (retval) { 1757e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->size -= 100; 1767e70829632f82de15db187845666aaca6e04b792Chris Lattner return retval; 1777e70829632f82de15db187845666aaca6e04b792Chris Lattner } 1785a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner } 1795a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner new_entry = dblist->list + ( dblist->count++); 1807e70829632f82de15db187845666aaca6e04b792Chris Lattner new_entry->blk = blk; 1817e70829632f82de15db187845666aaca6e04b792Chris Lattner new_entry->ino = ino; 1827e70829632f82de15db187845666aaca6e04b792Chris Lattner new_entry->blockcnt = blockcnt; 1837e70829632f82de15db187845666aaca6e04b792Chris Lattner 184589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner dblist->sorted = 0; 185589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 186589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner return 0; 187589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner} 188589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 189589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner/* 1907e70829632f82de15db187845666aaca6e04b792Chris Lattner * Change the directory block to the directory block list 191589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner */ 192589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnererrcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino, 1935a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner blk64_t blk, e2_blkcnt_t blockcnt) 19488d942d8983aadecae477fee523c23312d194515Misha Brukman{ 1955a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner dgrp_t i; 1965a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner 197589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 198589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 199589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner for (i=0; i < dblist->count; i++) { 200589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner if ((dblist->list[i].ino != ino) || 201589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner (dblist->list[i].blockcnt != blockcnt)) 202589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner continue; 2035a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner dblist->list[i].blk = blk; 2047e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->sorted = 0; 20588d942d8983aadecae477fee523c23312d194515Misha Brukman return 0; 2067e70829632f82de15db187845666aaca6e04b792Chris Lattner } 207589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner return EXT2_ET_DB_NOT_FOUND; 208589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner} 209589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 210589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnervoid ext2fs_dblist_sort2(ext2_dblist dblist, 211589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner EXT2_QSORT_TYPE (*sortfunc)(const void *, 212589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner const void *)) 213589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner{ 214589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner if (!sortfunc) 2151ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner sortfunc = dir_block_cmp2; 216589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner qsort(dblist->list, (size_t) dblist->count, 217589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner sizeof(struct ext2_db_entry2), sortfunc); 218589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner dblist->sorted = 1; 219ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattner} 220ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattner 221589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner/* 222589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner * This function iterates over the directory block list 223589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner */ 224589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnererrcode_t ext2fs_dblist_iterate2(ext2_dblist dblist, 225589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner int (*func)(ext2_filsys fs, 226589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner struct ext2_db_entry2 *db_info, 2271ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner void *priv_data), 2281ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner void *priv_data) 2297e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 2307e70829632f82de15db187845666aaca6e04b792Chris Lattner unsigned long long i; 2317e70829632f82de15db187845666aaca6e04b792Chris Lattner int ret; 2327e70829632f82de15db187845666aaca6e04b792Chris Lattner 2337e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 2347e70829632f82de15db187845666aaca6e04b792Chris Lattner 2357e70829632f82de15db187845666aaca6e04b792Chris Lattner if (!dblist->sorted) 2367e70829632f82de15db187845666aaca6e04b792Chris Lattner ext2fs_dblist_sort2(dblist, 0); 2377e70829632f82de15db187845666aaca6e04b792Chris Lattner for (i=0; i < dblist->count; i++) { 2387e70829632f82de15db187845666aaca6e04b792Chris Lattner ret = (*func)(dblist->fs, &dblist->list[i], priv_data); 2397e70829632f82de15db187845666aaca6e04b792Chris Lattner if (ret & DBLIST_ABORT) 2407e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 2417e70829632f82de15db187845666aaca6e04b792Chris Lattner } 2427e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 2437e70829632f82de15db187845666aaca6e04b792Chris Lattner} 2447e70829632f82de15db187845666aaca6e04b792Chris Lattner 2457e70829632f82de15db187845666aaca6e04b792Chris Lattnerstatic EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b) 2467e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 2477e70829632f82de15db187845666aaca6e04b792Chris Lattner const struct ext2_db_entry2 *db_a = 2487e70829632f82de15db187845666aaca6e04b792Chris Lattner (const struct ext2_db_entry2 *) a; 2497e70829632f82de15db187845666aaca6e04b792Chris Lattner const struct ext2_db_entry2 *db_b = 2507e70829632f82de15db187845666aaca6e04b792Chris Lattner (const struct ext2_db_entry2 *) b; 2517e70829632f82de15db187845666aaca6e04b792Chris Lattner 2527e70829632f82de15db187845666aaca6e04b792Chris Lattner if (db_a->blk != db_b->blk) 2537e70829632f82de15db187845666aaca6e04b792Chris Lattner return (int) (db_a->blk - db_b->blk); 2547e70829632f82de15db187845666aaca6e04b792Chris Lattner 2557e70829632f82de15db187845666aaca6e04b792Chris Lattner if (db_a->ino != db_b->ino) 2567e70829632f82de15db187845666aaca6e04b792Chris Lattner return (int) (db_a->ino - db_b->ino); 2577e70829632f82de15db187845666aaca6e04b792Chris Lattner 2587e70829632f82de15db187845666aaca6e04b792Chris Lattner return (db_a->blockcnt - db_b->blockcnt); 2597e70829632f82de15db187845666aaca6e04b792Chris Lattner} 2607e70829632f82de15db187845666aaca6e04b792Chris Lattner 2617e70829632f82de15db187845666aaca6e04b792Chris Lattnerblk64_t ext2fs_dblist_count2(ext2_dblist dblist) 2627e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 2637e70829632f82de15db187845666aaca6e04b792Chris Lattner return dblist->count; 2647e70829632f82de15db187845666aaca6e04b792Chris Lattner} 2657e70829632f82de15db187845666aaca6e04b792Chris Lattner 2667e70829632f82de15db187845666aaca6e04b792Chris Lattnererrcode_t ext2fs_dblist_get_last2(ext2_dblist dblist, 2677e70829632f82de15db187845666aaca6e04b792Chris Lattner struct ext2_db_entry2 **entry) 2687e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 2697e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 2707e70829632f82de15db187845666aaca6e04b792Chris Lattner 2717e70829632f82de15db187845666aaca6e04b792Chris Lattner if (dblist->count == 0) 2727e70829632f82de15db187845666aaca6e04b792Chris Lattner return EXT2_ET_DBLIST_EMPTY; 2737e70829632f82de15db187845666aaca6e04b792Chris Lattner 2747e70829632f82de15db187845666aaca6e04b792Chris Lattner if (entry) 2757e70829632f82de15db187845666aaca6e04b792Chris Lattner *entry = dblist->list + ( dblist->count-1); 2767e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 2777e70829632f82de15db187845666aaca6e04b792Chris Lattner} 2787e70829632f82de15db187845666aaca6e04b792Chris Lattner 2797e70829632f82de15db187845666aaca6e04b792Chris Lattnererrcode_t ext2fs_dblist_drop_last(ext2_dblist dblist) 2807e70829632f82de15db187845666aaca6e04b792Chris Lattner{ 2817e70829632f82de15db187845666aaca6e04b792Chris Lattner EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 2827e70829632f82de15db187845666aaca6e04b792Chris Lattner 2837e70829632f82de15db187845666aaca6e04b792Chris Lattner if (dblist->count == 0) 2847e70829632f82de15db187845666aaca6e04b792Chris Lattner return EXT2_ET_DBLIST_EMPTY; 2857e70829632f82de15db187845666aaca6e04b792Chris Lattner 2867e70829632f82de15db187845666aaca6e04b792Chris Lattner dblist->count--; 2877e70829632f82de15db187845666aaca6e04b792Chris Lattner return 0; 2887e70829632f82de15db187845666aaca6e04b792Chris Lattner} 2897e70829632f82de15db187845666aaca6e04b792Chris Lattner 2907e70829632f82de15db187845666aaca6e04b792Chris Lattner/* 2917e70829632f82de15db187845666aaca6e04b792Chris Lattner * Legacy 32-bit versions 292589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner */ 293589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner 294589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner/* 2957e70829632f82de15db187845666aaca6e04b792Chris Lattner * Add a directory block to the directory block list 2967e70829632f82de15db187845666aaca6e04b792Chris Lattner */ 297errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 298 int blockcnt) 299{ 300 return ext2fs_add_dir_block2(dblist, ino, blk, blockcnt); 301} 302 303/* 304 * Change the directory block to the directory block list 305 */ 306errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 307 int blockcnt) 308{ 309 return ext2fs_set_dir_block2(dblist, ino, blk, blockcnt); 310} 311 312void ext2fs_dblist_sort(ext2_dblist dblist, 313 EXT2_QSORT_TYPE (*sortfunc)(const void *, 314 const void *)) 315{ 316 if (sortfunc) { 317 sortfunc32 = sortfunc; 318 sortfunc = dir_block_cmp; 319 } else 320 sortfunc = dir_block_cmp2; 321 qsort(dblist->list, (size_t) dblist->count, 322 sizeof(struct ext2_db_entry2), sortfunc); 323 dblist->sorted = 1; 324} 325 326/* 327 * This function iterates over the directory block list 328 */ 329struct iterate_passthrough { 330 int (*func)(ext2_filsys fs, 331 struct ext2_db_entry *db_info, 332 void *priv_data); 333 void *priv_data; 334}; 335 336static int passthrough_func(ext2_filsys fs, 337 struct ext2_db_entry2 *db_info, 338 void *priv_data) 339{ 340 struct iterate_passthrough *p = priv_data; 341 struct ext2_db_entry db; 342 int ret; 343 344 db.ino = db_info->ino; 345 db.blk = (blk_t) db_info->blk; 346 db.blockcnt = (int) db_info->blockcnt; 347 ret = (p->func)(fs, &db, p->priv_data); 348 db_info->ino = db.ino; 349 db_info->blk = db.blk; 350 db_info->blockcnt = db.blockcnt; 351 return ret; 352} 353 354errcode_t ext2fs_dblist_iterate(ext2_dblist dblist, 355 int (*func)(ext2_filsys fs, 356 struct ext2_db_entry *db_info, 357 void *priv_data), 358 void *priv_data) 359{ 360 struct iterate_passthrough pass; 361 362 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 363 pass.func = func; 364 pass.priv_data = priv_data; 365 366 return ext2fs_dblist_iterate2(dblist, passthrough_func, &pass); 367} 368 369static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) 370{ 371 const struct ext2_db_entry2 *db_a = 372 (const struct ext2_db_entry2 *) a; 373 const struct ext2_db_entry2 *db_b = 374 (const struct ext2_db_entry2 *) b; 375 376 struct ext2_db_entry a32, b32; 377 378 a32.ino = db_a->ino; a32.blk = db_a->blk; 379 a32.blockcnt = db_a->blockcnt; 380 381 b32.ino = db_b->ino; b32.blk = db_b->blk; 382 b32.blockcnt = db_b->blockcnt; 383 384 return sortfunc32(&a32, &b32); 385} 386 387int ext2fs_dblist_count(ext2_dblist dblist) 388{ 389 return dblist->count; 390} 391 392errcode_t ext2fs_dblist_get_last(ext2_dblist dblist, 393 struct ext2_db_entry **entry) 394{ 395 EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 396 static struct ext2_db_entry ret_entry; 397 struct ext2_db_entry2 *last; 398 399 if (dblist->count == 0) 400 return EXT2_ET_DBLIST_EMPTY; 401 402 if (!entry) 403 return 0; 404 405 last = dblist->list + dblist->count -1; 406 407 ret_entry.ino = last->ino; 408 ret_entry.blk = last->blk; 409 ret_entry.blockcnt = last->blockcnt; 410 *entry = &ret_entry; 411 412 return 0; 413} 414 415