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