/*
 * filefrag.c --- display the fragmentation information for a file
 *
 * Copyright (C) 2011 Theodore Ts'o.  This file may be redistributed
 * under the terms of the GNU Public License.
 */

#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif

#include "debugfs.h"

#define VERBOSE_OPT	0x0001
#define DIR_OPT		0x0002
#define RECURSIVE_OPT	0x0004

struct dir_list {
	char		*name;
	ext2_ino_t	ino;
	struct dir_list	*next;
};

struct filefrag_struct {
	FILE		*f;
	const char	*name;
	const char	*dir_name;
	int		options;
	int		logical_width;
	int		physical_width;
	int		ext;
	int		cont_ext;
	e2_blkcnt_t	num;
	e2_blkcnt_t	logical_start;
	blk64_t		physical_start;
	blk64_t		expected;
	struct dir_list *dir_list, *dir_last;
};

static int int_log10(unsigned long long arg)
{
	int     l = 0;

	arg = arg / 10;
	while (arg) {
		l++;
		arg = arg / 10;
	}
	return l;
}

static void print_header(struct filefrag_struct *fs)
{
	if (fs->options & VERBOSE_OPT) {
		fprintf(fs->f, "%4s %*s %*s %*s %*s\n", "ext",
			fs->logical_width, "logical", fs->physical_width,
			"physical", fs->physical_width, "expected",
			fs->logical_width, "length");
	}
}

static void report_filefrag(struct filefrag_struct *fs)
{
	if (fs->num == 0)
		return;
	if (fs->options & VERBOSE_OPT) {
		if (fs->expected)
			fprintf(fs->f, "%4d %*lu %*llu %*llu %*lu\n", fs->ext,
				fs->logical_width,
				(unsigned long) fs->logical_start,
				fs->physical_width, fs->physical_start,
				fs->physical_width, fs->expected,
				fs->logical_width, (unsigned long) fs->num);
		else
			fprintf(fs->f, "%4d %*lu %*llu %*s %*lu\n", fs->ext,
				fs->logical_width,
				(unsigned long) fs->logical_start,
				fs->physical_width, fs->physical_start,
				fs->physical_width, "",
				fs->logical_width, (unsigned long) fs->num);
	}
	fs->ext++;
}

static int filefrag_blocks_proc(ext2_filsys ext4_fs EXT2FS_ATTR((unused)),
				blk64_t *blocknr, e2_blkcnt_t blockcnt,
				blk64_t ref_block EXT2FS_ATTR((unused)),
				int ref_offset EXT2FS_ATTR((unused)),
				void *private)
{
	struct filefrag_struct *fs = private;

	if (blockcnt < 0 || *blocknr == 0)
		return 0;

	if ((fs->num == 0) || (blockcnt != fs->logical_start + fs->num) ||
	    (*blocknr != fs->physical_start + fs->num)) {
		report_filefrag(fs);
		if (blockcnt == fs->logical_start + fs->num)
			fs->expected = fs->physical_start + fs->num;
		else
			fs->expected = 0;
		fs->logical_start = blockcnt;
		fs->physical_start = *blocknr;
		fs->num = 1;
		fs->cont_ext++;
	} else
		fs->num++;
	return 0;
}

static void filefrag(ext2_ino_t ino, struct ext2_inode *inode,
		     struct filefrag_struct *fs)
{
	errcode_t	retval;
	int		blocksize = current_fs->blocksize;

	fs->logical_width = int_log10((EXT2_I_SIZE(inode) + blocksize - 1) /
				      blocksize) + 1;
	if (fs->logical_width < 7)
		fs->logical_width = 7;
	fs->ext = 0;
	fs->cont_ext = 0;
	fs->logical_start = 0;
	fs->physical_start = 0;
	fs->num = 0;

	if (fs->options & VERBOSE_OPT) {
		blk64_t num_blocks = ext2fs_inode_i_blocks(current_fs, inode);

		if (!ext2fs_has_feature_huge_file(current_fs->super) ||
		    !(inode->i_flags & EXT4_HUGE_FILE_FL))
			num_blocks /= current_fs->blocksize / 512;

		fprintf(fs->f, "\n%s has %llu block(s), i_size is %llu\n",
			fs->name, num_blocks, EXT2_I_SIZE(inode));
	}
	print_header(fs);
	if (ext2fs_inode_has_valid_blocks2(current_fs, inode)) {
		retval = ext2fs_block_iterate3(current_fs, ino,
					       BLOCK_FLAG_READ_ONLY, NULL,
					       filefrag_blocks_proc, fs);
		if (retval)
			com_err("ext2fs_block_iterate3", retval, 0);
	}

	report_filefrag(fs);
	fprintf(fs->f, "%s: %d contiguous extents%s\n", fs->name, fs->ext,
		LINUX_S_ISDIR(inode->i_mode) ? " (dir)" : "");
}

static int filefrag_dir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
			     int	entry,
			     struct ext2_dir_entry *dirent,
			     int	offset EXT2FS_ATTR((unused)),
			     int	blocksize EXT2FS_ATTR((unused)),
			     char	*buf EXT2FS_ATTR((unused)),
			     void	*private)
{
	struct filefrag_struct *fs = private;
	struct ext2_inode	inode;
	ext2_ino_t		ino;
	char			name[EXT2_NAME_LEN + 1];
	char			*cp;
	int			thislen;

	if (entry == DIRENT_DELETED_FILE)
		return 0;

	thislen = ext2fs_dirent_name_len(dirent);
	strncpy(name, dirent->name, thislen);
	name[thislen] = '\0';
	ino = dirent->inode;

	if (!strcmp(name, ".") || !strcmp(name, ".."))
		return 0;

	cp = malloc(strlen(fs->dir_name) + strlen(name) + 2);
	if (!cp) {
		fprintf(stderr, "Couldn't allocate memory for %s/%s\n",
			fs->dir_name, name);
		return 0;
	}

	sprintf(cp, "%s/%s", fs->dir_name, name);
	fs->name = cp;

	if (debugfs_read_inode(ino, &inode, fs->name))
		goto errout;

	filefrag(ino, &inode, fs);

	if ((fs->options & RECURSIVE_OPT) && LINUX_S_ISDIR(inode.i_mode)) {
		struct dir_list *p;

		p = malloc(sizeof(struct dir_list));
		if (!p) {
			fprintf(stderr, "Couldn't allocate dir_list for %s\n",
				fs->name);
			goto errout;
		}
		memset(p, 0, sizeof(struct dir_list));
		p->name = cp;
		p->ino = ino;
		if (fs->dir_last)
			fs->dir_last->next = p;
		else
			fs->dir_list = p;
		fs->dir_last = p;
		return 0;
	}
errout:
	free(cp);
	fs->name = 0;
	return 0;
}


static void dir_iterate(ext2_ino_t ino, struct filefrag_struct *fs)
{
	errcode_t	retval;
	struct dir_list	*p = NULL;

	fs->dir_name = fs->name;

	while (1) {
		retval = ext2fs_dir_iterate2(current_fs, ino, 0,
					     0, filefrag_dir_proc, fs);
		if (retval)
			com_err("ext2fs_dir_iterate2", retval, 0);
		if (p) {
			free(p->name);
			fs->dir_list = p->next;
			if (!fs->dir_list)
				fs->dir_last = 0;
			free(p);
		}
		p = fs->dir_list;
		if (!p)
			break;
		ino = p->ino;
		fs->dir_name = p->name;
	}
}

void do_filefrag(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
		 void *infop EXT2FS_ATTR((unused)))
{
	struct filefrag_struct fs;
	struct ext2_inode inode;
	ext2_ino_t	ino;
	int		c;

	memset(&fs, 0, sizeof(fs));
	if (check_fs_open(argv[0]))
		return;

	reset_getopt();
	while ((c = getopt(argc, argv, "dvr")) != EOF) {
		switch (c) {
		case 'd':
			fs.options |= DIR_OPT;
			break;
		case 'v':
			fs.options |= VERBOSE_OPT;
			break;
		case 'r':
			fs.options |= RECURSIVE_OPT;
			break;
		default:
			goto print_usage;
		}
	}

	if (argc > optind+1) {
	print_usage:
		com_err(0, 0, "Usage: filefrag [-dvr] file");
		return;
	}

	if (argc == optind) {
		ino = cwd;
		fs.name = ".";
	} else {
		ino = string_to_inode(argv[optind]);
		fs.name = argv[optind];
	}
	if (!ino)
		return;

	if (debugfs_read_inode(ino, &inode, argv[0]))
		return;

	fs.f = open_pager();
	fs.physical_width = int_log10(ext2fs_blocks_count(current_fs->super));
	fs.physical_width++;
	if (fs.physical_width < 8)
		fs.physical_width = 8;

	if (!LINUX_S_ISDIR(inode.i_mode) || (fs.options & DIR_OPT))
		filefrag(ino, &inode, &fs);
	else
		dir_iterate(ino, &fs);

	fprintf(fs.f, "\n");
	close_pager(fs.f);

	return;
}
