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_ */

Reply via email to