[Samba] RE: [PATCH] smbfs readdir fix (CFT: NetApp, OS/2)

Urban Widmark urban at teststation.com
Wed Jun 26 01:28:02 GMT 2002


On Tue, 25 Jun 2002, Gene Yee wrote:

> 
> Can someone share the smbfs-2.4.19-pre9-readdir.patch.

You can try it, but the symptoms you see are different from the ones seen 
by others where it just silently drops files.

/Urban
-------------- next part --------------
diff -urN -X exclude linux-2.4.19-pre9-orig/fs/smbfs/proc.c linux-2.4.19-pre9-smbfs/fs/smbfs/proc.c
--- linux-2.4.19-pre9-orig/fs/smbfs/proc.c	Thu May 30 23:33:45 2002
+++ linux-2.4.19-pre9-smbfs/fs/smbfs/proc.c	Sun Jun 23 00:49:53 2002
@@ -1865,10 +1865,8 @@
  * go there for advise.
  *
  * Bugs Noted:
- * (1) When using Info Level 1 Win NT 4.0 truncates directory listings 
- * for certain patterns of names and/or lengths. The breakage pattern
- * is completely reproducible and can be toggled by the creation of a
- * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
+ * (1) When using the continue bit NT4 and Windows 2000 sometimes skips a file
+ * in the FIND_NEXT reply.
  */
 static int
 smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
@@ -1952,7 +1950,7 @@
 			WSET(param, 2, max_matches);	/* max count */
 			WSET(param, 4, info_level);
 			DSET(param, 6, 0);
-			WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
+			WSET(param, 10, SMB_CLOSE_IF_END);
 		}
 
 		result = smb_trans2_request(server, command,
@@ -2009,38 +2007,41 @@
 		 * here that those who do not point to a filename do not need
 		 * this info to continue the listing.
 		 *
-		 * OS/2 needs this and talks infolevel 1
-		 * NetApps want lastname with infolevel 260
+		 * NT4/win2k sometimes drops files without the filename.
 		 *
-		 * Both are happy if we return the data they point to. So we do.
+		 * OS/2 needs this and talks infolevel 1 (*)
+		 * NetApps want lastname with infolevel 260 (*)
+		 *
+		 * (* = probably broken by this change)
 		 */
 		mask_len = 0;
-		if (ff_lastname > 0 && ff_lastname < resp_data_len) {
-			lastname = resp_data + ff_lastname;
-
-			switch (info_level) {
-			case 260:
-				mask_len = resp_data_len - ff_lastname;
-				break;
-			case 1:
-				/* lastname points to a length byte */
-				mask_len = *lastname++;
-				if (ff_lastname + 1 + mask_len > resp_data_len)
-					mask_len = resp_data_len - ff_lastname - 1;
-				break;
-			}
-
-			/*
-			 * Update the mask string for the next message.
-			 */
-			if (mask_len < 0)
-				mask_len = 0;
+		lastname = resp_data + ff_lastname;
+		if (ff_lastname <= 0 || ff_lastname > resp_data_len) {
+			PARANOIA("lastname points beyond buffer (%d > %d)\n",
+				 ff_lastname, resp_data_len);
+		} else if (info_level == 1) {
+			/* lastname points to a length byte */
+			mask_len = *lastname++;
+			if (ff_lastname + 1 + mask_len > resp_data_len)
+				mask_len = resp_data_len - ff_lastname - 1;
 			if (mask_len > 255)
 				mask_len = 255;
 			if (mask_len)
 				strncpy(mask, lastname, mask_len);
+			mask_len = strnlen(mask, mask_len);
+		} else if (info_level == 260) {
+			/* lastname points to a dirent */
+			/* FIXME: max name length? buffer sizes? */
+			/* FIXME: NT4/win2k wants this, what about NetApp? */
+			/* FIXME: unicode patch needs to not strip the 0 */
+			mask_len = DVAL(lastname, 60);
+			p = lastname + 94;
+			if (mask_len && p[mask_len-1] == '\0')
+				mask_len--;
+
+			memcpy(mask, p, mask_len);
+			mask[mask_len] = '\0';
 		}
-		mask_len = strnlen(mask, mask_len);
 		VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
 			mask_len, ff_lastname, resp_data_len, mask_len, mask);
 


More information about the samba mailing list