dblist.c revision 543547a52a20cb7e69d74921b2f691078fd55d83
121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * dblist.c -- directory block list functions 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright 1997 by Theodore Ts'o 5efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header% 1021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 1121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 1221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <stdio.h> 134cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 1421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <unistd.h> 154cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 1621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <string.h> 1721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include <time.h> 1821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 19b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 2021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include "ext2fsP.h" 2121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 224c77fe50d97a773e32a4756c79dade3adbb6a601Theodore Ts'ostatic EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b); 2321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 2521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Returns the number of directories in the filesystem as reported by 2621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * the group descriptors. Of course, the group descriptors could be 2721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * wrong! 2821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 2931dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs) 3021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 312eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o dgrp_t i; 3231dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t num_dirs, max_dirs; 3321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 3421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 35efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o num_dirs = 0; 3779b05dbed2003cd678ba6b210695420486ce920dTheodore Ts'o max_dirs = fs->super->s_inodes_per_group; 385be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o for (i = 0; i < fs->group_desc_count; i++) { 395be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o if (fs->group_desc[i].bg_used_dirs_count > max_dirs) 4079b05dbed2003cd678ba6b210695420486ce920dTheodore Ts'o num_dirs += max_dirs / 8; 415be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o else 425be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o num_dirs += fs->group_desc[i].bg_used_dirs_count; 435be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o } 445be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o if (num_dirs > fs->super->s_inodes_count) 455be8dc2143c7b3b21a9b8fb56797dd855ee87560Theodore Ts'o num_dirs = fs->super->s_inodes_count; 4621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 4721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *ret_num_dirs = num_dirs; 4821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 4921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 5021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 5121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 5221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 53a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * helper function for making a new directory block list (for 54a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * initialize and copy). 5521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 5631dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'ostatic errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count, 57a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o struct ext2_db_entry *list, 58a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist *ret_dblist) 5921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 6021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o ext2_dblist dblist; 6121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o errcode_t retval; 62a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o size_t len; 6321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 6421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 6521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 6621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if ((ret_dblist == 0) && fs->dblist && 6721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST)) 6821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 6921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 70c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist); 717b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 727b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 7321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o memset(dblist, 0, sizeof(struct ext2_struct_dblist)); 7421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 7521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->magic = EXT2_ET_MAGIC_DBLIST; 7621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->fs = fs; 77a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (size) 78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->size = size; 79a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o else { 80a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = ext2fs_get_num_dirs(fs, &dblist->size); 81a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 82a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o goto cleanup; 831e1da29fbd4204a267ebd7c64d37e1f95a9dad08Theodore Ts'o dblist->size = (dblist->size * 2) + 12; 84a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o } 853cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o len = (size_t) sizeof(struct ext2_db_entry) * dblist->size; 86a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->count = count; 87ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry), 88ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o &dblist->list); 897b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 9021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o goto cleanup; 91efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 92a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (list) 93a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memcpy(dblist->list, list, len); 9421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o else 95a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o memset(dblist->list, 0, len); 962eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o if (ret_dblist) 972eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o *ret_dblist = dblist; 982eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o else 992eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o fs->dblist = dblist; 10021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 10121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ocleanup: 10221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (dblist) 103c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&dblist); 10421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return retval; 10521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 10621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 10721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 108a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Initialize a directory block list 109a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */ 110a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist) 111a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{ 112a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist dblist; 113a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o errcode_t retval; 114a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 115a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = make_dblist(fs, 0, 0, 0, &dblist); 116a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 117a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return retval; 118a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 119a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->sorted = 1; 120a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (ret_dblist) 121a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *ret_dblist = dblist; 122a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o else 123a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o fs->dblist = dblist; 124a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 125a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return 0; 126a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o} 127a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 128a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/* 129a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o * Copy a directory block list 130a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o */ 131a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'oerrcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest) 132a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o{ 133a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o ext2_dblist dblist; 134a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o errcode_t retval; 135a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 136a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o retval = make_dblist(src->fs, src->size, src->count, src->list, 137a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o &dblist); 138a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o if (retval) 139a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return retval; 140a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o dblist->sorted = src->sorted; 141a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o *dest = dblist; 142a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o return 0; 143a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o} 144a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o 145a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o/* 14621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Close a directory block list 14721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 14821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * (moved to closefs.c) 14921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 15021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 15121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 15221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 15321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Add a directory block to the directory block list 15421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 15531dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 15621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o int blockcnt) 15721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 158b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o struct ext2_db_entry *new_entry; 1597b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o errcode_t retval; 16076f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o unsigned long old_size; 161efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 16221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 16321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 16421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (dblist->count >= dblist->size) { 16576f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o old_size = dblist->size * sizeof(struct ext2_db_entry); 1669f9e5c3aea024c92c50e8bb834a3ea33d9e1f55dAndreas Dilger dblist->size += dblist->size > 200 ? dblist->size / 2 : 100; 16776f875daa1c9c2cdc72f0c6f0f7be4bbc7f0fc07Theodore Ts'o retval = ext2fs_resize_mem(old_size, (size_t) dblist->size * 1687b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o sizeof(struct ext2_db_entry), 169c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &dblist->list); 1707b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) { 17121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->size -= 100; 1727b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 17321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 17421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 175b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry = dblist->list + ( (int) dblist->count++); 176b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->blk = blk; 177b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->ino = ino; 178b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o new_entry->blockcnt = blockcnt; 17921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o dblist->sorted = 0; 18121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 18321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 18421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 18521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o/* 186521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o * Change the directory block to the directory block list 187521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o */ 18831dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, 189521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o int blockcnt) 190521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o{ 1912eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o dgrp_t i; 192efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 193521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 194521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o 195521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o for (i=0; i < dblist->count; i++) { 196521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o if ((dblist->list[i].ino != ino) || 197521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o (dblist->list[i].blockcnt != blockcnt)) 198521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o continue; 199521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o dblist->list[i].blk = blk; 200521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o dblist->sorted = 0; 201521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o return 0; 202521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o } 2031f0b6c1f895d189fea6999d0c07a7fee936a4baaTheodore Ts'o return EXT2_ET_DB_NOT_FOUND; 204521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o} 205521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o 206ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'ovoid ext2fs_dblist_sort(ext2_dblist dblist, 207ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o EXT2_QSORT_TYPE (*sortfunc)(const void *, 208ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o const void *)) 209ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o{ 210ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o if (!sortfunc) 211ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o sortfunc = dir_block_cmp; 212ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o qsort(dblist->list, (size_t) dblist->count, 213ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o sizeof(struct ext2_db_entry), sortfunc); 214ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o dblist->sorted = 1; 215ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o} 216ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o 217521e36857227b21e7ab47b0a97f788d2af9f9717Theodore Ts'o/* 21821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * This function iterates over the directory block list 21921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o */ 22021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'oerrcode_t ext2fs_dblist_iterate(ext2_dblist dblist, 22121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o int (*func)(ext2_filsys fs, 22221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o struct ext2_db_entry *db_info, 223b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data), 224b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data) 22521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 22631dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t i; 22731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o int ret; 228efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 22921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 23021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 231ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o if (!dblist->sorted) 232ea1959f01523ffc105747d660ccc5b7f02805928Theodore Ts'o ext2fs_dblist_sort(dblist, 0); 23321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o for (i=0; i < dblist->count; i++) { 234b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data); 23521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (ret & DBLIST_ABORT) 23621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 23721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 23821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return 0; 23921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 24021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2414c77fe50d97a773e32a4756c79dade3adbb6a601Theodore Ts'ostatic EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) 24221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{ 24321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o const struct ext2_db_entry *db_a = 24421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (const struct ext2_db_entry *) a; 24521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o const struct ext2_db_entry *db_b = 24621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o (const struct ext2_db_entry *) b; 24721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 24821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (db_a->blk != db_b->blk) 2493cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->blk - db_b->blk); 250efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 25121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (db_a->ino != db_b->ino) 2523cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->ino - db_b->ino); 25321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 2543cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o return (int) (db_a->blockcnt - db_b->blockcnt); 25521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o} 25621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 257549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'oint ext2fs_dblist_count(ext2_dblist dblist) 258549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o{ 259549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o return (int) dblist->count; 260549860c5c7a5a2974c103a55d881fbd5701aff13Theodore Ts'o} 26152b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 262efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_dblist_get_last(ext2_dblist dblist, 26352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o struct ext2_db_entry **entry) 26452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o{ 26552b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 26652b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 26752b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (dblist->count == 0) 26852b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return EXT2_ET_DBLIST_EMPTY; 26952b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27052b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (entry) 27152b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o *entry = dblist->list + ( (int) dblist->count-1); 27252b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return 0; 27352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o} 27452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27552b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'oerrcode_t ext2fs_dblist_drop_last(ext2_dblist dblist) 276efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o{ 27752b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); 27852b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 27952b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o if (dblist->count == 0) 28052b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return EXT2_ET_DBLIST_EMPTY; 28152b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o 28252b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o dblist->count--; 28352b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o return 0; 28452b1dd5e496c199e9cbcc238f26fd2264a07a2cfTheodore Ts'o} 285