Example #1
0
int bfree(int dev, int block)
{
    u8* bmap = get_bmap(dev);

    clear_bit(&bmap, block);
    set_free_blocks(dev, +1);

    put_bmap(dev, bmap);
}
Example #2
0
int balloc(int dev)
{
    int block_count = get_blocks_count(dev);
    u8* bmap = get_bmap(dev);

    int  i;
    for (i = 0; i < block_count; i++)
    {
        if (test_bit(bmap, i) == 0)
        {
            set_bit(&bmap, i);
            set_free_blocks(dev, -1);
            put_bmap(dev, bmap);

            return i;
        }
    }
    printf("balloc(): no more free blocks\n");
    return -1;
}
static void frag_report(const char *filename)
{
	struct statfs	fsinfo;
#ifdef HAVE_FSTAT64
	struct stat64	fileinfo;
#else
	struct stat	fileinfo;
#endif
	int		bs;
	long		fd;
	unsigned long	block, last_block = 0, numblocks, i, count;
	long		bpib;	/* Blocks per indirect block */
	long		cylgroups;
	int		discont = 0, expected;
	int		is_ext2 = 0;
	unsigned int	flags;

	if (statfs(filename, &fsinfo) < 0) {
		perror("statfs");
		return;
	}
#ifdef HAVE_FSTAT64
	if (stat64(filename, &fileinfo) < 0) {
#else
	if (stat(filename, &fileinfo) < 0) {
#endif
		perror("stat");
		return;
	}
	if (!S_ISREG(fileinfo.st_mode)) {
		printf("%s: Not a regular file\n", filename);
		return;
	}
	if ((fsinfo.f_type == 0xef51) || (fsinfo.f_type == 0xef52) ||
	    (fsinfo.f_type == 0xef53))
		is_ext2++;
	if (verbose) {
		printf("Filesystem type is: %lx\n",
		       (unsigned long) fsinfo.f_type);
	}
	cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize*8);
	if (verbose) {
		printf("Filesystem cylinder groups is approximately %ld\n",
		       cylgroups);
	}
#ifdef HAVE_OPEN64
	fd = open64(filename, O_RDONLY);
#else
	fd = open(filename, O_RDONLY);
#endif
	if (fd < 0) {
		perror("open");
		return;
	}
	if (ioctl(fd, FIGETBSZ, &bs) < 0) { /* FIGETBSZ takes an int */
		perror("FIGETBSZ");
		close(fd);
		return;
	}
	if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
		flags = 0;
	if (flags & EXT4_EXTENTS_FL) {
		if (verbose)
			printf("File is stored in extents format\n");
		is_ext2 = 0;
	}
	if (verbose)
		printf("Blocksize of file %s is %d\n", filename, bs);
	bpib = bs / 4;
	numblocks = (fileinfo.st_size + (bs-1)) / bs;
	if (verbose) {
		printf("File size of %s is %lld (%ld blocks)\n", filename,
		       (long long) fileinfo.st_size, numblocks);
		printf("First block: %lu\nLast block: %lu\n",
		       get_bmap(fd, 0), get_bmap(fd, numblocks - 1));
	}
	for (i=0, count=0; i < numblocks; i++) {
		if (is_ext2 && last_block) {
			if (((i-EXT2_DIRECT) % bpib) == 0)
				last_block++;
			if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
				last_block++;
			if (((i-EXT2_DIRECT-bpib-bpib*bpib) % (bpib*bpib*bpib)) == 0)
				last_block++;
		}
		block = get_bmap(fd, i);
		if (block == 0)
			continue;
		count++;
		if (last_block && (block != last_block +1) ) {
			if (verbose)
				printf("Discontinuity: Block %ld is at %lu (was %lu)\n",
				       i, block, last_block);
			discont++;
		}
		last_block = block;
	}
	if (discont==0)
		printf("%s: 1 extent found", filename);
	else
		printf("%s: %d extents found", filename, discont+1);
	expected = (count/((bs*8)-(fsinfo.f_files/8/cylgroups)-3))+1;
	if (is_ext2 && expected < discont+1)
		printf(", perfection would be %d extent%s\n", expected,
			(expected>1) ? "s" : "");
	else
		fputc('\n', stdout);
	close(fd);
}

