X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fnewdir.c;h=7f472850090b9c5b942757179bff5b891d96465d;hb=947315c86645e3ac3e814a49a7e7ab4b3498f64b;hp=7f4266a5e93cf08b0943f6992fe6afd8abb2036c;hpb=8a480350952f6f0fdbce54326b6d847e66368897;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/newdir.c b/lib/ext2fs/newdir.c index 7f4266a..7f47285 100644 --- a/lib/ext2fs/newdir.c +++ b/lib/ext2fs/newdir.c @@ -4,11 +4,12 @@ * Copyright (C) 1994, 1995 Theodore Ts'o. * * %Begin-Header% - * This file may be redistributed under the terms of the GNU Public - * License. + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -33,6 +34,8 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino, char *buf; int rec_len; int filetype = 0; + struct ext2_dir_entry_tail *t; + int csum_size = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -42,21 +45,26 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino, memset(buf, 0, fs->blocksize); dir = (struct ext2_dir_entry *) buf; - retval = ext2fs_set_rec_len(fs, fs->blocksize, dir); - if (retval) + if (ext2fs_has_feature_metadata_csum(fs->super)) + csum_size = sizeof(struct ext2_dir_entry_tail); + + retval = ext2fs_set_rec_len(fs, fs->blocksize - csum_size, dir); + if (retval) { + ext2fs_free_mem(&buf); return retval; + } if (dir_ino) { - if (fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE) - filetype = EXT2_FT_DIR << 8; + if (ext2fs_has_feature_filetype(fs->super)) + filetype = EXT2_FT_DIR; /* * Set up entry for '.' */ dir->inode = dir_ino; - dir->name_len = 1 | filetype; + ext2fs_dirent_set_name_len(dir, 1); + ext2fs_dirent_set_file_type(dir, filetype); dir->name[0] = '.'; - rec_len = fs->blocksize - EXT2_DIR_REC_LEN(1); + rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1); dir->rec_len = EXT2_DIR_REC_LEN(1); /* @@ -64,14 +72,55 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino, */ dir = (struct ext2_dir_entry *) (buf + dir->rec_len); retval = ext2fs_set_rec_len(fs, rec_len, dir); - if (retval) + if (retval) { + ext2fs_free_mem(&buf); return retval; + } dir->inode = parent_ino; - dir->name_len = 2 | filetype; + ext2fs_dirent_set_name_len(dir, 2); + ext2fs_dirent_set_file_type(dir, filetype); dir->name[0] = '.'; dir->name[1] = '.'; } + + if (csum_size) { + t = EXT2_DIRENT_TAIL(buf, fs->blocksize); + ext2fs_initialize_dirent_tail(fs, t); + } *block = buf; return 0; } + +/* + * Create new directory on inline data + */ +errcode_t ext2fs_new_dir_inline_data(ext2_filsys fs, + ext2_ino_t dir_ino EXT2FS_ATTR((unused)), + ext2_ino_t parent_ino, __u32 *iblock) +{ + struct ext2_dir_entry *dir = NULL; + errcode_t retval; + int rec_len; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + iblock[0] = ext2fs_cpu_to_le32(parent_ino); + + dir = (struct ext2_dir_entry *)((char *)iblock + + EXT4_INLINE_DATA_DOTDOT_SIZE); + dir->inode = 0; + rec_len = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DATA_DOTDOT_SIZE; + retval = ext2fs_set_rec_len(fs, rec_len, dir); + if (retval) + goto errout; + +#ifdef WORDS_BIGENDIAN + retval = ext2fs_dirent_swab_out2(fs, (char *)dir, rec_len, 0); + if (retval) + goto errout; +#endif + +errout: + return retval; +}