r14986: Fix OS/2 directory delete bug found by kukks.
authorJeremy Allison <jra@samba.org>
Sat, 8 Apr 2006 05:00:04 +0000 (05:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:15:55 +0000 (11:15 -0500)
(Thanks a lot for all your hard work on this).
We were caching the results of *all* directory
scans, not just the results that match the
client wildcard. This actually made no sense,
as only matches on the client wildcard can be
returned to the client and so might need to
be searched for in the cache. This fixes the
directory cache to only cache entries that we
return to the client.
Jeremy.
(This used to be commit c88af597d042390ff11b26fe802b0b10d0faa6ce)

source3/smbd/dir.c
source3/smbd/trans2.c

index 81fe7c40218e3351cee6d8cf611529171a5b56c3..cd6c1b0bda352652bbe399bf4b1de42604563d4a 100644 (file)
@@ -644,6 +644,15 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S
        return False;
 }
 
+/****************************************************************************
+ Add the name we're returning into the underlying cache.
+****************************************************************************/
+
+void dptr_DirCacheAdd(struct dptr_struct *dptr, const char *name, long offset)
+{
+       DirCacheAdd(dptr->dir_hnd, name, offset);
+}
+
 /****************************************************************************
  Fill the 5 byte server reserved dptr field.
 ****************************************************************************/
@@ -812,6 +821,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn
                        DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
 
                        found = True;
+
+                       DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff);
                }
        }
 
@@ -1109,21 +1120,15 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
        }
 
        while ((n = vfs_readdirname(conn, dirp->dir))) {
-               struct name_cache_entry *e;
                /* Ignore . and .. - we've already returned them. */
                if (*n == '.') {
                        if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
                                continue;
                        }
                }
-               dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
-               dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE;
-               e = &dirp->name_cache[dirp->name_cache_index];
-               SAFE_FREE(e->name);
-               e->name = SMB_STRDUP(n);
-               *poffset = e->offset= dirp->offset;
+               *poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
                dirp->file_number++;
-               return e->name;
+               return n;
        }
        *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
        return NULL;
@@ -1183,6 +1188,21 @@ long TellDir(struct smb_Dir *dirp)
        return(dirp->offset);
 }
 
+/*******************************************************************
+ Add an entry into the dcache.
+********************************************************************/
+
+void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset)
+{
+       struct name_cache_entry *e;
+
+       dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE;
+       e = &dirp->name_cache[dirp->name_cache_index];
+       SAFE_FREE(e->name);
+       e->name = SMB_STRDUP(name);
+       e->offset = offset;
+}
+
 /*******************************************************************
  Find an entry by name. Leave us at the offset after it.
  Don't check for veto or invisible files.
index 8429cd71491cc7e814a60f98757b74f8eb7558b9..4f5039e86c332e0f97e00929342cbd4ae951d705 100644 (file)
@@ -1163,6 +1163,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
          
                        found = True;
+
+                       dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
                }
        }