From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <6f6e9584590fddc728079369c8a098af@quintile.net> From: "Steve Simon" Date: Tue, 5 Feb 2019 17:26:46 +0000 To: 9fans@9fans.net In-Reply-To: <5421E6F7082F34B3BF0A4DEC931F9AA5@felloff.net> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] cifs buglet - take 2 Topicbox-Message-UUID: f4c8504c-ead9-11e9-9d60-3106f5b1d025 > that looks like a bug to me. Yep, In fact it turned out to be rather more subtle than I first though, my bad. sorry for the noise. -Steve diff /n/dump/2019/0205/sys/src/cmd/cifs/main.c /sys/src/cmd/cifs/main.c 216a217,222 > /* remove "." and ".." from the cache */ > static int > rmdots(Aux *a, int got) > { > int i, num; > FInfo *fi; 217a224,237 > 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; > } > 250d269 < fi = (FInfo *)a->cache; 257a277 > got = rmdots(a, got); 260,266d279 < < 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); < } 278a292 > got = rmdots(a, got); 288a303,304 > > from_cache: 292d307 < from_cache: ------------------------------------------------------------------ or as a snippet: /* 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; FInfo *fi; int rc, got; Aux *a = aux; char *npath; int numinf = numinfo(); int slots; slots = 32; /* number of dir entries to fetch at one time */ if(strcmp(a->path, "/") == 0){ if(slot < numinf){ dirgeninfo(slot, d); return 0; } else slot -= numinf; if(slot >= Nshares) return -1; V2D(d, mkqid(Shares[slot].name, 1, 1, Pshare, slot), Shares[slot].name); return 0; } off = slot * sizeof(FInfo); if(off >= a->off && off < a->end && time(nil) < a->expire) goto from_cache; if(off == 0){ npath = smprint("%s/*", mapfile(a->path)); a->sh = T2findfirst(Sess, a->sp, slots, npath, &got, &a->srch, (FInfo *)a->cache); free(npath); if(a->sh == -1) return -1; got = rmdots(a, got); a->off = 0; a->end = got * sizeof(FInfo); goto from_cache; } while(off >= a->end && a->sh != -1){ fi = (FInfo *)(a->cache + (a->end - a->off) - sizeof(FInfo)); a->off = a->end; npath = smprint("%s/%s", mapfile(a->path), fi->name); rc = T2findnext(Sess, a->sp, slots, npath, &got, &a->srch, (FInfo *)a->cache, a->sh); free(npath); if(rc == -1 || got == 0) break; got = rmdots(a, got); a->end = a->off + got * sizeof(FInfo); } a->expire = time(nil) + CACHETIME; if(got < slots){ if(a->sh != -1) CIFSfindclose2(Sess, a->sp, a->sh); a->sh = -1; } from_cache: if(off >= a->end) return -1; fi = (FInfo *)(a->cache + (off - a->off)); npath = smprint("%s/%s", mapfile(a->path), fi->name); I2D(d, a->sp, npath, realmtime(npath), fi); if(Billtrog == 0) upd_names(Sess, a->sp, npath, d); free(npath); return 0; }