code: mafs

ref: fb53d7e68bcb2108fb304c81dccb1d7ff50ffa1f
dir: /updatefrees.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

/*
	update /adm/frees

	disk/unused <{disk/used tests/test.0/disk} 32 | tr -d '	' > /mnt/term/tmp/unused.blocks
	cat /mnt/term/tmp/unused.blocks
	disk/updatefrees tests/test.0/disk /mnt/term/tmp/unused.blocks

	TODO
		does not work when the size of free extents > Blocksize-(3*8)
 */

int debug = 0;
char *devfile = nil, *freesfile = nil;

static void
usage(void)
{
	fprint(2, "usage: updatefrees [-D] fsfile freecontentfile\n");
	exits("usage");
}

void
main(int argc, char *argv[])
{
	u64 size, freeblkno;
	s32 nfreesize;
	s8 buf[Metadatablocksize], frees[Maxdatablocksize];
	u64 freesdata[Nu64perblock];
	int fd;
	Data *f;
	Dentry *d;

	ARGBEGIN{
	default:	usage();
	case 'D':	debug++; break;
	}ARGEND

	if(argc != 2)
		usage();

	devfile = argv[0];
	if(devfile == nil)
		sysfatal("no disk file");

	freesfile = strdup(argv[1]);
	if(freesfile == nil)
		sysfatal("no frees file");

	memset(buf, 0, Metadatablocksize);
	memset(frees, 0, Maxdatablocksize);

	fd = open(freesfile, OREAD);
	if(fd < 0)
		sysfatal("updatefrees: cannot open freesfile %s\n", freesfile);

	nfreesize = readn(fd, frees, Maxdatablocksize);
	if(nfreesize <= 0)
		sysfatal("updatefrees: nfreesize %d <= 0\n", nfreesize);
	if(nfreesize > (Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */)))
		sysfatal("updatefrees: unsupported nfreesize %d needs more than a block Datablocksize %llud\n",
					nfreesize, Blocksize -sizeof(Datahdr) -sizeof(u64 /* trailing path */));
	if(nfreesize > Maxdatablocksize)
		sysfatal("updatefrees: unsupported nfreesize %d > Datablocksize %llud\n",
					nfreesize, Maxdatablocksize);
	close(fd);

	/* use the first block to write */
	freeblkno = atoll((s8*)frees);

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

	size = devinit(devfile);
	if(size == 0)
		panic("null size %s", devfile);

	if(debug){
		print("Namelen %d\n", Namelen);
		print("Dentry size %d\n", sizeof(Dentry));
	}

	devread(Bdfrees, buf, Metadataunits);
	// showblock(1, buf);
	recentmetadata(buf, &d, nil);

	if(d->size != nfreesize)
		print("changed size: %llud to %d\n", d->size, nfreesize);
	d->size = nfreesize;
	if(nfreesize < Ddatasize){
		strncpy(d->buf, frees, nfreesize);
		devwrite(Bdfrees, buf, Metadataunits);
	}else{
		if(d->dblocks[0] != freeblkno)
			print("changed dblocks[0]: %llud to %llud\n", d->dblocks[0], freeblkno);
		d->dblocks[0] = freeblkno;

		f = (Data*)freesdata;
		f->tag = Tdata;
		f->len = 1;
		memcpy(f->buf, frees, Blocksize -Ddataidssize);
		freesdata[Dpathidx] = Qpfrees;

		devwrite(Bdfrees, buf, Metadataunits);
		// devwrite(freeblkno, frees, nlastdatablocks(nfreesize));
		devwrite(freeblkno, (s8*)freesdata, 1);
	}
	close(devfd);
	exits(0);
}