13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * newdir.c --- create a new directory block
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * Copyright (C) 1994, 1995 Theodore Ts'o.
519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header%
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header%
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
17f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
18b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h"
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
21e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o#ifndef EXT2_FT_DIR
22e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o#define EXT2_FT_DIR		2
23e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o#endif
24e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Create new directory block
273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
2831dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
2931dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o			       ext2_ino_t parent_ino, char **block)
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
317b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	struct ext2_dir_entry 	*dir = NULL;
327b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	errcode_t		retval;
337b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	char			*buf;
347b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	int			rec_len;
35e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o	int			filetype = 0;
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
37f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
38f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
39c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o	retval = ext2fs_get_mem(fs->blocksize, &buf);
407b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o	if (retval)
417b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		return retval;
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	memset(buf, 0, fs->blocksize);
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	dir = (struct ext2_dir_entry *) buf;
448a480350952f6f0fdbce54326b6d847e66368897Theodore Ts'o
458a480350952f6f0fdbce54326b6d847e66368897Theodore Ts'o	retval = ext2fs_set_rec_len(fs, fs->blocksize, dir);
46e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (retval) {
47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ext2fs_free_mem(&buf);
488a480350952f6f0fdbce54326b6d847e66368897Theodore Ts'o		return retval;
49e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (dir_ino) {
52e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o		if (fs->super->s_feature_incompat &
53e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o		    EXT2_FEATURE_INCOMPAT_FILETYPE)
54e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o			filetype = EXT2_FT_DIR << 8;
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		/*
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 * Set up entry for '.'
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 */
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir->inode = dir_ino;
59e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o		dir->name_len = 1 | filetype;
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir->name[0] = '.';
615dd77dbe5a0ac6d78c1c6441fae4087be56d9088Theodore Ts'o		rec_len = fs->blocksize - EXT2_DIR_REC_LEN(1);
62e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o		dir->rec_len = EXT2_DIR_REC_LEN(1);
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		/*
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 * Set up entry for '..'
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 */
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
688a480350952f6f0fdbce54326b6d847e66368897Theodore Ts'o		retval = ext2fs_set_rec_len(fs, rec_len, dir);
69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (retval) {
70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ext2fs_free_mem(&buf);
718a480350952f6f0fdbce54326b6d847e66368897Theodore Ts'o			return retval;
72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		}
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir->inode = parent_ino;
74e6198e5a0191b2cbbf9765c4e4df11c7929279e6Theodore Ts'o		dir->name_len = 2 | filetype;
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir->name[0] = '.';
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		dir->name[1] = '.';
77efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	*block = buf;
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
82