/*
 * 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
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#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 300
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;
	blk64_t			lblk, bend = 0;
	__u64			size;
	blk64_t			left;
	blk64_t			count = 0;
	struct ext2_inode	inode;
	ext2_extent_handle_t	handle;

	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);

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

	/*
	 * We don't use ext2fs_fallocate() here because hugefiles are
	 * designed to be physically contiguous (if the block group
	 * descriptors are configured to be in a single block at the
	 * beginning of the file system, by using the
	 * packed_meta_blocks layout), with the extent tree blocks
	 * allocated near the beginning of the file system.
	 */
	lblk = 0;
	left = num ? num : 1;
	while (left) {
		blk64_t pblk, end;
		blk64_t n = left;

		retval =  ext2fs_find_first_zero_block_bitmap2(fs->block_map,
			goal, ext2fs_blocks_count(fs->super) - 1, &end);
		if (retval)
			goto errout;
		goal = end;

		retval =  ext2fs_find_first_set_block_bitmap2(fs->block_map, goal,
			       ext2fs_blocks_count(fs->super) - 1, &bend);
		if (retval == ENOENT) {
			bend = ext2fs_blocks_count(fs->super);
			if (num == 0)
				left = 0;
		}
		if (!num || bend - goal < left)
			n = bend - goal;
		pblk = goal;
		if (num)
			left -= n;
		goal += n;
		count += n;
		ext2fs_block_alloc_stats_range(fs, pblk, n, +1);

		if (zero_hugefile) {
			blk64_t ret_blk;
			retval = ext2fs_zero_blocks2(fs, pblk, n,
						     &ret_blk, NULL);

			if (retval)
				com_err(program_name, retval,
					_("while zeroing block %llu "
					  "for hugefile"), ret_blk);
		}

		while (n) {
			blk64_t l = n;
			struct ext2fs_extent newextent;

			if (l > EXT_INIT_MAX_LEN)
				l = EXT_INIT_MAX_LEN;

			newextent.e_len = l;
			newextent.e_pblk = pblk;
			newextent.e_lblk = lblk;
			newextent.e_flags = 0;

			retval = ext2fs_extent_insert(handle,
					EXT2_EXTENT_INSERT_AFTER, &newextent);
			if (retval)
				return retval;
			pblk += l;
			lblk += l;
			n -= l;
		}
	}

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

	retval = ext2fs_iblk_add_blocks(fs, &inode,
					count / EXT2FS_CLUSTER_RATIO(fs));
	if (retval)
		goto errout;
	size = (__u64) count * fs->blocksize;
	retval = ext2fs_inode_size_set(fs, &inode, size);
	if (retval)
		goto errout;

	retval = ext2fs_write_new_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;
	}

	if (retval)
		goto errout;

errout:
	if (handle)
		ext2fs_extent_free(handle);

	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) *
		EXT2FS_CLUSTER_RATIO(fs);
}

/*
 * 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_blocks : fs_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);
	}
	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;
}
