DragonFly bugs List (threaded) for 2008-05
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Seekdir Bug
There is a bug in all seekdir()/readdir() implementations in all BSDs:
Under some circumstance, a seekdir() will no take you to the expected
position, but one further. This happens when the first entry in a
block has been unlinked and you seekdir to the second. In this case
seekdir() overshoots by one entry.
_readdir_unlocked() must not skip deleted entries when being called
from _seekdir().
A diff is attached.
- Marc Balmer
--- readdir.c.orig Fri May 2 10:25:47 2008
+++ readdir.c Fri May 2 10:27:18 2008
@@ -51,7 +51,7 @@
* get next entry in a directory.
*/
struct dirent *
-_readdir_unlocked(DIR *dirp)
+_readdir_unlocked(DIR *dirp, int skipdeleted)
{
struct dirent *dp;
long dummy;
@@ -73,7 +73,7 @@
if (_DIRENT_DIRSIZ(dp) > dirp->dd_len + 1 - dirp->dd_loc)
return (NULL);
dirp->dd_loc += _DIRENT_DIRSIZ(dp);
- if (dp->d_ino == 0)
+ if (dp->d_ino == 0 && skipdeleted)
continue;
if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
continue;
@@ -88,7 +88,7 @@
if (__isthreaded)
_pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
- dp = _readdir_unlocked(dirp);
+ dp = _readdir_unlocked(dirp, 0);
if (__isthreaded)
_pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
@@ -105,10 +105,10 @@
errno = 0;
if (__isthreaded)
_pthread_mutex_lock((pthread_mutex_t *)&dirp->dd_lock);
- if ((dp = _readdir_unlocked(dirp)) != NULL)
+ if ((dp = _readdir_unlocked(dirp, 0)) != NULL)
memcpy(entry, dp, _DIRENT_MINSIZ(dp));
if (__isthreaded)
- _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock);
+ _pthread_mutex_unlock((pthread_mutex_t *)&dirp->dd_lock, 0);
if (errno != 0) {
if (dp == NULL) {
--- telldir.c.orig Fri May 2 10:25:58 2008
+++ telldir.c Fri May 2 10:26:02 2008
@@ -148,7 +148,7 @@
* load a new buffer or for dd_loc to not match directly.
*/
while (dirp->dd_loc < lp->loc_loc && dirp->dd_seek == lp->loc_seek) {
- dp = _readdir_unlocked(dirp);
+ dp = _readdir_unlocked(dirp, 1);
if (dp == NULL)
break;
}
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]