Ejemplo n.º 1
0
/*
 * Attempt to acquire the lease.
 * Return 1 if succedded, 0 if not , and < 0 on errors.
 */
int
acquire(int fd, off_t offset, char *id, int busyloop, long long *ts)
{
    char curr[taglen+1] = "", last[taglen+1] = "", tag[taglen+1] = "";
    long backoff_usec = (lease_ms + 6 * op_max_ms) * 1000;
    long contend_usec = (2 * op_max_ms) * 1000;
    char dummyid[idlen+1];

    if (readtag(fd, offset, curr, 1) < 0)
        return -errno;

    settag(last, freetag);

    do {
        DEBUG("restart: curr tag is '%s'", curr);
        if (!sametag(curr, last) && !isfree(curr)) do {
            DEBUG("backoff: curr tag is '%s'", curr);
            settag(last, curr);
            usleep(backoff_usec);
            if (readtag(fd, offset, curr, 1) < 0)
                return -errno;
        } while (busyloop && !sametag(curr, last) && !isfree(curr));
        if (!sametag(curr, last) && !isfree(curr)) {
            DEBUG("fail:    curr tag is '%s'", curr);
            return 0;
        }
        DEBUG("contend: curr tag is '%s'", curr);
        if (writetimestamp(fd, offset, id, tag, ts) < 0) {
            DEBUG("lost (writetimestamp failed)  : curr tag is %s", curr);
            return -errno;
        }
        usleep(contend_usec);
        if (readtag(fd, offset, curr, 1) < 0) {
            DEBUG("lost (readtag failed)  : curr tag is %s", curr);
            return -errno;
        }
    } while (busyloop && !sametag(curr, tag));

    if (busyloop || sametag(curr, tag)) {
        DEBUG("won    : curr tag is %s", curr);
        querytag(curr, dummyid, ts);
        return renew(fd, offset, id, ts);
    }
    DEBUG("lost   : curr tag is %s\n         our tag is  %s", curr, tag);
    return 0;
}
Ejemplo n.º 2
0
int
doclri(File *f)
{
	Iobuf *p, *p1;
	Dentry *d, *d1;
	int err;

	err = 0;
	p = 0;
	p1 = 0;
	if(f->fs->dev->type == Devro) {
		err = Eronly;
		goto out;
	}
	/*
	 * check on parent directory of file to be deleted
	 */
	if(f->wpath == 0 || f->wpath->addr == f->addr) {
		err = Ephase;
		goto out;
	}
	p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
	d1 = getdir(p1, f->wpath->slot);
	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
		err = Ephase;
		goto out;
	}

	accessdir(p1, d1, FWRITE, 0);
	putbuf(p1);
	p1 = 0;

	/*
	 * check on file to be deleted
	 */
	p = getbuf(f->fs->dev, f->addr, Brd);
	d = getdir(p, f->slot);

	/*
	 * do it
	 */
	memset(d, 0, sizeof(Dentry));
	settag(p, Tdir, QPNONE);
	freewp(f->wpath);
	freefp(f);

out:
	if(p1)
		putbuf(p1);
	if(p)
		putbuf(p);
	return err;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
void
superream(Device dev, long addr)
{
	Iobuf *p;
	Superb *s;
	long i;

	p = getbuf(dev, addr, Bmod|Bimm);
	memset(p->iobuf, 0, RBUFSIZE);
	settag(p, Tsuper, QPSUPER);

	s = (Superb*)p->iobuf;
	s->fstart = 1;
	s->fsize = devsize(dev);
	s->fbuf.nfree = 1;
	s->qidgen = 10;
	for(i=s->fsize-1; i>=addr+2; i--)
		addfree(dev, i, s);
	putbuf(p);
}
Ejemplo n.º 5
0
void
rootream(Device dev, long addr)
{
	Iobuf *p;
	Dentry *d;

	p = getbuf(dev, addr, Bmod|Bimm);
	memset(p->iobuf, 0, RBUFSIZE);
	settag(p, Tdir, QPROOT);
	d = getdir(p, 0);
	strcpy(d->name, "/");
	d->uid = -1;
	d->gid = -1;
	d->mode = DALLOC | DDIR |
		((DREAD|DWRITE|DEXEC) << 6) |
		((DREAD|DWRITE|DEXEC) << 3) |
		((DREAD|DWRITE|DEXEC) << 0);
	d->qid = QID9P1(QPROOT|QPDIR,0);
	d->atime = time(0);
	d->mtime = d->atime;
	putbuf(p);
}
Ejemplo n.º 6
0
void
fwormream(Device *d)
{
	Iobuf *p;
	Device *fdev;
	Off a, b;

	print("fworm ream\n");
	devinit(d);
	fdev = FDEV(d);
	a = fwormsize(d);
	b = devsize(fdev);
	print("\tfwsize = %lld\n", (Wideoff)a);
	print("\tbwsize = %lld\n", (Wideoff)b-a);
	for(; a < b; a++) {
		p = getbuf(fdev, a, Bmod|Bres);
		if(!p)
			panic("fworm: init");
		memset(p->iobuf, 0, RBUFSIZE);
		settag(p, Tvirgo, a);
		putbuf(p);
	}
}
Ejemplo n.º 7
0
Archivo: sub.c Proyecto: npe9/harvey
void
addfree(Device *dev, Off addr, Superb *sb)
{
	int n;
	Iobuf *p;

	n = sb->fbuf.nfree;
	if(n < 0 || n > FEPERBUF)
		panic("addfree: bad freelist");
	if(n >= FEPERBUF) {
		p = getbuf(dev, addr, Bmod|Bimm);
		if(p == 0)
			panic("addfree: getbuf");
		*(Fbuf*)p->iobuf = sb->fbuf;
		settag(p, Tfree, QPNONE);
		putbuf(p);
		n = 0;
	}
	sb->fbuf.free[n++] = addr;
	sb->fbuf.nfree = n;
	sb->tfree++;
	if(addr >= sb->fsize)
		sb->fsize = addr+1;
}
Ejemplo n.º 8
0
/**
 * anchor_load: load anchor table
 *
 *	@param[in]	path	path name
 */
