Пример #1
0
/*
 * Collect up the data into tape record sized buffers and output them.
 */
void
ufs2_blksout(daddr_t *blkp, int frags, ino_t ino)
{
	daddr_t *bp;
	int i, j, count, blks, tbperdb;

	blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
	tbperdb = sblock->fs_bsize >> tp_bshift;
	for (i = 0; i < blks; i += TP_NINDIR) {
		if (i + TP_NINDIR > blks)
			count = blks;
		else
			count = i + TP_NINDIR;
		for (j = i; j < count; j++)
			if (blkp[j / tbperdb] != 0)
				spcl.c_addr[j - i] = 1;
			else
				spcl.c_addr[j - i] = 0;
		spcl.c_count = count - i;
		writeheader(ino);
		bp = &blkp[i / tbperdb];
		for (j = i; j < count; j += tbperdb, bp++)
			if (*bp != 0) {
				if (j + tbperdb <= count)
					dumpblock(*bp, (int)sblock->fs_bsize);
				else
					dumpblock(*bp, (count - j) * TP_BSIZE);
			}
		spcl.c_type = TS_ADDR;
	}
}
Пример #2
0
/*
 * Dump the extended attribute data. If there was room in the file
 * header, then all we need to do is output the data blocks. If there
 * was not room in the file header, then an additional TS_ADDR header
 * is created to hold the attribute data.
 */
static void
writeextdata(union dinode *dp, ino_t ino, int added)
{
	int i, frags, blks, tbperdb, last;
	ufs2_daddr_t *bp;
	off_t size;

	/*
	 * If no extended attributes, there is nothing to do.
	 */
	if (spcl.c_extsize == 0)
		return;
	/*
	 * If there was no room in the file block for the attributes,
	 * dump them out in a new block, otherwise just dump the data.
	 */
	if (added == 0) {
		if (spcl.c_extsize > NXADDR * sblock->fs_bsize) {
			frags = NXADDR * sblock->fs_frag;
			last = 0;
		} else {
			frags = howmany(spcl.c_extsize, sblock->fs_fsize);
			last = 1;
		}
		ufs2_blksout(dp, &dp->dp2.di_extb[0], frags, ino, last);
	} else {
		if (spcl.c_extsize > NXADDR * sblock->fs_bsize)
			blks = howmany(NXADDR * sblock->fs_bsize, TP_BSIZE);
		else
			blks = howmany(spcl.c_extsize, TP_BSIZE);
		tbperdb = sblock->fs_bsize >> tp_bshift;
		for (i = 0; i < blks; i += tbperdb) {
			bp = &dp->dp2.di_extb[i / tbperdb];
			if (*bp != 0) {
				if (i + tbperdb <= blks)
					dumpblock(*bp, (int)sblock->fs_bsize);
				else
					dumpblock(*bp, (blks - i) * TP_BSIZE);
			}
		}

	}
	/*
	 * If an indirect block is added for extended attributes, then
	 * di_exti below should be changed to the structure element
	 * that references the extended attribute indirect block. This
	 * definition is here only to make it compile without complaint.
	 */
#define di_exti di_spare[0]
	/*
	 * If the extended attributes fall into an indirect block,
	 * dump it as well.
	 */
	if ((size = spcl.c_extsize - NXADDR * sblock->fs_bsize) > 0)
		dmpindir(dp, ino, dp->dp2.di_exti, 0, &size);
}
Пример #3
0
/*
 * Collect up the data into tape record sized buffers and output them.
 */
