Extend generic dirhash to include an empty directory checker based on
the knowledge the dirhash has. This is done by keeping a count of the current hash entries.
This commit is contained in:
parent
7716d8c63e
commit
8fd5b25064
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vfs_dirhash.c,v 1.10 2009/02/06 23:56:26 enami Exp $ */
|
||||
/* $NetBSD: vfs_dirhash.c,v 1.11 2013/07/07 19:31:26 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Reinoud Zandijk
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_dirhash.c,v 1.10 2009/02/06 23:56:26 enami Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_dirhash.c,v 1.11 2013/07/07 19:31:26 reinoud Exp $");
|
||||
|
||||
/* CLEAN UP! */
|
||||
#include <sys/param.h>
|
||||
|
@ -165,6 +165,7 @@ dirhash_purge_entries(struct dirhash *dirh)
|
|||
|
||||
dirh->flags &= ~DIRH_COMPLETE;
|
||||
dirh->flags |= DIRH_PURGED;
|
||||
dirh->num_files = 0;
|
||||
|
||||
dirhashsize -= dirh->size;
|
||||
dirh->size = 0;
|
||||
|
@ -309,6 +310,7 @@ dirhash_enter(struct dirhash *dirh,
|
|||
dirh_e->entry_size = entry_size;
|
||||
|
||||
dirh->size += sizeof(struct dirhash_entry);
|
||||
dirh->num_files++;
|
||||
dirhashsize += sizeof(struct dirhash_entry);
|
||||
LIST_INSERT_HEAD(&dirh->entries[hashline], dirh_e, next);
|
||||
}
|
||||
|
@ -378,6 +380,8 @@ dirhash_remove(struct dirhash *dirh, struct dirent *dirent,
|
|||
KASSERT(dirh_e->entry_size == entry_size);
|
||||
LIST_REMOVE(dirh_e, next);
|
||||
dirh->size -= sizeof(struct dirhash_entry);
|
||||
KASSERT(dirh->num_files > 0);
|
||||
dirh->num_files--;
|
||||
dirhashsize -= sizeof(struct dirhash_entry);
|
||||
|
||||
dirhash_enter_freed(dirh, offset, entry_size);
|
||||
|
@ -469,3 +473,33 @@ dirhash_lookup_freed(struct dirhash *dirh, uint32_t min_entrysize,
|
|||
*result = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
dirhash_dir_isempty(struct dirhash *dirh)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
struct dirhash_entry *dirh_e;
|
||||
int hashline, num;
|
||||
|
||||
num = 0;
|
||||
for (hashline = 0; hashline < DIRHASH_HASHSIZE; hashline++) {
|
||||
LIST_FOREACH(dirh_e, &dirh->entries[hashline], next) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirh->num_files != num) {
|
||||
printf("dirhash_dir_isempy: dirhash_counter failed: "
|
||||
"dirh->num_files = %d, counted %d\n",
|
||||
dirh->num_files, num);
|
||||
assert(dirh->num_files == num);
|
||||
}
|
||||
#endif
|
||||
/* assert the directory hash info is valid */
|
||||
KASSERT(dirh->flags & DIRH_COMPLETE);
|
||||
|
||||
/* the directory is empty when only '..' lifes in it or is absent */
|
||||
return (dirh->num_files <= 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: dirhash.h,v 1.5 2009/09/27 21:50:48 reinoud Exp $ */
|
||||
/* $NetBSD: dirhash.h,v 1.6 2013/07/07 19:31:26 reinoud Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Reinoud Zandijk
|
||||
|
@ -52,6 +52,7 @@ struct dirhash {
|
|||
uint32_t flags;
|
||||
uint32_t size; /* in bytes */
|
||||
uint32_t refcnt;
|
||||
uint32_t num_files;
|
||||
LIST_HEAD(, dirhash_entry) entries[DIRHASH_HASHSIZE];
|
||||
LIST_HEAD(, dirhash_entry) free_entries;
|
||||
TAILQ_ENTRY(dirhash) next;
|
||||
|
@ -79,5 +80,6 @@ int dirhash_lookup(struct dirhash *, const char *, int,
|
|||
struct dirhash_entry **);
|
||||
int dirhash_lookup_freed(struct dirhash *, uint32_t,
|
||||
struct dirhash_entry **);
|
||||
bool dirhash_dir_isempty(struct dirhash *dirh);
|
||||
|
||||
#endif /* _SYS_DIRHASH_H_ */
|
||||
|
|
Loading…
Reference in New Issue