newdir.c revision 3984b61df41c68966bdfbb2a5e5a45ef4b9a536c
1d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * newdir.c --- create a new directory block
3d0825bca7fe65beaee391d30da42e937db621564Steve Block *
4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 1994, 1995 Theodore Ts'o.
5d0825bca7fe65beaee391d30da42e937db621564Steve Block *
6d0825bca7fe65beaee391d30da42e937db621564Steve Block * %Begin-Header%
7d0825bca7fe65beaee391d30da42e937db621564Steve Block * This file may be redistributed under the terms of the GNU Public
8d0825bca7fe65beaee391d30da42e937db621564Steve Block * License.
9d0825bca7fe65beaee391d30da42e937db621564Steve Block * %End-Header%
10d0825bca7fe65beaee391d30da42e937db621564Steve Block */
11d0825bca7fe65beaee391d30da42e937db621564Steve Block
12d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <stdio.h>
13d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <string.h>
14d0825bca7fe65beaee391d30da42e937db621564Steve Block#if HAVE_UNISTD_H
15d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <unistd.h>
16d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
17d0825bca7fe65beaee391d30da42e937db621564Steve Block
18d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ext2_fs.h"
19d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ext2fs.h"
20d0825bca7fe65beaee391d30da42e937db621564Steve Block
21d0825bca7fe65beaee391d30da42e937db621564Steve Block#ifndef EXT2_FT_DIR
22d0825bca7fe65beaee391d30da42e937db621564Steve Block#define EXT2_FT_DIR		2
23d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
24d0825bca7fe65beaee391d30da42e937db621564Steve Block
25d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Create new directory block
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
28d0825bca7fe65beaee391d30da42e937db621564Steve Blockerrcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch			       ext2_ino_t parent_ino, char **block)
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	struct ext2_dir_entry 	*dir = NULL;
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	errcode_t		retval;
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	char			*buf;
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	int			rec_len;
352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block	int			filetype = 0;
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
38d0825bca7fe65beaee391d30da42e937db621564Steve Block
39d0825bca7fe65beaee391d30da42e937db621564Steve Block	retval = ext2fs_get_mem(fs->blocksize, &buf);
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	if (retval)
41d0825bca7fe65beaee391d30da42e937db621564Steve Block		return retval;
42d0825bca7fe65beaee391d30da42e937db621564Steve Block	memset(buf, 0, fs->blocksize);
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	dir = (struct ext2_dir_entry *) buf;
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
45ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch	retval = ext2fs_set_rec_len(fs, fs->blocksize, dir);
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	if (retval)
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		return retval;
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	if (dir_ino) {
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		if (fs->super->s_feature_incompat &
51d0825bca7fe65beaee391d30da42e937db621564Steve Block		    EXT2_FEATURE_INCOMPAT_FILETYPE)
52d0825bca7fe65beaee391d30da42e937db621564Steve Block			filetype = EXT2_FT_DIR << 8;
53ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch		/*
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		 * Set up entry for '.'
55d0825bca7fe65beaee391d30da42e937db621564Steve Block		 */
56ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch		dir->inode = dir_ino;
57ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch		dir->name_len = 1 | filetype;
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		dir->name[0] = '.';
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		rec_len = fs->blocksize - EXT2_DIR_REC_LEN(1);
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block		dir->rec_len = EXT2_DIR_REC_LEN(1);
612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		/*
63d0825bca7fe65beaee391d30da42e937db621564Steve Block		 * Set up entry for '..'
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		 */
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch		retval = ext2fs_set_rec_len(fs, rec_len, dir);
67d0825bca7fe65beaee391d30da42e937db621564Steve Block		if (retval)
68ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch			return retval;
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		dir->inode = parent_ino;
70ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch		dir->name_len = 2 | filetype;
71ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch		dir->name[0] = '.';
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch		dir->name[1] = '.';
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
74ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch	}
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	*block = buf;
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch	return 0;
77ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
78ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch