Plan 9 from Bell Labs’s /usr/web/sources/contrib/blstuart/θfs/super.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * Copyright (c) 2013, Coraid, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Coraid nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL CORAID BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <u.h>
#include <libc.h>
#include <thread.h>
#include <fcall.h>
#include <9p.h>
#include "dat.h"

enum {
	Nht = 67108859,
};

static ulong primes[] = {1048573, 2097143, 4194301, 8388593,
	16777213, 33554393, 67108859, 134217689, 268435399};

static Lock slock;

Super super;

void
loadsuper(void)
{
	Super *sp;

	lock(&slock);
	sp = cbread(0);
	if(sp->magic != Magicθ)
		sysfatal("Bad super magic");
	memmove(&super, sp, sizeof(Super));
	brelease(0);
	if(super.nht == 0) {
		super.nht = Nht;
		super.nhashblk = (super.nht + NPerBlk - 1) / NPerBlk;
	}
	if(super.snaptime == 0)
		super.snaptime = (3 * 60 + 15) * 60;
	initfree();
	unlock(&slock);
}

static char supbuf[1024];

char *
prsuper(void)
{
	char *p, *e;

	p = supbuf;
	e = p + nelem(supbuf);
	p = seprint(p, e, "Superblock:\n");
	p = seprint(p, e, "magic: %ulld(0x%ullx)\n", super.magic, super.magic);
	p = seprint(p, e, "qgen: %ulld(0x%ullx)\n", super.qgen, super.qgen);
	p = seprint(p, e, "nblk: %ulld(0x%ullx)\n", super.nblk, super.nblk);
	p = seprint(p, e, "nfreemap: %ulld(0x%ullx)\n", super.nfreemap, super.nfreemap);
	p = seprint(p, e, "freemap: %ulld(0x%ullx)\n", super.freemap, super.freemap);
	p = seprint(p, e, "stat: %ulld(0x%ullx)\n", super.state, super.state);
	p = seprint(p, e, "firstdat: %ulld(0x%ullx)\n", super.firstdat, super.firstdat);
	p = seprint(p, e, "nfree: %ulld(0x%ullx)\n", super.nfree, super.nfree);
	p = seprint(p, e, "firstlun: %ulld(0x%ullx)\n", super.firstlun, super.firstlun);
	p = seprint(p, e, "nmeta: %ulld(0x%ullx)\n", super.nmeta, super.nmeta);
	p = seprint(p, e, "firstmeta: %ulld(0x%ullx)\n", super.firstmeta, super.firstmeta);
	p = seprint(p, e, "ffmeta: %ulld(0x%ullx)\n", super.ffmeta, super.ffmeta);
	p = seprint(p, e, "nblob: %ulld(0x%ullx)\n", super.nblob, super.nblob);
	p = seprint(p, e, "firstblob: %ulld(0x%ullx)\n", super.firstblob, super.firstblob);
	p = seprint(p, e, "ffblob: %ulld(0x%ullx)\n", super.ffblob, super.ffblob);
	p = seprint(p, e, "lfblob: %ulld(0x%ullx)\n", super.lfblob, super.lfblob);
	p = seprint(p, e, "nht: %ulld(0x%ullx)\n", super.nht, super.nht);
	seprint(p, e, "nhashblk: %ulld(0x%ullx)\n", super.nhashblk, super.nhashblk);
	return supbuf;
}

void
savesuper(void)
{
	char *p;

	lock(&slock);
	p = cbread(0);
	memset(p, 0, BlkSize);
	memmove(p, &super, sizeof(Super));
	cbwrite(0);
	brelease(0);
	unlock(&slock);
}

void
ream(char *dev)
{
	Qid rootqid;
	char *me;
	uchar *bigbuf;
	uvlong meta, firstnon, lastnon, i;
	vlong bperb;
	vlong now;
	int j, k, sfd;
int ndot = 0;

fprint(2, "reaming %s\n", dev);
	sfd = open(dev, ORDWR);
	if(sfd < 0)
		sysfatal("Couldn't open device for write: %r");
	/*
	 * Init superblock
	 */
	super.magic = Magicθ;
	super.version = 1;
	super.qgen = 1 | ((uvlong)TFile << 60);
	i = devsize(dev);
	if(i == ~0ULL)
		sysfatal("couldn't get device size:%r\n");
	super.nblk = i / BlkSize;
	for(i = 0; i < nelem(primes) - 1 && super.nblk > primes[i]; ++i) ;
	super.nht = primes[i];
	super.nhashblk = (super.nht + NPerBlk - 1) / NPerBlk;
	bperb = 8 * BlkSize;
	super.nfreemap = (super.nblk + bperb - 1) / bperb;
	super.freemap = 2 * super.nhashblk + 1;
	super.nmeta = super.nblk / 200;
	super.firstmeta = super.freemap + super.nfreemap;
	super.ffmeta = 1;
	super.nblob = super.nblk / 200;
	super.firstblob = super.firstmeta + super.nmeta;
	super.ffblob = super.firstblob * BlkSize;
	super.lfblob = super.ffblob + (super.nblob - 1) * BlkSize + BlkSize/2;
	super.state = FSClean;
	super.firstdat = super.firstblob + super.nblob;
	super.nfree = super.nblk - super.firstdat;
fprint(2, "writing superblock: freemap=%ulld nfreemap=%ulld firstdat=%ulld nmeta=%ulld firstmeta=%ulld\n", super.freemap, super.nfreemap, super.firstdat, super.nmeta, super.firstmeta);
	savesuper();
	/*
	 * Clear hash tables
	 */
	bigbuf = malloc(1024*1024);
	j = (1024 * 1024) / BlkSize;
	memset(bigbuf, 0, 1024 * 1024);
	for(i = 1; i < super.freemap; i += j)
{
fprint(2, ".");
if(++ndot % 60 == 0) fprint(2, "\n");
		pwrite(sfd, bigbuf, 1024 * 1024, i * BlkSize);
}
fprint(2, "\n");
	/*
	 * Init free bit map
	 */
	firstnon = super.firstdat / (BlkSize * 8);
	lastnon = super.nblk / (BlkSize * 8);
	memset(bigbuf, 0, BlkSize);
	for(i = 0; i < firstnon; ++i)
		pwrite(sfd, bigbuf, BlkSize, (super.freemap + i) * BlkSize);
	for(i = firstnon; i <= lastnon; ++i) {
		memset(bigbuf, 0xff, BlkSize);
		if(i == firstnon) {
			j = super.firstdat % (BlkSize * 8);
			k = j % 8;
			memset(bigbuf, 0, j/8);
			bigbuf[j/8] = ~((1 << k) - 1);
		}
		if(i == lastnon) {
			j = super.nblk % (BlkSize * 8);
			k = j % 8;
			bigbuf[j/8] = (1 << k) - 1;
			memset(bigbuf + j/8 + 1, 0, BlkSize - (j/8 + 1));
		}
		pwrite(sfd, bigbuf, BlkSize, (super.freemap + i) * BlkSize);
	}
	memset(bigbuf, 0, BlkSize);
	for(i = lastnon + 1; i < super.nfreemap; ++i)
		pwrite(sfd, bigbuf, BlkSize, (super.freemap + i) * BlkSize);
	free(bigbuf);
	loadsuper();
	/*
	 * Initialize the metadata regions
	 */
	reammeta(sfd);
	/*
	 * Create root directory
	 */
	rootqid.path = p2q(-1, "/", 1);
	meta = q2m(-1, rootqid.path, 1);
	setmetastr(meta, "name", nil, "/", 0);
	rootqid.vers = 0;
	rootqid.type = QTDIR;
	setmetaint(meta, "qpath", nil, rootqid.path);
	setmetaint(meta, "qvers", nil, rootqid.vers);
	setmetaint(meta, "qtype", nil, rootqid.type);
	setmetaint(meta, "mode", nil, DMDIR | 0775);
	now = nsec();
	setmetaint(meta, "atime", nil, now);
	setmetaint(meta, "mtime", nil, now);
	setmetaint(meta, "length", nil, 0);
	me = getuser();
	setmetastr(meta, "uid", nil, me, 0);
	setmetastr(meta, "gid", nil, me, 0);
	setmetastr(meta, "muid", nil, me, 0);
	setmetaint(meta, "child", nil, 0);
	setqhash(rootqid.path, meta);
	savesuper();
fprint(2, "Done with ream\n");
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].