X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=adu.c;h=4c1c62c0d56bb3955dabd1cfb52499d6d6fca4a3;hb=b542a1e3c66b7b01cd2dc91749c5154e25cbff1e;hp=c21df0b3aa5daa3136b5638a74127d803b373f69;hpb=49353a00223b95a49f5750d3dcf1501a3f17c4c2;p=adu.git diff --git a/adu.c b/adu.c index c21df0b..4c1c62c 100644 --- a/adu.c +++ b/adu.c @@ -28,6 +28,9 @@ uint64_t num_bytes = 0; /** The number of different uids found so far. */ uint32_t num_uids = 0; +/** This is always a power of two. It is set in create_hash_table(). */ +static uint32_t uid_hash_table_size; + /** * Contains info for each user that owns at least one regular file. * @@ -35,7 +38,7 @@ uint32_t num_uids = 0; * option occupy a slot in this hash table. This allows to find out * quicky whether a uid is admissible. And yes, this has to be fast. */ -struct user_info *uid_hash_table = NULL; +static struct user_info *uid_hash_table; /** * The table containing the directory names and statistics. @@ -285,10 +288,29 @@ err: return ret; } +int for_each_admissible_user(int (*func)(struct user_info *, void *), + void *data) +{ + struct user_info *ui = uid_hash_table; + + if (!ui) + return -ERRNO_TO_ERROR(EFAULT); + + for (; ui < uid_hash_table + uid_hash_table_size; ui++) { + int ret; + + if (!ui_used(ui) || !ui_admissible(ui)) + continue; + ret = func(ui, data); + if (ret < 0) + return ret; + } + return 1; +} + #define PRIME1 0x811c9dc5 #define PRIME2 0x01000193 -uint32_t uid_hash_table_size; void create_hash_table(unsigned bits) { uid_hash_table_size = 1 << bits; @@ -315,12 +337,10 @@ static void close_dir_table(void) dir_table = NULL; } -static void close_user_table(struct user_info *ui) +static int close_user_table(struct user_info *ui, __a_unused void *data) { int ret; - if (!ui || !ui_used(ui) || !ui_admissible(ui)) - return; ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN)); if (ret < 0) ERROR_LOG("failed to close user table %u: %s\n", @@ -335,14 +355,12 @@ static void close_user_table(struct user_info *ui) ui->desc = NULL; ui->table = NULL; ui->flags = 0; + return 1; } static void close_user_tables(void) { - struct user_info *ui; - - FOR_EACH_USER(ui) - close_user_table(ui); + for_each_admissible_user(close_user_table, NULL); } void close_all_tables(void)