⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lump.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "stdinc.h"#include "dat.h"#include "fns.h"int			queueWrites = 0;static Packet		*readILump(Lump *u, IAddr *ia, u8int *score, int rac);Packet*readLump(u8int *score, int type, u32int size){	Lump *u;	Packet *p;	IAddr ia;	u32int n;	int rac;	vtLock(stats.lock);	stats.lumpReads++;	vtUnlock(stats.lock);	u = lookupLump(score, type);	if(u->data != nil){		n = packetSize(u->data);		if(n > size){			setErr(EOk, "read too small: asked for %d need at least %d", size, n);			putLump(u);			return nil;		}		p = packetDup(u->data, 0, n);		putLump(u);		return p;	}	if(!lookupScore(score, type, &ia, &rac)){		//ZZZ place to check for someone trying to guess scores		setErr(EOk, "no block with that score exists");		putLump(u);		return nil;	}	if(ia.size > size){		setErr(EOk, "read too small 1: asked for %d need at least %d", size, ia.size);		putLump(u);		return nil;	}	p = readILump(u, &ia, score, rac);	putLump(u);	return p;}/* * save away a lump, and return it's score. * doesn't store duplicates, but checks that the data is really the same. */intwriteLump(Packet *p, u8int *score, int type, u32int creator){	Lump *u;	int ok;	vtLock(stats.lock);	stats.lumpWrites++;	vtUnlock(stats.lock);	packetSha1(p, score);	u = lookupLump(score, type);	if(u->data != nil){		ok = 1;		if(packetCmp(p, u->data) != 0){			setErr(EStrange, "score collision");			ok = 0;		}		packetFree(p);		putLump(u);		return ok;	}	if(queueWrites)		return queueWrite(u, p, creator);	ok = writeQLump(u, p, creator);	putLump(u);	return ok;}intwriteQLump(Lump *u, Packet *p, int creator){	ZBlock *flat;	Packet *old;	IAddr ia;	int ok;	int rac;	if(lookupScore(u->score, u->type, &ia, &rac)){		/*		 * if the read fails,		 * assume it was corrupted data and store the block again		 */		old = readILump(u, &ia, u->score, rac);		if(old != nil){			ok = 1;			if(packetCmp(p, old) != 0){				setErr(EStrange, "score collision");				ok = 0;			}			packetFree(p);			packetFree(old);			return ok;		}		logErr(EAdmin, "writelump: read %V failed, rewriting: %R\n", u->score);	}	flat = packet2ZBlock(p, packetSize(p));	ok = storeClump(mainIndex, flat, u->score, u->type, creator, &ia);	freeZBlock(flat);	if(ok)		ok = insertScore(u->score, &ia, 1);	if(ok)		insertLump(u, p);	else		packetFree(p);	return ok;}static voidreadAhead(u64int a, Arena *arena, u64int aa, int n){	u8int buf[ClumpSize];	Clump cl;	IAddr ia;	while(n > 0) {		if (aa >= arena->used)			break;		if(readArena(arena, aa, buf, ClumpSize) < ClumpSize)			break;		if(!unpackClump(&cl, buf))			break;		ia.addr = a;		ia.type = cl.info.type;		ia.size = cl.info.uncsize;		ia.blocks = (cl.info.size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog;		insertScore(cl.info.score, &ia, 0);		a += ClumpSize + cl.info.size;		aa += ClumpSize + cl.info.size;		n--;	}}static Packet*readILump(Lump *u, IAddr *ia, u8int *score, int rac){	Arena *arena;	ZBlock *zb;	Packet *p, *pp;	Clump cl;	u64int a, aa;	u8int sc[VtScoreSize];	arena = amapItoA(mainIndex, ia->addr, &aa);	if(arena == nil)		return nil;	zb = loadClump(arena, aa, ia->blocks, &cl, sc, paranoid);	if(zb == nil)		return nil;	if(ia->size != cl.info.uncsize){		setErr(EInconsist, "index and clump size mismatch");		freeZBlock(zb);		return nil;	}	if(ia->type != cl.info.type){		setErr(EInconsist, "index and clump type mismatch");		freeZBlock(zb);		return nil;	}	if(!scoreEq(score, sc)){		setErr(ECrash, "score mismatch");		freeZBlock(zb);		return nil;	}	if(rac == 0) {		a = ia->addr + ClumpSize + cl.info.size;		aa += ClumpSize + cl.info.size;		readAhead(a, arena, aa, 20);	}	p = zblock2Packet(zb, cl.info.uncsize);	freeZBlock(zb);	pp = packetDup(p, 0, packetSize(p));	insertLump(u, pp);	return p;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -