/*
 * mk_hugefiles.c -- create huge files
 */

#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
#define _BSD_SOURCE	  /* for makedev() and major() */
#define _DEFAULT_SOURCE	  /* since glibc 2.20 _BSD_SOURCE is deprecated */

#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#ifdef __linux__
#include <sys/utsname.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include <limits.h>
#include <blkid/blkid.h>

#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fsP.h"
#include "et/com_err.h"
#include "uuid/uuid.h"
#include "e2p/e2p.h"
#include "ext2fs/ext2fs.h"
#include "util.h"
#include "support/profile.h"
#include "support/prof_err.h"
#include "support/nls-enable.h"
#include "mke2fs.h"

static int uid;
static int gid;
static blk64_t num_blocks;
static blk64_t num_slack;
static unsigned long num_files;
static blk64_t goal;
static char *fn_prefix;
static int idx_digits;
static char *fn_buf;
static char *fn_numbuf;
int zero_hugefile = 1;

#define SYSFS_PATH_LEN 256
typedef char sysfs_path_t[SYSFS_PATH_LEN];

#ifndef HAVE_SNPRINTF
/*
 * We are very careful to avoid needing to worry about buffer
 * overflows, so we don't really need to use snprintf() except as an
 * additional safety check.  So if snprintf() is not present, it's
 * safe to fall back to vsprintf().  This provides portability since
 * vsprintf() is guaranteed by C89, while snprintf() is only
 * guaranteed by C99 --- which for example, Microsoft Visual Studio
 * has *still* not bothered to implement.  :-/  (Not that I expect
 * mke2fs to be ported to MS Visual Studio any time soon, but
 * libext2fs *does* get built on Microsoft platforms, and we might
 * want to move this into libext2fs some day.)
 */
static int my_snprintf(char *str, size_t size, const char *format, ...)
{
	va_list	ap;
	int ret;

	va_start(ap, format);
	ret = vsprintf(str, format, ap);
	va_end(ap);
	return ret;
}

#define snprintf my_snprintf
#endif

/*
 * Fall back to Linux's definitions of makedev and major are needed.
 * The search_sysfs_block() function is highly unlikely to work on
 * non-Linux systems anyway.
 */
#ifndef makedev
#define makedev(maj, min) (((maj) << 8) + (min))
#endif

static char *search_sysfs_block(dev_t devno, sysfs_path_t ret_path)
{
	struct dirent	*de, *p_de;
	DIR		*dir = NULL, *p_dir = NULL;
	FILE		*f;
	sysfs_path_t	path, p_path;
	unsigned int	major, minor;
	char		*ret = ret_path;

	ret_path[0] = 0;
	if ((dir = opendir("/sys/block")) == NULL)
		return NULL;
	while ((de = readdir(dir)) != NULL) {
		if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
		    strlen(de->d_name) > sizeof(path)-32)
			continue;
		snprintf(path, SYSFS_PATH_LEN,
			 "/sys/block/%s/dev", de->d_name);
		f = fopen(path, "r");
		if (f &&
		    (fscanf(f, "%u:%u", &major, &minor) == 2)) {
			fclose(f); f = NULL;
			if (makedev(major, minor) == devno) {
				snprintf(ret_path, SYSFS_PATH_LEN,
					 "/sys/block/%s", de->d_name);
				goto success;
			}
#ifdef major
			if (major(devno) != major)
				continue;
#endif
		}
		if (f)
			fclose(f);

		snprintf(path, SYSFS_PATH_LEN, "/sys/block/%s", de->d_name);

		if (p_dir)
			closedir(p_dir);
		if ((p_dir = opendir(path)) == NULL)
			continue;
		while ((p_de = readdir(p_dir)) != NULL) {
			if (!strcmp(p_de->d_name, ".") ||
			    !strcmp(p_de->d_name, "..") ||
			    (strlen(p_de->d_name) >
			     SYSFS_PATH_LEN - strlen(path) - 32))
				continue;
			snprintf(p_path, SYSFS_PATH_LEN, "%s/%s/dev",
				 path, p_de->d_name);

			f = fopen(p_path, "r");
			if (f &&
			    (fscanf(f, "%u:%u", &major, &minor) == 2) &&
			    (((major << 8) + minor) == devno)) {
				fclose(f);
				snprintf(ret_path, SYSFS_PATH_LEN, "%s/%s",
					 path, p_de->d_name);
				goto success;
			}
			if (f)
				fclose(f);
		}
	}
	ret = NULL;
