SMB FindFirst/FindNext don't fill in Last Name Offset
This is an interesting bug we ran across with a Windows 7 client.
With a large directory (30k entries) the client would get about 70% of the way through the directory listing, and then of no obvious reason skip back to about 20% of the way through and resume listing there. It would then do that over and over, endlessly while the user stares in boredom at the progress bar.
Updated by Gordon Ross about 8 years ago
After much experimentation, it turns out that the key to making the Win7 client happy is to fill in the Last Name Offset field in the data returned by FindFirst/FindNext. It apparently uses that to construct the "resume name" for it's subsequent FindNext call.
SMB FindFirst/FindNext is complicated by history (and a history of bugs).
A big part of this work was to improve the reliability of the mechanisms "FindNext" supports for continuing a directory listing at a specified name. (SMB calls this the "resume name".) In smb_odir.c, we implement smb_odir_save_fname(), which saves a filename / offset pair. It's a one entry cache used by smb_com_trans2_find_next2 to (more reliably) find the directory offset where we should continue a directory listing, given the specified "resume name". We can get away with a single entry cache for this (per search handle) because the "resume name" is always the last name previously returned. (Clients always continue where they left off.)
In theory, the client could resume anywhere, using any name previously returned via the search handle created by FindFirst, and if they did, our "one entry cache" would "miss". In the unlikely event that a client tries to resume somewhere other than the last name returned, this implementation will fall back to using the "resume key", which the client also provides. There is a "resume key" value with every directory entry returned to the client (it's our directory offset), so this mechanism will work as long as the client faithfully returns the resume key. Now you probably wonder, why don't we just always use these resume keys in FindNext to determine the position where we continue? (That's what this code used to do!:-) The answer: more bugs. Some SMB clients will sometimes NOT faithfully return the resume keys we gave them. The only truly reliable resume mechanism is "resume by name".
Updated by Gordon Ross almost 8 years ago
- Status changed from Pending RTI to Resolved
commit bfbce3c1273efa22c185ea2995c57c37163fd7c3 Author: Gordon Ross <firstname.lastname@example.org> Date: Mon Sep 10 22:06:18 2012 -0400 3223 SMB FindFirst/FindNext don't fill in Last Name Offset Reviewed by: Bayard Bell <email@example.com> Reviewed by: Dan McDonald <firstname.lastname@example.org> Reviewed by: Kevin Crowe <email@example.com> Reviewed by: Yakov Zaytsev <firstname.lastname@example.org> Approved by: Richard Lowe <email@example.com> :100644 100644 52250f6... 1dae4e8... M usr/src/uts/common/fs/smbsrv/smb_find.c :100644 100644 6101267... aff6183... M usr/src/uts/common/fs/smbsrv/smb_odir.c :100644 100644 4eb2ca3... 037b2a3... M usr/src/uts/common/fs/smbsrv/smb_trans2_ :100644 100644 a0c6766... 7c5c9f3... M usr/src/uts/common/smbsrv/smb_kproto.h :100644 100644 580b249... 4ce1967... M usr/src/uts/common/smbsrv/smb_ktypes.h