void
anchor_load(const char *path)
{
	int db, current_fid;

	/* Get fid of the path */
	{
		const char *p = path2fid(path);
		if (p == NULL)
			die("anchor_load: internal error. file '%s' not found in GPATH.", path);
		current_fid = atoi(p);
	}
	FIRST = LAST = 0;
	end = CURRENT = NULL;

	if (vb == NULL)
		vb = varray_open(sizeof(struct anchor), 1000);
	else
		varray_reset(vb);

	for (db = GTAGS; db < GTAGLIM; db++) {
		XARGS *xp;
		char *ctags_xid;

		if ((xp = anchor_input[db]) == NULL)
			continue;
		/*
		 * Read from input stream until it reaches end of file
		 * or the line of another file appears.
		 */
		while ((ctags_xid = xargs_read(xp)) != NULL) {
			SPLIT ptable;
			struct anchor *a;
			int type, fid;
			const char *ctags_x = parse_xid(ctags_xid, NULL, &fid);

			/*
			 * It is the following file.
			 */
			if (current_fid != fid) {
				xargs_unread(xp);
				break;
			}
			if (split(ctags_x, 4, &ptable) < 4) {
				recover(&ptable);
				die("too small number of parts in anchor_load().\n'%s'", ctags_x);
			}
			if (db == GTAGS) {
				char *p = ptable.part[PART_LINE].start;

				for (; *p && isspace((unsigned char)*p); p++)
					;
				if (!*p) {
					recover(&ptable);
					die("The output of parser is illegal.\n%s", ctags_x);
				}
				/*
				 * Function header is applied only to the anchor whoes type is 'D'.
				 * (D: function, M: macro, T: type)
				 */
				type = 'T';
				if (*p == '#')
					type = 'M';
				else if (locatestring(p, "typedef", MATCH_AT_FIRST))
					type = 'T';
				else if ((p = locatestring(p, ptable.part[PART_TAG].start, MATCH_FIRST)) != NULL) {
					/* skip a tag and the following blanks */
					p += strlen(ptable.part[PART_TAG].start);
					for (; *p && isspace((unsigned char)*p); p++)
						;
					if (*p == '(')
						type = 'D';
				}
			}  else if (db == GRTAGS)
				type = 'R';
			else
				type = 'Y';
			/* allocate an entry */
			a = varray_append(vb);
			a->lineno = atoi(ptable.part[PART_LNO].start);
			a->type = type;
			a->done = 0;
			settag(a, ptable.part[PART_TAG].start);
			recover(&ptable);
		}
		if (ctags_xid == NULL) {
			xargs_close(anchor_input[db]);
			anchor_input[db] = NULL;
		}
	}
	if (vb->length == 0) {
		table = NULL;
	} else {
		int i, used = vb->length;
		/*
		 * Sort by lineno.
		 */
		table = varray_assign(vb, 0, 0);
		qsort(table, used, sizeof(struct anchor), cmp); 
		/*
		 * Setup some lineno.
		 */
		for (i = 0; i < used; i++)
			if (table[i].type == 'D')
				break;
		if (i < used)
			FIRST = table[i].lineno;
		for (i = used - 1; i >= 0; i--)
			if (table[i].type == 'D')
				break;
		if (i >= 0)
			LAST = table[i].lineno;
	}
	/*
	 * Setup loop range.
	 */
	start = table;
	curp = NULL;
	end = &table[vb->length];
	/* anchor_dump(stderr, 0);*/
}
Ejemplo n.º 9
0
void
sysinit(void)
{
	int error;
	char *cp, *ep;
	Device *d;
	Filsys *fs;
	Fspar *fsp;
	Iobuf *p;

	cons.chan = fs_chaninit(Devcon, 1, 0);

start:
	/*
	 * part 1 -- read the config file
	 */
	devnone = iconfig("n");

	cp = nvrgetconfig();
	print("config %s\n", cp);

	confdev = d = iconfig(cp);
	devinit(d);
	if(f.newconf) {
		p = getbuf(d, 0, Bmod);
		memset(p->iobuf, 0, RBUFSIZE);
		settag(p, Tconfig, 0);
	} else
		p = getbuf(d, 0, Brd|Bmod);
	if(!p || checktag(p, Tconfig, 0))
		panic("config io");

	mergeconf(p);

	if (resetparams) {
		for (fsp = fspar; fsp->name != nil; fsp++)
			fsp->declared = 0;
		resetparams = 0;
	}

	for (fsp = fspar; fsp->name != nil; fsp++) {
		/* supply defaults from this cwfs instance */
		if (fsp->declared == 0) {
			fsp->declared = fsp->actual;
			f.modconf = 1;
		}
		/* warn if declared value is not our compiled-in value */
		if (fsp->declared != fsp->actual)
			print("warning: config %s %ld != compiled-in %ld\n",
				fsp->name, fsp->declared, fsp->actual);
	}

	if(f.modconf) {
		memset(p->iobuf, 0, BUFSIZE);
		p->flags |= Bmod|Bimm;
		cp = p->iobuf;
		ep = p->iobuf + RBUFSIZE - 1;
		if(service[0])
			cp = seprint(cp, ep, "service %s\n", service);
		for(fs=filsys; fs->name; fs++)
			if(fs->conf && fs->conf[0] != '\0')
				cp = seprint(cp, ep, "filsys %s %s\n", fs->name,
					fs->conf);

		for (fsp = fspar; fsp->name != nil; fsp++)
			cp = seprint(cp, ep, "%s %ld\n",
				fsp->name, fsp->declared);

		putbuf(p);
		f.modconf = f.newconf = 0;
		print("config block written\n");
		goto start;
	}
	putbuf(p);

	print("service    %s\n", service);

loop:
	/*
	 * part 2 -- squeeze out the deleted filesystems
	 */
	for(fs=filsys; fs->name; fs++)
		if(fs->conf == nil || fs->conf[0] == '\0') {
			for(; fs->name; fs++)
				*fs = *(fs+1);
			goto loop;
		}
	if(filsys[0].name == nil)
		panic("no filsys");

	/*
	 * part 3 -- compile the device expression
	 */
	error = 0;
	for(fs=filsys; fs->name; fs++) {
		print("filsys %s %s\n", fs->name, fs->conf);
		fs->dev = iconfig(fs->conf);
		if(f.error) {
			error = 1;
			continue;
		}
	}
	if(error)
		panic("fs config");

	/*
	 * part 4 -- initialize the devices
	 */
	for(fs=filsys; fs->name; fs++) {
		delay(3000);
		print("sysinit: %s\n", fs->name);
		if(fs->flags & FREAM)
			devream(fs->dev, 1);
		if(fs->flags & FRECOVER)
			devrecover(fs->dev);
		devinit(fs->dev);
	}

	/*
	 * part 5 -- optionally copy devices or worms
	 */
	if (copyworm) {
		dowormcopy();		/* can return if user quits early */
		panic("copyworm bailed out!");
	}
	if (copydev)
		if (dodevcopy() < 0)
			panic("copydev failed!");
		else
			panic("copydev done.");
}
Ejemplo n.º 10
0
Archivo: sub.c Proyecto: 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;
}
Ejemplo n.º 11
0
int
doremove(File *f, int iscon)
{
	Iobuf *p, *p1;
	Dentry *d, *d1;
	int32_t addr;
	int slot, err;

	p = 0;
	p1 = 0;
	if(isro(f->fs->dev) || (f->cp != cons.chan && writegroup && !ingroup(f->uid, writegroup))) {
		err = Eronly;
		goto out;
	}
	/*
	 * check on parent directory of file to be deleted
	 */
	if(f->wpath == 0 || f->wpath->addr == f->addr) {
		err = Ephase;
		goto out;
	}
	p1 = getbuf(f->fs->dev, f->wpath->addr, Bread);
	d1 = getdir(p1, f->wpath->slot);
	if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
		err = Ephase;
		goto out;
	}
	if(!iscon && iaccess(f, d1, DWRITE)) {
		err = Eaccess;
		goto out;
	}
	accessdir(p1, d1, FWRITE);
	putbuf(p1);
	p1 = 0;

	/*
	 * check on file to be deleted
	 */
	p = getbuf(f->fs->dev, f->addr, Bread);
	d = getdir(p, f->slot);
	if(!d || checktag(p, Tdir, QPNONE) || !(d->mode & DALLOC)) {
		err = Ealloc;
		goto out;
	}
	if(err = mkqidcmp(&f->qid, d))
		goto out;

	/*
	 * if deleting a directory, make sure it is empty
	 */
	if((d->mode & DDIR))
	for(addr=0;; addr++) {
		p1 = dnodebuf(p, d, addr, 0);
		if(!p1)
			break;
		if(checktag(p1, Tdir, d->qid.path)) {
			err = Ephase;
			goto out;
		}
		for(slot=0; slot<DIRPERBUF; slot++) {
			d1 = getdir(p1, slot);
			if(!(d1->mode & DALLOC))
				continue;
			err = Eempty;
			goto out;
		}
		putbuf(p1);
	}

	/*
	 * do it
	 */
	dtrunc(p, d);
	memset(d, 0, sizeof(Dentry));
	settag(p, Tdir, QPNONE);

out:
	if(p1)
		putbuf(p1);
	if(p)
		putbuf(p);
	return err;
}
Ejemplo n.º 12
0
Archivo: chk.c Proyecto: 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);
}