success:
	if (dir)
		closedir(dir);
	if (p_dir)
		closedir(p_dir);
	return ret;
}

static blk64_t get_partition_start(const char *device_name)
{
	unsigned long long start;
	sysfs_path_t	path;
	struct stat	st;
	FILE		*f;
	char		*cp;
	int		n;

	if ((stat(device_name, &st) < 0) || !S_ISBLK(st.st_mode))
		return 0;

	cp = search_sysfs_block(st.st_rdev, path);
	if (!cp)
		return 0;
	if (strlen(path) > SYSFS_PATH_LEN - sizeof("/start"))
		return 0;
	strcat(path, "/start");
	f = fopen(path, "r");
	if (!f)
		return 0;
	n = fscanf(f, "%llu", &start);
	fclose(f);
	return (n == 1) ? start : 0;
}

static errcode_t create_directory(ext2_filsys fs, char *dir,
				  ext2_ino_t *ret_ino)

{
	struct ext2_inode	inode;
	ext2_ino_t		ino = EXT2_ROOT_INO;
	ext2_ino_t		newdir;
	errcode_t		retval = 0;
	char			*fn, *cp, *next;

	fn = malloc(strlen(dir) + 1);
	if (fn == NULL)
		return ENOMEM;

	strcpy(fn, dir);
	cp = fn;
	while(1) {
		next = strchr(cp, '/');
		if (next)
			*next++ = 0;
		if (*cp) {
			retval = ext2fs_new_inode(fs, ino, LINUX_S_IFDIR,
						  NULL, &newdir);
			if (retval)
				goto errout;

			retval = ext2fs_mkdir(fs, ino, newdir, cp);
			if (retval)
				goto errout;

			ino = newdir;
			retval = ext2fs_read_inode(fs, ino, &inode);
			if (retval)
				goto errout;

			inode.i_uid = uid & 0xFFFF;
			ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
			inode.i_gid = gid & 0xFFFF;
			ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);
			retval = ext2fs_write_inode(fs, ino, &inode);
			if (retval)
				goto errout;
		}
		if (next == NULL || *next == '\0')
			break;
		cp = next;
	}
errout:
	free(fn);
	if (retval == 0)
		*ret_ino = ino;
	return retval;
}

static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
			     ext2_ino_t dir, unsigned long idx, ext2_ino_t *ino)

{
	errcode_t		retval;
	struct ext2_inode	inode;

	retval = ext2fs_new_inode(fs, 0, LINUX_S_IFREG, NULL, ino);
	if (retval)
		return retval;

	memset(&inode, 0, sizeof(struct ext2_inode));
	inode.i_mode = LINUX_S_IFREG | (0666 & ~fs->umask);
	inode.i_links_count = 1;
	inode.i_uid = uid & 0xFFFF;
	ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
	inode.i_gid = gid & 0xFFFF;
	ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);

	retval = ext2fs_write_new_inode(fs, *ino, &inode);
	if (retval)
		return retval;

	ext2fs_inode_alloc_stats2(fs, *ino, +1, 0);

	if (ext2fs_has_feature_extents(fs->super))
		inode.i_flags |= EXT4_EXTENTS_FL;
	retval = ext2fs_fallocate(fs,
				  EXT2_FALLOCATE_FORCE_INIT |
				  EXT2_FALLOCATE_ZERO_BLOCKS,
				  *ino, &inode, goal, 0, num);
	if (retval)
		return retval;
	retval = ext2fs_inode_size_set(fs, &inode, num * fs->blocksize);
	if (retval)
		return retval;

	retval = ext2fs_write_inode(fs, *ino, &inode);
	if (retval)
		goto errout;

	if (idx_digits)
		sprintf(fn_numbuf, "%0*lu", idx_digits, idx);
	else if (num_files > 1)
		sprintf(fn_numbuf, "%lu", idx);

