Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111017411
D2410.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D2410.diff
View Options
Index: lib/libc/gen/readdir.c
===================================================================
--- lib/libc/gen/readdir.c
+++ lib/libc/gen/readdir.c
@@ -54,19 +54,25 @@
int skip;
{
struct dirent *dp;
+ long initial_seek;
+ long initial_loc = 0;
for (;;) {
if (dirp->dd_loc >= dirp->dd_size) {
if (dirp->dd_flags & __DTF_READALL)
return (NULL);
+ initial_loc = dirp->dd_loc;
+ dirp->dd_flags &= ~__DTF_SKIPREAD;
dirp->dd_loc = 0;
}
if (dirp->dd_loc == 0 &&
!(dirp->dd_flags & (__DTF_READALL | __DTF_SKIPREAD))) {
+ initial_seek = dirp->dd_seek;
dirp->dd_size = _getdirentries(dirp->dd_fd,
dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
if (dirp->dd_size <= 0)
return (NULL);
+ _fixtelldir(dirp, initial_seek, initial_loc);
}
dirp->dd_flags &= ~__DTF_SKIPREAD;
dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
Index: lib/libc/gen/rewinddir.c
===================================================================
--- lib/libc/gen/rewinddir.c
+++ lib/libc/gen/rewinddir.c
@@ -51,6 +51,7 @@
if (__isthreaded)
_pthread_mutex_lock(&dirp->dd_lock);
+ dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */
if (dirp->dd_flags & __DTF_READALL)
_filldir(dirp, false);
else {
Index: lib/libc/gen/telldir.h
===================================================================
--- lib/libc/gen/telldir.h
+++ lib/libc/gen/telldir.h
@@ -64,5 +64,6 @@
struct dirent *_readdir_unlocked(DIR *, int);
void _reclaim_telldir(DIR *);
void _seekdir(DIR *, long);
+void _fixtelldir(DIR *dirp, long oldseek, long oldloc);
#endif
Index: lib/libc/gen/telldir.c
===================================================================
--- lib/libc/gen/telldir.c
+++ lib/libc/gen/telldir.c
@@ -101,9 +101,21 @@
return;
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
return;
+ /* If it's within the same chunk of data, don't bother reloading */
+ if (lp->loc_seek == dirp->dd_seek) {
+ /*
+ * If we go back to 0 don't make the next readdir
+ * trigger a call to getdirentries()
+ */
+ if (lp->loc_loc == 0)
+ dirp->dd_flags |= __DTF_SKIPREAD;
+ dirp->dd_loc = lp->loc_loc;
+ return;
+ }
(void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
dirp->dd_seek = lp->loc_seek;
dirp->dd_loc = 0;
+ dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */
while (dirp->dd_loc < lp->loc_loc) {
dp = _readdir_unlocked(dirp, 0);
if (dp == NULL)
@@ -112,6 +124,27 @@
}
/*
+ * when we do a read and cross a boundary, any telldir we
+ * just did will have wrong information in it.
+ * We need to move it from "beyond the end of the previous chunk"
+ * to "the beginning of the new chunk"
+ */
+void
+_fixtelldir(DIR *dirp, long oldseek, long oldloc)
+{
+ struct ddloc *lp;
+
+ lp = LIST_FIRST(&dirp->dd_td->td_locq);
+ if (lp != NULL) {
+ if (lp->loc_loc == oldloc &&
+ lp->loc_seek == oldseek) {
+ lp->loc_seek = dirp->dd_seek;
+ lp->loc_loc = dirp->dd_loc;
+ }
+ }
+}
+
+/*
* Reclaim memory for telldir cookies which weren't used.
*/
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 27, 6:47 AM (18 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16863915
Default Alt Text
D2410.diff (3 KB)
Attached To
Mode
D2410: fix (hack) readdir and seekdir to allow samba to correctly delete files
Attached
Detach File
Event Timeline
Log In to Comment