/*
 * mkdir.c --- make a directory in the filesystem
 * 
 * Copyright (C) 1994, 1995 Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <time.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#if EXT2_FLAT_INCLUDES
#include "ext2_fs.h"
#else
#include <linux/ext2_fs.h>
#endif

#include "ext2fs.h"

#ifndef EXT2_FT_DIR
#define EXT2_FT_DIR		2
#endif

errcode_t ext2fs_mkdir(ext2_filsys fs, ino_t parent, ino_t inum,
		       const char *name)
{
	errcode_t		retval;
	struct ext2_inode	inode;
	ino_t			ino = inum;
	ino_t			scratch_ino;
	blk_t			blk;
	char			*block = 0;
	int			group;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	/*
	 * Allocate an inode, if necessary
	 */
	if (!ino) {
		retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755,
					  0, &ino);
		if (retval)
			goto cleanup;
	}

	/*
	 * Allocate a data block for the directory
	 */
	retval = ext2fs_new_block(fs, 0, 0, &blk);
	if (retval)
		goto cleanup;

	/*
	 * Create a scratch template for the directory
	 */
	retval = ext2fs_new_dir_block(fs, ino, parent, &block);
	if (retval)
		goto cleanup;

	/*
	 * Create the inode structure....
	 */
	memset(&inode, 0, sizeof(struct ext2_inode));
	inode.i_mode = LINUX_S_IFDIR | 0755;
	inode.i_uid = inode.i_gid = 0;
	inode.i_blocks = fs->blocksize / 512;
	inode.i_block[0] = blk;
	inode.i_links_count = 2;
	inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
	inode.i_size = fs->blocksize;

	/*
	 * Write out the inode and inode data block
	 */
	retval = ext2fs_write_dir_block(fs, blk, block);
	if (retval)
		goto cleanup;
	retval = ext2fs_write_inode(fs, ino, &inode); 
	if (retval)
		goto cleanup;

	/*
	 * Update parent inode's counts
	 */
	if (parent != ino) {
		retval = ext2fs_read_inode(fs, parent, &inode);
		if (retval)
			goto cleanup;
		inode.i_links_count++;
		retval = ext2fs_write_inode(fs, parent, &inode);
		if (retval)
			goto cleanup;
	}
	
	/*
	 * Link the directory into the filesystem hierarchy
	 */
	if (name) {
		retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
				       &scratch_ino);
		if (!retval) {
			retval = EXT2_ET_DIR_EXISTS;
			name = 0;
			goto cleanup;
		}
		if (retval != EXT2_ET_FILE_NOT_FOUND)
			goto cleanup;
		retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR);
		if (retval)
			goto cleanup;
	}

	/*
	 * Update accounting....
	 */
	ext2fs_mark_block_bitmap(fs->block_map, blk);
	ext2fs_mark_bb_dirty(fs);
	ext2fs_mark_inode_bitmap(fs->inode_map, ino);
	ext2fs_mark_ib_dirty(fs);

	group = ext2fs_group_of_blk(fs, blk);
	fs->group_desc[group].bg_free_blocks_count--;
	group = ext2fs_group_of_ino(fs, ino);
	fs->group_desc[group].bg_free_inodes_count--;
	fs->group_desc[group].bg_used_dirs_count++;
	fs->super->s_free_blocks_count--;
	fs->super->s_free_inodes_count--;
	ext2fs_mark_super_dirty(fs);
	
cleanup:
	if (block)
		ext2fs_free_mem((void **) &block);
	return retval;

}