static void usage(const char *progname)
{
	fprintf(stderr, "Usage: %s [-v] file ...\n", progname);
	exit(1);
}
Example #4
0
static void frag_report(const char *filename)
{
	struct statfs	fsinfo;
#ifdef HAVE_FSTAT64
	struct stat64	fileinfo;
#else
	struct stat	fileinfo;
#endif
	int		bs;
	long		fd;
	unsigned long	block, last_block = 0, numblocks, i, count;
	long		bpib;	/* Blocks per indirect block */
	long		cylgroups;
	int		num_extents = 0, expected;
	int		is_ext2 = 0;
	static int	once = 1;
	unsigned int	flags;
	int rc;

#ifdef HAVE_OPEN64
	fd = open64(filename, O_RDONLY);
#else
	fd = open(filename, O_RDONLY);
#endif
	if (fd < 0) {
		perror("open");
		return;
	}

	if (statfs(filename, &fsinfo) < 0) {
		perror("statfs");
		return;
	}
#ifdef HAVE_FSTAT64
	if (stat64(filename, &fileinfo) < 0) {
#else
	if (stat(filename, &fileinfo) < 0) {
#endif
		perror("stat");
		return;
	}
	if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
		flags = 0;
	if (!(flags & EXT4_EXTENTS_FL) &&
	    ((fsinfo.f_type == 0xef51) || (fsinfo.f_type == 0xef52) ||
	     (fsinfo.f_type == 0xef53)))
		is_ext2++;
	if (verbose && once)
		printf("Filesystem type is: %lx\n",
		       (unsigned long) fsinfo.f_type);

	cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize*8);
	if (verbose && is_ext2 && once)
		printf("Filesystem cylinder groups is approximately %ld\n",
		       cylgroups);

	physical_width = int_log10(fsinfo.f_blocks);
	if (physical_width < 8)
		physical_width = 8;

	if (ioctl(fd, FIGETBSZ, &bs) < 0) { /* FIGETBSZ takes an int */
		perror("FIGETBSZ");
		close(fd);
		return;
	}

	if (no_bs)
		bs = 1024;

	bpib = bs / 4;
	numblocks = (fileinfo.st_size + (bs-1)) / bs;
	logical_width = int_log10(numblocks);
	if (logical_width < 7)
		logical_width = 7;
	filesize = (long long)fileinfo.st_size;
	if (verbose)
		printf("File size of %s is %lld (%ld block%s, blocksize %d)\n",
		       filename, (long long) fileinfo.st_size, numblocks,
		       numblocks == 1 ? "" : "s", bs);
	if (force_bmap ||
	    filefrag_fiemap(fd, int_log2(bs), &num_extents) != 0) {
		for (i = 0, count = 0; i < numblocks; i++) {
			if (is_ext2 && last_block) {
				if (((i-EXT2_DIRECT) % bpib) == 0)
					last_block++;
				if (((i-EXT2_DIRECT-bpib) % (bpib*bpib)) == 0)
					last_block++;
				if (((i-EXT2_DIRECT-bpib-bpib*bpib) %
							(bpib*bpib*bpib)) == 0)
					last_block++;
			}
			rc = get_bmap(fd, i, &block);
			if (block == 0)
				continue;
			if (!num_extents)
				num_extents++;
			count++;
			if (last_block && (block != last_block+1) ) {
				if (verbose)
					printf("Discontinuity: Block %ld is at "
					       "%lu (was %lu)\n",
					       i, block, last_block+1);
				num_extents++;
			}
			last_block = block;
		}
	}
	if (num_extents == 1)
		printf("%s: 1 extent found", filename);
	else
		printf("%s: %d extents found", filename, num_extents);
	expected = (count/((bs*8)-(fsinfo.f_files/8/cylgroups)-3))+1;
	if (is_ext2 && expected < num_extents)
		printf(", perfection would be %d extent%s\n", expected,
			(expected>1) ? "s" : "");
	else
		fputc('\n', stdout);
	close(fd);
	once = 0;
}

static void usage(const char *progname)
{
	fprintf(stderr, "Usage: %s [-Bbvsx] file ...\n", progname);
	exit(1);
}
static void copy_sparse_file(const char *src, const char *dest)
{
	struct stat64	fileinfo;
	long		lb, i, fd, ofd, bs, block, numblocks;
	ssize_t		got, got2;
	off64_t		offset = 0, should_be;
	char		*buf;

	if (verbose)
		printf("Copying sparse file from %s to %s\n", src, dest);

	if (strcmp(src, "-")) {
		if (stat64(src, &fileinfo) < 0) {
			perror("stat");
			exit(1);
		}
		if (!S_ISREG(fileinfo.st_mode)) {
			printf("%s: Not a regular file\n", src);
			exit(1);
		}
		fd = open(src, O_RDONLY | O_LARGEFILE);
		if (fd < 0) {
			perror("open");
			exit(1);
		}
		if (ioctl(fd, FIGETBSZ, &bs) < 0) {
			perror("FIGETBSZ");
			close(fd);
			exit(1);
		}
		if (bs < 0) {
			printf("%s: Invalid block size: %ld\n", src, bs);
			exit(1);
		}
		if (verbose)
			printf("Blocksize of file %s is %ld\n", src, bs);
		numblocks = (fileinfo.st_size + (bs-1)) / bs;
		if (verbose)
			printf("File size of %s is %lld (%ld blocks)\n", src,
			       (long long) fileinfo.st_size, numblocks);
	} else {
		fd = 0;
		bs = 1024;
	}

	ofd = open(dest, O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0777);
	if (ofd < 0) {
		perror(dest);
		exit(1);
	}

	buf = malloc(bs);
	if (!buf) {
		fprintf(stderr, "Couldn't allocate buffer");
		exit(1);
	}

	for (lb = 0; !fd || lb < numblocks; lb++) {
		if (fd) {
			block = get_bmap(fd, lb);
			if (!block)
				continue;
			should_be = ((off64_t) lb) * bs;
			if (offset != should_be) {
				if (verbose)
					printf("Seeking to %lld\n", should_be);
				if (lseek64(fd, should_be, SEEK_SET) == (off_t) -1) {
					perror("lseek src");
					exit(1);
				}
				if (lseek64(ofd, should_be, SEEK_SET) == (off_t) -1) {
					perror("lseek dest");
					exit(1);
				}
				offset = should_be;
			}
		}
		got = full_read(fd, buf, bs);

		if (fd == 0 && got == 0)
			break;

		if (got == bs) {
			for (i=0; i < bs; i++)
				if (buf[i])
					break;
			if (i == bs) {
				lseek(ofd, bs, SEEK_CUR);
				offset += bs;
				continue;
			}
		}
		got2 = write(ofd, buf, got);
		if (got != got2) {
			printf("short write\n");
			exit(1);
		}
		offset += got;
	}
	offset = fileinfo.st_size;
	if (fstat64(ofd, &fileinfo) < 0) {
		perror("fstat");
		exit(1);
	}
	if (fileinfo.st_size != offset) {
		lseek64(ofd, offset-1, SEEK_CUR);
		buf[0] = 0;
		write(ofd, buf, 1);
	}
	close(fd);
	close(ofd);
}