ref: 6604cc2c1e49c6267c084e3d33d5fc154c90ca19
parent: 53384104eaf69e95a3e15699bd1082d98e75f25c
	author: cinap_lenrek <cinap_lenrek@felloff.net>
	date: Tue Feb  5 15:53:40 EST 2019
	
cifs: fix pruning of . and .. directory entries (thanks steve simon) steve wrote: > I cam across a bug in cifs. > > An empty directory under windows 7 pro contains a single entry "." but it > doesn't appear to contain "..". As a result "." is not removed on dirscan > and plan9 gets when trying to traverse the hierarchy.
--- a/sys/src/cmd/cifs/main.c
+++ b/sys/src/cmd/cifs/main.c
@@ -189,7 +189,28 @@
 	return smprint("%s/%s", path, name);}
+/* remove "." and ".." from the cache */
static int
+rmdots(Aux *a, int got)
+{+ int i, num;
+ FInfo *fi;
+
+ num = 0;
+ fi = (FInfo *)a->cache;
+	for(i = 0; i < got; i++){+		if(strcmp(fi->name, ".") == 0 || strcmp(fi->name, "..") == 0){+ memmove(fi, fi+1, got * sizeof(FInfo));
+ continue;
+ }
+ fi++;
+ num++;
+ }
+
+ return num;
+}
+
+static int
dirgen(int slot, Dir *d, void *aux)
 {long off;
@@ -200,7 +221,7 @@
int numinf = numinfo();
int slots;
- slots = 128; /* number of dir entries to fetch at one time */
+ slots = 32; /* number of dir entries to fetch at one time */
 	if(strcmp(a->path, "/") == 0){ 		if(slot < numinf){@@ -221,7 +242,6 @@
goto from_cache;
 	if(off == 0){- fi = (FInfo *)a->cache;
 		npath = smprint("%s/*", mapfile(a->path));a->sh = T2findfirst(Sess, a->sp, slots, npath, &got, &a->srch,
(FInfo *)a->cache);
@@ -229,15 +249,10 @@
if(a->sh == -1)
return -1;
+ got = rmdots(a, got);
a->off = 0;
a->end = got * sizeof(FInfo);
-
- if(got >= 2 && strcmp(fi[0].name, ".") == 0 &&
-		    strcmp(fi[1].name, "..") == 0){- a->end = (got - 2) * sizeof(FInfo);
- memmove(a->cache, a->cache + sizeof(FInfo)*2,
- a->end - a->off);
- }
+ goto from_cache;
}
 	while(off >= a->end && a->sh != -1){@@ -249,6 +264,7 @@
free(npath);
if(rc == -1 || got == 0)
break;
+ got = rmdots(a, got);
a->end = a->off + got * sizeof(FInfo);
}
a->expire = time(nil) + CACHETIME;
@@ -259,10 +275,11 @@
a->sh = -1;
}
+
+from_cache:
if(off >= a->end)
return -1;
-from_cache:
fi = (FInfo *)(a->cache + (off - a->off));
 	npath = smprint("%s/%s", mapfile(a->path), fi->name);I2D(d, a->sp, npath, fi);
--
⑨