dblist.c revision 52b1dd5e496c199e9cbcc238f26fd2264a07a2cf
121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * dblist.c -- directory block list functions 321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright 1997 by Theodore Ts'o 521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header% 721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * This file may be redistributed under the terms of the GNU Public 821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * License. 921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header% 1021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 1121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 1221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 1321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <stdio.h> 144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 1521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <unistd.h> 164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 1721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <string.h> 1821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <time.h> 1921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 20b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 2121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include "ext2fsP.h" 2221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 234c77fe50d97a773e32a4756c79dade3adbb6a601Theodore Ts'ostatic EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b); 2421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 2621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Returns the number of directories in the filesystem as reported by 2721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * the group descriptors. Of course, the group descriptors could be 2821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * wrong! 2921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 3031dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs) 3121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 322eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o dgrp_t i; 3331dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t num_dirs, max_dirs; 3421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 3521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 3621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 3721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o num_dirs = 0; 3879b05dbed2003cd678ba6b210695420486ce920dTheodore Ts'o max_dirs = fs->super->s_inodes_per_group; 395be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o for (i = 0; i < fs->group_desc_count; i++) { 405be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o if (fs->group_desc[i].bg_used_dirs_count > max_dirs) 4179b05dbed2003cd678ba6b210695420486ce920dTheodore Ts'o num_dirs += max_dirs / 8; 425be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o else 435be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o num_dirs += fs->group_desc[i].bg_used_dirs_count; 445be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o } 455be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o if (num_dirs > fs->super->s_inodes_count) 465be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o num_dirs = fs->super->s_inodes_count; 4721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 4821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *ret_num_dirs = num_dirs; 4921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 5021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 5121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 5221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 5321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 54a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * helper function for making a new directory block list (for 55a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * initialize and copy). 5621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 5731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'ostatic errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count, 58a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o struct ext2_db_entry *list, 59a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist *ret_dblist) 6021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 6121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o ext2_dblist dblist; 6221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o errcode_t retval; 63a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o size_t len; 6421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 6521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 6621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 6721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if ((ret_dblist == 0) && fs->dblist && 6821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST)) 6921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 7021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 71c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist); 727b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 737b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 7421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o memset(dblist, 0, sizeof(struct ext2_struct_dblist)); 7521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 7621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->magic = EXT2_ET_MAGIC_DBLIST; 7721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->fs = fs; 78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (size) 79a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->size = size; 80a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o else { 81a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_get_num_dirs(fs, &dblist->size); 82a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 83a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto cleanup; 841e1da29fbd4204a267ebd7c64d37e1f95a9dad08Theodore Ts'o dblist->size = (dblist->size * 2) + 12; 85a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 863cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o len = (size_t) sizeof(struct ext2_db_entry) * dblist->size; 87a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->count = count; 88ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry), 89ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o &dblist->list); 907b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 9121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o goto cleanup; 927b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o 93a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (list) 94a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memcpy(dblist->list, list, len); 9521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o else 96a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memset(dblist->list, 0, len); 972eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o if (ret_dblist) 982eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o *ret_dblist = dblist; 992eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o else 1002eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o fs->dblist = dblist; 10121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 10221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ocleanup: 10321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (dblist) 104c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&dblist); 10521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return retval; 10621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 10721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 10821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 109a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Initialize a directory block list 110a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */ 111a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist) 112a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{ 113a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist dblist; 114a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o errcode_t retval; 115a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 116a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = make_dblist(fs, 0, 0, 0, &dblist); 117a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 118a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return retval; 119a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 120a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->sorted = 1; 121a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (ret_dblist) 122a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *ret_dblist = dblist; 123a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o else 124a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->dblist = dblist; 125a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 126a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return 0; 127a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o} 128a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 129a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/* 130a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Copy a directory block list 131a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */ 132a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest) 133a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{ 134a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist dblist; 135a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o errcode_t retval; 136a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 137a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = make_dblist(src->fs, src->size, src->count, src->list, 138a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o &dblist); 139a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 140a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return retval; 141a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->sorted = src->sorted; 142a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *dest = dblist; 143a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return 0; 144a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o} 145a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 146a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/* 14721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Close a directory block list 14821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 14921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * (moved to closefs.c) 15021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 15121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 15221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 15321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 15421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Add a directory block to the directory block list 15521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 15631dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 15721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o int blockcnt) 15821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 159b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o struct ext2_db_entry *new_entry; 1607b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o errcode_t retval; 16176f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o unsigned long old_size; 16221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 16321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 16421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 16521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (dblist->count >= dblist->size) { 16676f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o old_size = dblist->size * sizeof(struct ext2_db_entry); 16721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->size += 100; 16876f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o retval = ext2fs_resize_mem(old_size, (size_t) dblist->size * 1697b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o sizeof(struct ext2_db_entry), 170c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &dblist->list); 1717b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) { 17221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->size -= 100; 1737b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 17421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 17521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 176b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry = dblist->list + ( (int) dblist->count++); 177b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->blk = blk; 178b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->ino = ino; 179b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->blockcnt = blockcnt; 18021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->sorted = 0; 18221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 18421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 18521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 187521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o * Change the directory block to the directory block list 188521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o */ 18931dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 190521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o int blockcnt) 191521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o{ 1922eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o dgrp_t i; 193521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o 194521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 195521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o 196521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o for (i=0; i < dblist->count; i++) { 197521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o if ((dblist->list[i].ino != ino) || 198521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o (dblist->list[i].blockcnt != blockcnt)) 199521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o continue; 200521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o dblist->list[i].blk = blk; 201521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o dblist->sorted = 0; 202521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o return 0; 203521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o } 2041f0b6c1f895d189fea6999d0c07a7fee936a4baaTheodore Ts'o return EXT2_ET_DB_NOT_FOUND; 205521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o} 206521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o 207ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'ovoid ext2fs_dblist_sort(ext2_dblist dblist, 208ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o EXT2_QSORT_TYPE (*sortfunc)(const void *, 209ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o const void *)) 210ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o{ 211ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o if (!sortfunc) 212ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o sortfunc = dir_block_cmp; 213ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o qsort(dblist->list, (size_t) dblist->count, 214ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o sizeof(struct ext2_db_entry), sortfunc); 215ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o dblist->sorted = 1; 216ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o} 217ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o 218521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o/* 21921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * This function iterates over the directory block list 22021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 22121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'oerrcode_t ext2fs_dblist_iterate(ext2_dblist dblist, 22221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o int (*func)(ext2_filsys fs, 22321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o struct ext2_db_entry *db_info, 224b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data), 225b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data) 22621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 22731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t i; 22831dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o int ret; 22921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 23021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 23121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 232ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o if (!dblist->sorted) 233ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o ext2fs_dblist_sort(dblist, 0); 23421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o for (i=0; i < dblist->count; i++) { 235b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data); 23621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (ret & DBLIST_ABORT) 23721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 23821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 23921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 24021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 24121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2424c77fe50d97a773e32a4756c79dade3adbb6a601Theodore Ts'ostatic EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) 24321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 24421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o const struct ext2_db_entry *db_a = 24521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (const struct ext2_db_entry *) a; 24621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o const struct ext2_db_entry *db_b = 24721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (const struct ext2_db_entry *) b; 24821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 24921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (db_a->blk != db_b->blk) 2503cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->blk - db_b->blk); 25121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 25221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (db_a->ino != db_b->ino) 2533cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->ino - db_b->ino); 25421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2553cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->blockcnt - db_b->blockcnt); 25621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 25721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 258549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'oint ext2fs_dblist_count(ext2_dblist dblist) 259549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o{ 260549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o return (int) dblist->count; 261549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o} 26252b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 26352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'oerrcode_t ext2fs_dblist_get_last(ext2_dblist dblist, 26452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o struct ext2_db_entry **entry) 26552b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o{ 26652b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o errcode_t retval; 26752b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 26852b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 26952b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27052b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (dblist->count == 0) 27152b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return EXT2_ET_DBLIST_EMPTY; 27252b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (entry) 27452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o *entry = dblist->list + ( (int) dblist->count-1); 27552b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return 0; 27652b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o} 27752b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27852b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'oerrcode_t ext2fs_dblist_drop_last(ext2_dblist dblist) 27952b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o{ 28052b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 28152b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 28252b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (dblist->count == 0) 28352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return EXT2_ET_DBLIST_EMPTY; 28452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 28552b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o dblist->count--; 28652b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return 0; 28752b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o} 288