Module Name: src Committed By: reinoud Date: Sun Jul 7 19:31:26 UTC 2013
Modified Files: src/sys/kern: vfs_dirhash.c src/sys/sys: dirhash.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/kern/vfs_dirhash.c cvs rdiff -u -r1.5 -r1.6 src/sys/sys/dirhash.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_dirhash.c diff -u src/sys/kern/vfs_dirhash.c:1.10 src/sys/kern/vfs_dirhash.c:1.11 --- src/sys/kern/vfs_dirhash.c:1.10 Fri Feb 6 23:56:26 2009 +++ src/sys/kern/vfs_dirhash.c Sun Jul 7 19:31:26 2013 @@ -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 *di 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, str 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 *dir *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); +} + Index: src/sys/sys/dirhash.h diff -u src/sys/sys/dirhash.h:1.5 src/sys/sys/dirhash.h:1.6 --- src/sys/sys/dirhash.h:1.5 Sun Sep 27 21:50:48 2009 +++ src/sys/sys/dirhash.h Sun Jul 7 19:31:26 2013 @@ -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 *, con 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_ */