예제 #1
0
파일: con.c 프로젝트: dancrossnyc/harvey
void
cmd_start(void)
{
	superok(cur_fs->dev, superaddr(cur_fs->dev), 0);
	wunlock(&mainlock);
	print("kfs: file system started\n");
}
예제 #2
0
파일: con.c 프로젝트: dancrossnyc/harvey
void
cmd_halt(void)
{
	wlock(&mainlock);
	syncall();
	superok(cur_fs->dev, superaddr(cur_fs->dev), 1);
	print("kfs: file system halted\n");
}
예제 #3
0
파일: sub.c 프로젝트: npe9/harvey
/*
 * free the block at `addr' on dev.
 * if it's an indirect block (d [depth] > 0),
 * first recursively free all the blocks it names.
 *
 * ts->relblk is the block number within the file of this
 * block (or the first data block eventually pointed to via
 * this indirect block).
 */
void
buffree(Device *dev, Off addr, int d, Truncstate *ts)
{
	Iobuf *p;
	Off a;
	int i, pastlast;

	if(!addr)
		return;
	pastlast = (ts == nil? 1: ts->pastlast);
	/*
	 * if this is an indirect block, recurse and free any
	 * suitable blocks within it (possibly via further indirect blocks).
	 */
	if(d > 0) {
		d--;
		p = getbuf(dev, addr, Brd);
		if(p) {
			if (ts == nil)		/* common case: create */
				for(i=INDPERBUF-1; i>=0; i--) {
					a = ((Off *)p->iobuf)[i];
					buffree(dev, a, d, nil);
				}
			else			/* wstat truncation */
				for (i = 0; i < INDPERBUF; i++)
					truncfree(ts, dev, d, p, i);
			putbuf(p);
		}
	}
	if (!pastlast)
		return;
	/*
	 * having zeroed the pointer to this block, add it to the free list.
	 * stop outstanding i/o
	 */
	p = getbuf(dev, addr, Bprobe);
	if(p) {
		p->flags &= ~(Bmod|Bimm);
		putbuf(p);
	}
	/*
	 * dont put written worm
	 * blocks into free list
	 */
	if(dev->type == Devcw) {
		i = cwfree(dev, addr);
		if(i)
			return;
	}
	p = getbuf(dev, superaddr(dev), Brd|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("buffree: super block");
	addfree(dev, addr, (Superb*)p->iobuf);
	putbuf(p);
}
예제 #4
0
파일: sub.c 프로젝트: carriercomm/plan9-gpl
long
qidpathgen(Device *dev)
{
	Iobuf *p;
	Superb *sb;
	long path;

	p = getbuf(*dev, superaddr((*dev)), Bread|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("newqid: super block");
	sb = (Superb*)p->iobuf;
	sb->qidgen++;
	path = sb->qidgen;
	putbuf(p);
	return path;
}
예제 #5
0
파일: sub.c 프로젝트: carriercomm/plan9-gpl
long
balloc(Device dev, int tag, long qid)
{
	Iobuf *bp, *p;
	Superb *sb;
	long a;
	int n;

	p = getbuf(dev, superaddr(dev), Bread|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("balloc: super block");
	sb = (Superb*)p->iobuf;

loop:
	n = --sb->fbuf.nfree;
	sb->tfree--;
	if(n < 0 || n >= FEPERBUF)
		panic("balloc: bad freelist");
	a = sb->fbuf.free[n];
	if(n <= 0) {
		if(a == 0) {
			sb->tfree = 0;
			sb->fbuf.nfree = 1;
			if(devgrow(dev, sb))
				goto loop;
			putbuf(p);
			return 0;
		}
		bp = getbuf(dev, a, Bread);
		if(!bp || checktag(bp, Tfree, QPNONE)) {
			if(bp)
				putbuf(bp);
			putbuf(p);
			return 0;
		}
		memmove(&sb->fbuf, bp->iobuf, (FEPERBUF+1)*sizeof(long));
		putbuf(bp);
	}
	bp = getbuf(dev, a, Bmod);
	memset(bp->iobuf, 0, RBUFSIZE);
	settag(bp, tag, qid);
	if(tag == Tind1 || tag == Tind2 || tag == Tdir)
		bp->flags |= Bimm;
	putbuf(bp);
	putbuf(p);
	return a;
}
예제 #6
0
파일: sub.c 프로젝트: carriercomm/plan9-gpl
Qid
newqid(Device dev)
{
	Iobuf *p;
	Superb *sb;
	Qid qid;

	p = getbuf(dev, superaddr(dev), Bread|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("newqid: super block");
	sb = (Superb*)p->iobuf;
	sb->qidgen++;
	qid.path = sb->qidgen;
	qid.vers = 0;
	qid.type = 0;
	putbuf(p);
	return qid;
}
예제 #7
0
파일: sub.c 프로젝트: carriercomm/plan9-gpl
void
bfree(Device dev, long addr, int d)
{
	Iobuf *p;
	long a;
	int i;

	if(!addr)
		return;
	if(d > 0) {
		d--;
		p = getbuf(dev, addr, Bread);
		if(p) {
			for(i=INDPERBUF-1; i>=0; i--) {
				a = ((long*)p->iobuf)[i];
				bfree(dev, a, d);
			}
			putbuf(p);
		}
	}
	/*
	 * stop outstanding i/o
	 */
	p = getbuf(dev, addr, Bprobe);
	if(p) {
		p->flags &= ~(Bmod|Bimm);
		putbuf(p);
	}
	/*
	 * dont put written worm
	 * blocks into free list
	 */
	if(nofree(dev, addr))
		return;
	p = getbuf(dev, superaddr(dev), Bread|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER))
		panic("bfree: super block");
	addfree(dev, addr, (Superb*)p->iobuf);
	putbuf(p);
}
예제 #8
0
파일: main.c 프로젝트: dancrossnyc/harvey
void
main(int argc, char *argv[])
{
	Filsys *fs;
	int ream, fsok;
	int newbufsize, nocheck;
	char buf[NAMELEN];
	int pid, ctl;

	progname = "kfs";
	procname = "init";

	/*
	 * insulate from invoker's environment and keep it from swapping
	 */
	rfork(RFNAMEG|RFNOTEG|RFREND);

	confinit();
	sfd = -1;
	ream = 0;
	newbufsize = 0;
	nocheck = 0;
	wrenfile = "/dev/sdC0/fs";

	pid = getpid();
	snprint(buf, sizeof buf, "/proc/%d/ctl", pid);
	ctl = open(buf, OWRITE);
	fprint(ctl, "noswap\n");
	close(ctl);

	buf[0] = '\0';

	ARGBEGIN{
	case 'b':
		newbufsize = atol(ARGF());
		break;
	case 'c':
		nocheck = 1;
		break;
	case 'f':
		wrenfile = ARGF();
		break;
	case 'm':
		nwren = atol(ARGF());
		break;
	case 'n':
		strncpy(buf, ARGF(), NAMELEN-1);
		buf[NAMELEN-1] = '\0';
		break;
	case 'p':
		cmdmode = atol(ARGF());
		break;
	case 'r':
		ream = 1;
		break;
	case 's':
		sfd = 0;
		rfd = dup(1, -1);
		close(1);
		if(open("/dev/cons", OWRITE) < 0)
			open("#c/cons", OWRITE);
		break;
	case 'B':
		conf.niobuf = strtoul(ARGF(), 0, 0);
		break;
	case 'C':
		chat = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 0)
		usage();

	cmdfd = 2;

	if (access(wrenfile, AREAD|AWRITE) == -1)
		sysfatal("%s cannot access device", wrenfile);

	formatinit();
	sublockinit();

	if(buf[0])
		sprint(service, "kfs.%s", buf);
	else
		strcpy(service, "kfs");
	chan = chaninit(service);
	consinit();
	tlocks = ialloc(NTLOCK * sizeof *tlocks);
	uid = ialloc(conf.nuid * sizeof(*uid));
	uidspace = ialloc(conf.uidspace * sizeof(*uidspace));
	gidspace = ialloc(conf.gidspace * sizeof(*gidspace));

	/*
	 * init global locks
	 */
	wlock(&mainlock); wunlock(&mainlock);

	/*
	 * init the file system, ream it if needed, and get the block sizes
	 */
	ream = fsinit(ream, newbufsize);
	iobufinit();
	for(fs=filesys; fs->name; fs++)
		if(fs->flags & FREAM){		/* set by fsinit if reamed */
			ream++;
			rootream(fs->dev, getraddr(fs->dev));
			superream(fs->dev, superaddr(fs->dev));
		}

	boottime = time(nil);

	consserve();
	fsok = superok(filesys[0].dev, superaddr(filesys[0].dev), 0);
	if(!nocheck && !ream && !fsok)
		cmd_exec("check fq");

	startproc(forkserve, "srv");
	startproc(syncproc, "sync");

	exits(0);
}
예제 #9
0
파일: sub.c 프로젝트: npe9/harvey
Off
bufalloc(Device *dev, int tag, int32_t qid, int uid)
{
	Iobuf *bp, *p;
	Superb *sb;
	Off a, n;

	p = getbuf(dev, superaddr(dev), Brd|Bmod);
	if(!p || checktag(p, Tsuper, QPSUPER)) {
		print("bufalloc: super block\n");
		if(p)
			putbuf(p);
		return 0;
	}
	sb = (Superb*)p->iobuf;

loop:
	n = --sb->fbuf.nfree;
	sb->tfree--;
	if(n < 0 || n >= FEPERBUF) {
		print("bufalloc: %Z: bad freelist\n", dev);
		n = 0;
		sb->fbuf.free[0] = 0;
	}
	a = sb->fbuf.free[n];
	if(n <= 0) {
		if(a == 0) {
			sb->tfree = 0;
			sb->fbuf.nfree = 1;
			if(dev->type == Devcw) {
				n = uid;
				if(n < 0 || n >= nelem(growacct))
					n = 0;
				growacct[n]++;
				if(cwgrow(dev, sb, uid))
					goto loop;
			}
			putbuf(p);
			print("fs %Z full uid=%d\n", dev, uid);
			return 0;
		}
		bp = getbuf(dev, a, Brd);
		if(!bp || checktag(bp, Tfree, QPNONE)) {
			if(bp)
				putbuf(bp);
			putbuf(p);
			return 0;
		}
		sb->fbuf = *(Fbuf*)bp->iobuf;
		putbuf(bp);
	}

	bp = getbuf(dev, a, Bmod);
	memset(bp->iobuf, 0, RBUFSIZE);
	settag(bp, tag, qid);
	if(tag == Tind1 || tag == Tind2 ||
#ifndef COMPAT32
	    tag == Tind3 || tag == Tind4 ||  /* add more Tind tags here ... */
#endif
	    tag == Tdir)
		bp->flags |= Bimm;
	putbuf(bp);
	putbuf(p);
	return a;
}
예제 #10
0
파일: chk.c 프로젝트: 99years/plan9
void
check(Filsys *fs, long flag)
{
	Iobuf *p;
	Superb *sb;
	Dentry *d;
	long raddr;
	long nqid;

	wlock(&mainlock);
	dev = fs->dev;
	flags = flag;
	fence = fencebase;

	sizname = 4000;
	name = zalloc(sizname);
	sizname -= NAMELEN+10;	/* for safety */

	sbaddr = superaddr(dev);
	raddr = getraddr(dev);
	p = xtag(sbaddr, Tsuper, QPSUPER);
	if(!p){
		cprint("bad superblock\n");
		goto out;
	}
	sb = (Superb*)p->iobuf;
	fstart = 1;

	fsize = sb->fsize;
	sizabits = (fsize-fstart + 7)/8;
	abits = zalloc(sizabits);

	nqid = sb->qidgen+100;		/* not as much of a botch */
	if(nqid > 1024*1024*8)
		nqid = 1024*1024*8;
	if(nqid < 64*1024)
		nqid = 64*1024;

	sizqbits = (nqid+7)/8;
	qbits = zalloc(sizqbits);

	mod = 0;
	nfree = 0;
	nfdup = 0;
	nused = 0;
	nbad = 0;
	ndup = 0;
	nqbad = 0;
	depth = 0;
	maxdepth = 0;

	if(flags & Ctouch) {
		oldblock = fsize/DSIZE;
		oldblock *= DSIZE;
		if(oldblock < 0)
			oldblock = 0;
		cprint("oldblock = %ld\n", oldblock);
	}
	if(amark(sbaddr))
		{}
	if(cwflag) {
		if(amark(sb->roraddr))
			{}
		if(amark(sb->next))
			{}
	}

	if(!(flags & Cquiet))
		cprint("checking file system: %s\n", fs->name);
	nfiles = 0;
	maxq = 0;

	d = maked(raddr, 0, QPROOT);
	if(d) {
		if(amark(raddr))
			{}
		if(fsck(d))
			modd(raddr, 0, d);
		depth--;
		fence -= sizeof(Dentry);
		if(depth)
			cprint("depth not zero on return\n");
	}

	if(flags & Cfree) {
		mkfreelist(sb);
		sb->qidgen = maxq;
		settag(p, Tsuper, QPNONE);
	}

	if(sb->qidgen < maxq)
		cprint("qid generator low path=%ld maxq=%ld\n",
			sb->qidgen, maxq);
	if(!(flags & Cfree))
		ckfreelist(sb);
	if(mod) {
		cprint("file system was modified\n");
		settag(p, Tsuper, QPNONE);
	}

	if(!(flags & Cquiet)){
		cprint("%8ld files\n", nfiles);
		cprint("%8ld blocks in the file system\n", fsize-fstart);
		cprint("%8ld used blocks\n", nused);
		cprint("%8ld free blocks\n", sb->tfree);
	}
	if(!(flags & Cfree)){
		if(nfree != sb->tfree)
			cprint("%8ld free blocks found\n", nfree);
		if(nfdup)
			cprint("%8ld blocks duplicated in the free list\n", nfdup);
		if(fsize-fstart-nused-nfree)
			cprint("%8ld missing blocks\n", fsize-fstart-nused-nfree);
	}
	if(ndup)
		cprint("%8ld address duplications\n", ndup);
	if(nbad)
		cprint("%8ld bad block addresses\n", nbad);
	if(nqbad)
		cprint("%8ld bad qids\n", nqbad);
	if(!(flags & Cquiet))
		cprint("%8ld maximum qid path\n", maxq);
	missing();

out:
	if(p)
		putbuf(p);
	free(abits);
	free(name);
	free(qbits);
	wunlock(&mainlock);
}