Hi,
The code in clear_remove() and clear_inodedeps() does not iterate over
the pagedep and inodedep hash tables correctly. The last entry in the
table is skipped -- this is due to the fact that 'pagedep_hash' and
'inodedep_hash' hold the size of the hash tables - 1.
-p.
Index: ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.116
diff -u -p -r1.116 ffs_softdep.c
--- ufs/ffs/ffs_softdep.c 17 Feb 2013 17:39:29 -0000 1.116
+++ ufs/ffs/ffs_softdep.c 25 Mar 2013 10:36:26 -0000
@@ -5320,9 +5320,9 @@ clear_remove(struct proc *p)
ino_t ino;
ACQUIRE_LOCK(&lk);
- for (cnt = 0; cnt < pagedep_hash; cnt++) {
+ for (cnt = 0; cnt <= pagedep_hash; cnt++) {
pagedephd = &pagedep_hashtbl[next++];
- if (next >= pagedep_hash)
+ if (next > pagedep_hash)
next = 0;
LIST_FOREACH(pagedep, pagedephd, pd_hash) {
if (LIST_FIRST(&pagedep->pd_dirremhd) == NULL)
@@ -5376,9 +5376,9 @@ clear_inodedeps(struct proc *p)
* We will then gather up all the inodes in its block
* that have dependencies and flush them out.
*/
- for (cnt = 0; cnt < inodedep_hash; cnt++) {
+ for (cnt = 0; cnt <= inodedep_hash; cnt++) {
inodedephd = &inodedep_hashtbl[next++];
- if (next >= inodedep_hash)
+ if (next > inodedep_hash)
next = 0;
if ((inodedep = LIST_FIRST(inodedephd)) != NULL)
break;