static void
ufs2_blksout(union dinode *dp, ufs2_daddr_t *blkp, int frags, ino_t ino,
	int last)
{
	ufs2_daddr_t *bp;
	int i, j, count, resid, blks, tbperdb, added;
	static int writingextdata = 0;

	/*
	 * Calculate the number of TP_BSIZE blocks to be dumped.
	 * For filesystems with a fragment size bigger than TP_BSIZE,
	 * only part of the final fragment may need to be dumped.
	 */
	blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
	if (last) {
		resid = howmany(fragoff(sblock, dp->dp2.di_size), TP_BSIZE);
		if (resid > 0)
			blks -= howmany(sblock->fs_fsize, TP_BSIZE) - resid;
	}
	tbperdb = sblock->fs_bsize >> tp_bshift;
	for (i = 0; i < blks; i += TP_NINDIR) {
		if (i + TP_NINDIR > blks)
			count = blks;
		else
			count = i + TP_NINDIR;
		for (j = i; j < count; j++)
			if (blkp[j / tbperdb] != 0)
				spcl.c_addr[j - i] = 1;
			else
				spcl.c_addr[j - i] = 0;
		spcl.c_count = count - i;
		if (last && count == blks && !writingextdata)
			added = appendextdata(dp);
		writeheader(ino);
		bp = &blkp[i / tbperdb];
		for (j = i; j < count; j += tbperdb, bp++)
			if (*bp != 0) {
				if (j + tbperdb <= count)
					dumpblock(*bp, (int)sblock->fs_bsize);
				else
					dumpblock(*bp, (count - j) * TP_BSIZE);
			}
		spcl.c_type = TS_ADDR;
		spcl.c_count = 0;
		if (last && count == blks && !writingextdata) {
			writingextdata = 1;
			writeextdata(dp, ino, added);
			writingextdata = 0;
		}
	}
}
Пример #4
0
/*
 * process to copy dump blocks from
 * cache to worm. it runs flat out when
 * it gets work, but only looks for
 * work every 10 seconds.
 */
void
wormcopy(void *)
{
	int f, dorecalc = 1;
	Timet dt, t = 0, nddate = 0, ntoytime = 0;
	Filsys *fs;

	for (;;) {
		if (dorecalc) {
			dorecalc = 0;
			t = time(nil);
			nddate = nextdump(t);		/* chatters */
			ntoytime = time(nil);
		}
		dt = time(nil) - t;
		if(dt < 0 || dt > MINUTE(100)) {
			if(dt < 0)
				print("time went back\n");
			else
				print("time jumped ahead\n");
			dorecalc = 1;
			continue;
		}
		t += dt;
		f = 0;
		if(t > ntoytime)
			ntoytime = time(nil) + HOUR(1);
		else if(t > nddate) {
			if(!conf.nodump) {
				print("automatic dump %T\n", t);
				for(fs=filsys; fs->name; fs++)
					if(fs->dev->type == Devcw)
						cfsdump(fs);
			}
			dorecalc = 1;
		} else {
			rlock(&mainlock);
			for(fs=filsys; fs->name; fs++)
				if(fs->dev->type == Devcw)
					f |= dumpblock(fs->dev);
			runlock(&mainlock);
			if(!f)
				delay(10000);
			wormprobe();
		}
	}
}
Пример #5
0
static int
readblks(int fd, size_t alignment)
{
	__uint64_t offset;
	char *buffer, *tmp;
	unsigned int xfer, block, i;
        int err=0;

	if (alloconly)
		return 0;
	xfer = READ_XFER*blocksize;
	if (posix_memalign((void **) &buffer, alignment, xfer)) {
		perror("malloc");
		exit(1);
	}
	memset(buffer, 0, xfer);
	if (verbose)
		printf("\n");

	if (lseek64(fd, fileoffset, SEEK_SET) < 0) {
		perror("lseek");
		exit(1);
	}
	block = 0;
	offset = 0;
	while (offset < filesize) {
		if ((i = read(fd, buffer, xfer) < xfer)) {
			if (i < 2)
				break;
			perror("read");
			exit(1);
		}
		tmp = buffer;
		for (i = 0; i < READ_XFER; i++) {
			__uint64_t want;
			__uint64_t first;
			__uint64_t second;

			if (verbose && ((block % 100) == 0)) {
				printf("+");
				fflush(stdout);
			}

			want = BITVAL(valid, block) ? offset : 0;
			first = *(__uint64_t *) tmp;
			second = *(__uint64_t *) (tmp + 256);
			if (first != want || second != want) {
				printf("mismatched data at offset=0x%" PRIx64
					", expected 0x%" PRIx64
					", got 0x%" PRIx64
					" and 0x%" PRIx64 "\n",
					 fileoffset + offset, want,
					 first, second);
				err++;
			}
			if (verbose > 2) {
				printf("block %d blocksize %d\n", block,
				       blocksize);
				dumpblock((int *)tmp, fileoffset + offset,
					  blocksize);
			}

			block++;
			offset += blocksize;
			tmp += blocksize;
		}
	}
	if (verbose)
		printf("\n");

	free(buffer);
        return err;
}