retry:
	retval = ext2fs_link(fs, dir, fn_buf, *ino, EXT2_FT_REG_FILE);
	if (retval == EXT2_ET_DIR_NO_SPACE) {
		retval = ext2fs_expand_dir(fs, dir);
		if (retval)
			goto errout;
		goto retry;
	}

errout:
	return retval;
}

static blk64_t calc_overhead(ext2_filsys fs, blk64_t num)
{
	blk64_t e_blocks, e_blocks2, e_blocks3, e_blocks4;
	int extents_per_block;
	int extents = (num + EXT_INIT_MAX_LEN - 1) / EXT_INIT_MAX_LEN;

	if (extents <= 4)
		return 0;

	/*
	 * This calculation is due to the fact that we are inefficient
	 * in how handle extent splits when appending to the end of
	 * the extent tree.  Sigh.  We should fix this so that we can
	 * actually store 340 extents per 4k block, instead of only 170.
	 */
	extents_per_block = ((fs->blocksize -
			      sizeof(struct ext3_extent_header)) /
			     sizeof(struct ext3_extent));
	extents_per_block = (extents_per_block/ 2) - 1;

	e_blocks = (extents + extents_per_block - 1) / extents_per_block;
	e_blocks2 = (e_blocks + extents_per_block - 1) / extents_per_block;
	e_blocks3 = (e_blocks2 + extents_per_block - 1) / extents_per_block;
	e_blocks4 = (e_blocks3 + extents_per_block - 1) / extents_per_block;
	return e_blocks + e_blocks2 + e_blocks3 + e_blocks4;
}

/*
 * Find the place where we should start allocating blocks for the huge
 * files.  Leave <slack> free blocks at the beginning of the file
 * system for things like metadata blocks.
 */
static blk64_t get_start_block(ext2_filsys fs, blk64_t slack)
{
	errcode_t retval;
	blk64_t blk = fs->super->s_first_data_block, next;
	blk64_t last_blk = ext2fs_blocks_count(fs->super) - 1;

	while (slack) {
		retval = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
						blk, last_blk, &blk);
		if (retval)
			break;

		retval = ext2fs_find_first_set_block_bitmap2(fs->block_map,
						blk, last_blk, &next);
		if (retval)
			next = last_blk;

		if (next - blk > slack) {
			blk += slack;
			break;
		}

		slack -= (next - blk);
		blk = next;
	}
	return blk;
}

static blk64_t round_up_align(blk64_t b, unsigned long align,
			      blk64_t part_offset)
{
	unsigned long m;

	if (align == 0)
		return b;
	part_offset = part_offset % align;
	m = (b + part_offset) % align;
	if (m)
		b += align - m;
	return b;
}

