smbfs patch - listing large direcories from an OS/2 server

christoph.pfisterer at rwg.de christoph.pfisterer at rwg.de
Mon Mar 20 13:40:23 GMT 2000


Hi!

Here's a patch that allows Linux smbfs to list large directories (i.e. > 100
items) when talking to an OS/2 server. There is a misunderstanding about the
flags sent in the FINDFIRST request which causes the OS/2 server to indicate an
EOS (end of search) in the FINDFIRST response, even when there are more items
to be listed. The result is that smbfs will display only the first ~120 items
in a directory (varies with file name length and buffer size) without getting
an error message. The patch below fixes that. I also had to add some
ff_lastname/mask code back in; OS/2 Server needs it to continue the search.

The patch is against Linux 2.2.14:

Index: fs/smbfs/proc.c
===================================================================
RCS file: /usr/src/cvsroot/linux/fs/smbfs/proc.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 proc.c
--- fs/smbfs/proc.c     2000/03/16 07:13:52     1.1.1.3
+++ fs/smbfs/proc.c     2000/03/20 12:52:08
@@ -12,6 +12,9 @@
  *           - don't sleep every time with win95 on a FINDNEXT
  *           - fixed loop_count bug
  *           - got rid of resume_key
+ *  20/03/00 (chrisp)
+ *           - fixed FINDFIRST flags for OS/2 Server
+ *           - added lastname/mask stuff back (OS/2 needs it)
  */

 #include <linux/types.h>
@@ -1550,6 +1553,7 @@
        int resp_param_len = 0;
        int ff_searchcount = 0;
        int ff_eos = 0;
+       int ff_lastname = 0;
        int ff_dir_handle = 0;
        int loop_count = 0;
        int mask_len, i, result;
@@ -1597,16 +1601,11 @@
                        command = TRANSACT2_FINDFIRST;
                        WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
                        WSET(param, 2, max_matches);    /* max count */
-                       WSET(param, 4,
-                            SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
+                       WSET(param, 4, SMB_CLOSE_IF_END);
                        WSET(param, 6, info_level);
                        DSET(param, 8, 0);
                } else
                {
-                       /* we don't need the mask after the first bit */
-                       mask_len = 0;
-                       mask[0] = 0;
-
                        command = TRANSACT2_FINDNEXT;
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_readdir_long: handle=0x%X, mask=%s\n",
@@ -1666,15 +1665,29 @@
                        ff_dir_handle = WVAL(resp_param, 0);
                        ff_searchcount = WVAL(resp_param, 2);
                        ff_eos = WVAL(resp_param, 4);
+                       ff_lastname = WVAL(resp_param, 8);
                } else
                {
                        ff_searchcount = WVAL(resp_param, 0);
                        ff_eos = WVAL(resp_param, 2);
+                       ff_lastname = WVAL(resp_param, 6);
                }

                if (ff_searchcount == 0)
                {
                        break;
+               }
+
+               if (ff_lastname > 0 && info_level == 1)
+               {
+                       mask_len = *(resp_data + ff_lastname);
+                       memcpy(mask, resp_data + ff_lastname + 1,
+                              mask_len);
+                       mask[mask_len] = 0;
+               } else
+               {
+                       mask_len = 0;
+                       mask[0] = 0;
                }

                /* Now we are ready to parse smb directory entries. */

The same bug exists in the Samba 2.0.6 client library; I submitted a patch to
samba-patches at samba.org. The Linux 2.3 tree has the same problem; if someone
wants a patch, let me know.

Hope this helps,
Christoph Pfisterer


More information about the samba mailing list