Updated to version 2.15

Added more debug output to the cache free/invalidate/fill functionality.

The Action_ExamineNext() function could omit the last directory entry. Oops.
This commit is contained in:
obarthel
2019-02-16 11:12:38 +01:00
parent 577723f797
commit 52aeb951a0
6 changed files with 107 additions and 70 deletions
+2 -3
View File
@@ -7474,7 +7474,6 @@ Action_ExamineNext(
struct LockNode * ln;
LONG result = DOSFALSE;
int error = OK;
int eof = FALSE;
LONG offset;
ENTER();
@@ -7529,7 +7528,7 @@ Action_ExamineNext(
SHOWMSG("calling 'smba_readdir'");
SHOWVALUE(offset);
smba_readdir(ln->ln_File,offset,fib,(smba_callback_t)dir_scan_callback_func_exnext,&eof,&error);
smba_readdir(ln->ln_File,offset,fib,(smba_callback_t)dir_scan_callback_func_exnext,NULL,&error);
if(error != OK)
{
@@ -7546,7 +7545,7 @@ Action_ExamineNext(
* returned all the entries available. There are no
* further entries to be delivered.
*/
if(eof || fib->fib_FileName[0] == '\0')
if(fib->fib_FileName[0] == '\0')
{
SHOWMSG("nothing to be read");
fib->fib_DiskKey = -1;
+21 -26
View File
@@ -2645,24 +2645,24 @@ smb_proc_readdir_short (
LOG (("skipped entry; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
}
else if (entry == NULL)
/* Was the cache invalidated, or there are no further
* cache entries to be filled?
*/
else if (entry == NULL || !dircache->is_valid)
{
result = total_count - fpos;
goto out;
}
else if (smb_decode_dirent (p, entry) == 0)
{
entry = get_next_dircache_entry(dircache);
}
else
{
if(smb_decode_dirent (p, entry) == 0)
{
entry = get_next_dircache_entry(dircache);
}
else
{
p += SMB_DIRINFO_SIZE;
p += SMB_DIRINFO_SIZE;
LOG (("skipped entry because name is too long; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
}
LOG (("skipped entry because name is too long; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
}
total_count += 1;
@@ -3325,18 +3325,11 @@ smb_proc_readdir_long (
LOG (("skipped entry; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
}
else if (entry == NULL)
/* Did we run out of cache, or the cache was invalidated? */
else if (entry == NULL || !dircache->is_valid)
{
smb_decode_long_dirent (server, p, NULL, info_level, &entry_length);
if(entry_length == 0)
{
LOG (("no more entries available; stopping.\n"));
break;
}
LOG (("skipped entry; total_count = %ld, i = %ld, fpos = %ld\n", total_count, i, fpos));
continue;
LOG (("no more entries available; stopping.\n"));
break;
}
else
{
@@ -3725,13 +3718,15 @@ smb_proc_getattrE (struct smb_server *server, struct smb_dirent *entry, int * er
goto out;
}
entry->ctime = date_dos2unix (WVAL (buf, smb_vwv1), WVAL (buf, smb_vwv0));
entry->atime = date_dos2unix (WVAL (buf, smb_vwv3), WVAL (buf, smb_vwv2));
entry->mtime = date_dos2unix (WVAL (buf, smb_vwv5), WVAL (buf, smb_vwv4));
entry->wtime = entry->mtime;
entry->ctime = date_dos2unix (WVAL (buf, smb_vwv1), WVAL (buf, smb_vwv0));
entry->atime = date_dos2unix (WVAL (buf, smb_vwv3), WVAL (buf, smb_vwv2));
entry->mtime = date_dos2unix (WVAL (buf, smb_vwv5), WVAL (buf, smb_vwv4));
entry->wtime = entry->mtime;
entry->size_low = DVAL (buf, smb_vwv6);
entry->size_high = 0;
entry->attr = WVAL (buf, smb_vwv10);
entry->attr = WVAL (buf, smb_vwv10);
#if DEBUG
{
+65 -31
View File
@@ -426,15 +426,20 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
if (!f->is_valid || f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
{
if (!f->is_valid || f->attr_time == 0)
LOG(("file attributes not yet known\n"));
else
LOG(("file attributes need to be updated\n"));
if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
SHOWMSG("using the LAN Manager 2.0 getattr() variant");
LOG(("using the LAN Manager 2.0 getattr() variant\n"));
result = smb_query_path_information (&s->server, f->dirent.complete_path, f->dirent.len, 0, &f->dirent, error_ptr);
}
else
{
SHOWMSG("using the legacy getattr() variant");
LOG(("using the legacy getattr() variant\n"));
result = smb_proc_getattr_core (&s->server, f->dirent.complete_path, f->dirent.len, &f->dirent, error_ptr);
}
@@ -453,7 +458,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
{
LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
SHOWMSG("using the LAN Manager 2.0 open() variant");
LOG(("using the LAN Manager 2.0 open() variant\n"));
result = smb_proc_open (&s->server, f->dirent.complete_path, f->dirent.len, writable, truncate_file, &f->dirent, error_ptr);
if (result < 0)
@@ -471,7 +476,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
{
LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
SHOWMSG("using the legacy open() variant");
LOG(("using the legacy open() variant\n"));
result = smb_proc_open (&s->server, f->dirent.complete_path, f->dirent.len, writable, truncate_file, &f->dirent, error_ptr);
if (result < 0)
@@ -503,7 +508,11 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate_file, int *
else
{
if (f->dircache != NULL)
{
LOG(("discarding the '%s' directory cache\n", escape_name(f->dirent.complete_path)));
invalidate_dircache(f->dircache);
}
}
f->attr_time = get_current_time();
@@ -584,7 +593,10 @@ smba_open (
f->dirent.len = strlen (name);
f->server = s;
LOG(("open '%s' (writable=%s, truncate_file=%s)\n", escape_name(name), writable ? "yes" : "no", truncate_file ? "yes" : "no"));
LOG(("open '%s' (writable=%s, truncate_file=%s)\n",
escape_name(name),
writable ? "yes" : "no",
truncate_file ? "yes" : "no"));
result = make_open (f, open_dont_need_fid, writable, truncate_file, error_ptr);
if (result < 0)
@@ -630,7 +642,7 @@ write_attr (smba_file_t * f, int * error_ptr)
LOG(("mtime = %lu\n",f->dirent.mtime));
LOG(("ctime = %lu\n",f->dirent.ctime));
SHOWMSG("using the LAN Manager 2.0 open() variant");
LOG(("using the LAN Manager 2.0 open() variant\n"));
result = make_open (f, open_need_fid, open_writable, open_dont_truncate, error_ptr);
if (result < 0)
@@ -659,7 +671,7 @@ write_attr (smba_file_t * f, int * error_ptr)
LOG(("mtime = %lu\n",f->dirent.mtime));
LOG(("ctime = %lu\n",f->dirent.ctime));
SHOWMSG("using the legacy open() variant");
LOG(("using the legacy open() variant\n"));
result = make_open (f, open_dont_need_fid, open_writable, open_dont_truncate, error_ptr);
if (result < 0)
@@ -995,7 +1007,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs
if (result < 0)
goto out;
SHOWVALUE(f->server->server.max_buffer_size);
D(("maximum buffer size = %ld\n", f->server->server.max_buffer_size));
max_buffer_size = f->server->server.max_buffer_size;
@@ -1264,11 +1276,14 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
if (f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
{
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
LOG (("file '%s' attributes %s\n",
escape_name(f->dirent.complete_path),
(f->attr_time == 0) ? "are not yet known" : "need to be updated"
));
if (!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
SHOWMSG("using the LAN Manager 2.0 path query variant");
LOG(("using the LAN Manager 2.0 path query variant\n"));
if (f->dirent.opened)
result = smb_query_path_information (&f->server->server, NULL, 0, f->dirent.fileid, &f->dirent, error_ptr);
@@ -1277,7 +1292,7 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
}
else
{
SHOWMSG("using the legacy path query variant");
LOG(("using the legacy path query variant\n"));
if (f->dirent.opened && f->server->supports_E)
{
@@ -1388,13 +1403,13 @@ smba_setattr (smba_file_t * f, const smba_stat_t * st, const QUAD * const size,
if(!f->server->server.prefer_core_protocol && f->server->server.protocol >= PROTOCOL_LANMAN2)
{
SHOWMSG("using the LAN Manager 2.0 trunc variant");
LOG(("using the LAN Manager 2.0 trunc variant\n"));
result = smb_set_file_information (&f->server->server, &f->dirent, size, error_ptr);
}
else
{
SHOWMSG("using the legacy trunc variant (which cannot truncate files)");
LOG(("using the legacy trunc variant (which cannot truncate files)\n"));
result = smb_proc_trunc (&f->server->server, &f->dirent, size->Low, error_ptr);
}
@@ -1423,7 +1438,8 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
int result;
ULONG now;
(*eof_ptr) = 0;
if(eof_ptr != NULL)
(*eof_ptr) = FALSE;
result = make_open (f, open_dont_need_fid, open_read_only, open_dont_truncate, error_ptr);
if (result < 0)
@@ -1460,9 +1476,9 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
/* has the cache already become stale? */
if (now > f->dircache->created_at && now - f->dircache->created_at >= DIR_CACHE_TIME)
{
reset_dircache(f->dircache);
LOG (("cache for '%s' has become stale\n", escape_name(f->dircache->cache_for->dirent.complete_path)));
LOG (("cache outdated\n"));
reset_dircache(f->dircache);
}
}
@@ -1495,6 +1511,9 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
/* We stop on error, or if the directory is empty. */
if (num_entries <= 0)
{
if (num_entries == 0)
LOG(("no directory entries read\n"));
result = num_entries;
goto out;
}
@@ -1524,26 +1543,31 @@ smba_readdir (smba_file_t * f, int offs, void *callback_data, smba_callback_t ca
/* is this the last directory entry to be delivered? */
eof = (o >= (f->dircache->cache_used - 1) && f->dircache->eof);
if(eof)
(*eof_ptr) = 1;
if(eof && eof_ptr != NULL)
(*eof_ptr) = TRUE;
count++;
dirent = &f->dircache->cache[o];
LOG (("delivering '%s', cache_index=%ld, last entry=%s\n", escape_name(dirent->complete_path), cache_index, eof ? "yes" : "no"));
LOG (("delivering '%s', cache_index=%ld, last entry=%s\n",
escape_name(dirent->complete_path),
cache_index,
eof ? "yes" : "no")
);
data.is_dir = (dirent->attr & SMB_FILE_ATTRIBUTE_DIRECTORY) != 0;
data.is_read_only = (dirent->attr & SMB_FILE_ATTRIBUTE_READONLY) != 0;
data.is_hidden = (dirent->attr & SMB_FILE_ATTRIBUTE_HIDDEN) != 0;
data.is_system = (dirent->attr & SMB_FILE_ATTRIBUTE_SYSTEM) != 0;
data.was_changed_since_last_archive = (dirent->attr & SMB_FILE_ATTRIBUTE_ARCHIVE) != 0;
data.size_low = dirent->size_low;
data.size_high = dirent->size_high;
data.atime = dirent->atime;
data.ctime = dirent->ctime;
data.mtime = dirent->mtime;
data.size_low = dirent->size_low;
data.size_high = dirent->size_high;
data.atime = dirent->atime;
data.ctime = dirent->ctime;
data.mtime = dirent->mtime;
if ((*callback) (callback_data, cache_index, cache_index + 1, dirent->complete_path, eof, &data))
break;
@@ -1570,6 +1594,9 @@ reset_dircache (dircache_t * dircache)
/*****************************************************************************/
/* Get the first directory cache entry, or return NULL
* if the cache has been invalidated.
*/
struct smb_dirent *
get_first_dircache_entry(dircache_t * dircache)
{
@@ -1593,6 +1620,9 @@ get_first_dircache_entry(dircache_t * dircache)
/*****************************************************************************/
/* Get the next available directory cache entry, or return
* NULL if the cache has been exhauste (or is no longer valid).
*/
struct smb_dirent *
get_next_dircache_entry(dircache_t * dircache)
{
@@ -1620,6 +1650,10 @@ get_next_dircache_entry(dircache_t * dircache)
/*****************************************************************************/
/* Invalidate the directory cache, which has the effect that adding
* new entries to it will fail until it has been reinitialized
* by reset_dircache().
*/
static void
invalidate_dircache(dircache_t * dircache)
{
@@ -1698,7 +1732,7 @@ smba_create (smba_file_t * dir, const char *name, int truncate, int * error_ptr)
if (!dir->server->server.prefer_core_protocol && dir->server->server.protocol >= PROTOCOL_LANMAN2)
{
SHOWMSG("using the LAN Manager 2.0 creat variant");
LOG(("using the LAN Manager 2.0 creat variant\n"));
result = smb_proc_open (&dir->server->server, path, path_len, open_writable, truncate, &entry, error_ptr);
if(result < 0)
@@ -1706,7 +1740,7 @@ smba_create (smba_file_t * dir, const char *name, int truncate, int * error_ptr)
}
else
{
SHOWMSG("using the legacy creat variant");
LOG(("using the legacy creat variant\n"));
result = smb_proc_create (&dir->server->server, path, path_len, &entry, error_ptr);
if(result < 0)
@@ -1819,10 +1853,10 @@ close_path (smba_server_t * s, const char *path, int * error_ptr)
if(sn != NULL)
{
/* Walk through all the files, marking them as no longer
* valid and closing them, if necessary. Note that we
* do not remove them from the list of open files, we just
* mark them for reopening later, if needed.
*/
* valid and closing them, if necessary. Note that we
* do not remove them from the list of open files, we just
* mark them for reopening later, if needed.
*/
for((void)NULL ; sn != NULL ; sn = sn->sn_next)
{
p = sn->sn_userdata;
+5 -5
View File
@@ -1,6 +1,6 @@
#define VERSION 2
#define REVISION 14
#define DATE "15.2.2019"
#define VERS "smbfs 2.14"
#define VSTRING "smbfs 2.14 (15.2.2019)\r\n"
#define VERSTAG "\0$VER: smbfs 2.14 (15.2.2019)"
#define REVISION 15
#define DATE "16.2.2019"
#define VERS "smbfs 2.15"
#define VSTRING "smbfs 2.15 (16.2.2019)\r\n"
#define VERSTAG "\0$VER: smbfs 2.15 (16.2.2019)"
+1 -1
View File
@@ -1 +1 @@
14
15