errcode_t mk_hugefiles(ext2_filsys fs, const char *device_name)
{
	unsigned long	i;
	ext2_ino_t	dir;
	errcode_t	retval;
	blk64_t		fs_blocks, part_offset = 0;
	unsigned long	align;
	int		d, dsize;
	char		*t;

	if (!get_bool_from_profile(fs_types, "make_hugefiles", 0))
		return 0;

	if (!ext2fs_has_feature_extents(fs->super))
		return EXT2_ET_EXTENT_NOT_SUPPORTED;

	uid = get_int_from_profile(fs_types, "hugefiles_uid", 0);
	gid = get_int_from_profile(fs_types, "hugefiles_gid", 0);
	fs->umask = get_int_from_profile(fs_types, "hugefiles_umask", 077);
	num_files = get_int_from_profile(fs_types, "num_hugefiles", 0);
	t = get_string_from_profile(fs_types, "hugefiles_slack", "1M");
	num_slack = parse_num_blocks2(t, fs->super->s_log_block_size);
	free(t);
	t = get_string_from_profile(fs_types, "hugefiles_size", "0");
	num_blocks = parse_num_blocks2(t, fs->super->s_log_block_size);
	free(t);
	t = get_string_from_profile(fs_types, "hugefiles_align", "0");
	align = parse_num_blocks2(t, fs->super->s_log_block_size);
	free(t);
	if (get_bool_from_profile(fs_types, "hugefiles_align_disk", 0)) {
		part_offset = get_partition_start(device_name) /
			(fs->blocksize / 512);
		if (part_offset % EXT2FS_CLUSTER_RATIO(fs)) {
			fprintf(stderr,
				_("Partition offset of %llu (%uk) blocks "
				  "not compatible with cluster size %u.\n"),
				part_offset, fs->blocksize,
				EXT2_CLUSTER_SIZE(fs->super));
			exit(1);
		}
	}
	num_blocks = round_up_align(num_blocks, align, 0);
	zero_hugefile = get_bool_from_profile(fs_types, "zero_hugefiles",
					      zero_hugefile);

	t = get_string_from_profile(fs_types, "hugefiles_dir", "/");
	retval = create_directory(fs, t, &dir);
	free(t);
	if (retval)
		return retval;

	fn_prefix = get_string_from_profile(fs_types, "hugefiles_name",
					    "hugefile");
	idx_digits = get_int_from_profile(fs_types, "hugefiles_digits", 5);
	d = int_log10(num_files) + 1;
	if (idx_digits > d)
		d = idx_digits;
	dsize = strlen(fn_prefix) + d + 16;
	fn_buf = malloc(dsize);
	if (!fn_buf) {
		free(fn_prefix);
		return ENOMEM;
	}
	strcpy(fn_buf, fn_prefix);
	fn_numbuf = fn_buf + strlen(fn_prefix);
	free(fn_prefix);

	fs_blocks = ext2fs_free_blocks_count(fs->super);
	if (fs_blocks < num_slack + align)
		return ENOSPC;
	fs_blocks -= num_slack + align;
	if (num_blocks && num_blocks > fs_blocks)
		return ENOSPC;
	if (num_blocks == 0 && num_files == 0)
		num_files = 1;

	if (num_files == 0 && num_blocks) {
		num_files = fs_blocks / num_blocks;
		fs_blocks -= (num_files / 16) + 1;
		fs_blocks -= calc_overhead(fs, num_blocks) * num_files;
		num_files = fs_blocks / num_blocks;
	}

	if (num_blocks == 0 && num_files > 1) {
		num_blocks = fs_blocks / num_files;
		fs_blocks -= (num_files / 16) + 1;
		fs_blocks -= calc_overhead(fs, num_blocks) * num_files;
		num_blocks = fs_blocks / num_files;
	}

	num_slack += calc_overhead(fs, num_blocks) * num_files;
	num_slack += (num_files / 16) + 1; /* space for dir entries */
	goal = get_start_block(fs, num_slack);
	goal = round_up_align(goal, align, part_offset);

	if ((num_blocks ? num_blocks : fs_blocks) >
	    (0x80000000UL / fs->blocksize))
		ext2fs_set_feature_large_file(fs->super);

	if (!quiet) {
		if (zero_hugefile && verbose)
			printf("%s", _("Huge files will be zero'ed\n"));
		printf(_("Creating %lu huge file(s) "), num_files);
		if (num_blocks)
			printf(_("with %llu blocks each"), num_blocks);
		fputs(": ", stdout);
	}
	if (num_blocks == 0)
		num_blocks = ext2fs_blocks_count(fs->super) - goal;
	for (i=0; i < num_files; i++) {
		ext2_ino_t ino;

		retval = mk_hugefile(fs, num_blocks, dir, i, &ino);
		if (retval) {
			com_err(program_name, retval,
				_("while creating huge file %lu"), i);
			goto errout;
		}
	}
	if (!quiet)
		fputs(_("done\n"), stdout);

errout:
	free(fn_buf);
	return retval;
}
