Re: cifs buglet - take 2

"Steve Simon" <[email protected]>
Newsgroups gmane.os.plan9.general
Message-ID <[email protected]>
> 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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.