mkdir.c revision 48f23054bb8ad0506c0baa9f06ba182acc2aa88b
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/* 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * mkdir.c --- make a directory in the filesystem 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Copyright (C) 1994, 1995 Theodore Ts'o. 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * %Begin-Header% 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * This file may be redistributed under the terms of the GNU Public 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * License. 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * %End-Header% 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <stdio.h> 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string.h> 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if HAVE_UNISTD_H 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <unistd.h> 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <fcntl.h> 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <time.h> 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if HAVE_SYS_STAT_H 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/stat.h> 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if HAVE_SYS_TYPES_H 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/types.h> 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ext2_fs.h" 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ext2fs.h" 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef EXT2_FT_DIR 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define EXT2_FT_DIR 2 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char *name) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles){ 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errcode_t retval; 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) struct ext2_inode parent_inode, inode; 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ext2_ino_t ino = inum; 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ext2_ino_t scratch_ino; 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) blk_t blk; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char *block = 0; 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Allocate an inode, if necessary 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) */ 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!ino) { 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755, 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 0, &ino); 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (retval) 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto cleanup; 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Allocate a data block for the directory 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) retval = ext2fs_new_block(fs, 0, 0, &blk); 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (retval) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto cleanup; 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Create a scratch template for the directory 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) retval = ext2fs_new_dir_block(fs, ino, parent, &block); 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (retval) 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto cleanup; 68 69 /* 70 * Get the parent's inode, if necessary 71 */ 72 if (parent != ino) { 73 retval = ext2fs_read_inode(fs, parent, &parent_inode); 74 if (retval) 75 goto cleanup; 76 } else 77 memset(&parent_inode, 0, sizeof(parent_inode)); 78 79 /* 80 * Create the inode structure.... 81 */ 82 memset(&inode, 0, sizeof(struct ext2_inode)); 83 inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask); 84 inode.i_uid = inode.i_gid = 0; 85 ext2fs_iblk_set(fs, &inode, 1); 86 inode.i_block[0] = blk; 87 inode.i_links_count = 2; 88 inode.i_size = fs->blocksize; 89 90 /* 91 * Write out the inode and inode data block 92 */ 93 retval = ext2fs_write_dir_block(fs, blk, block); 94 if (retval) 95 goto cleanup; 96 retval = ext2fs_write_new_inode(fs, ino, &inode); 97 if (retval) 98 goto cleanup; 99 100 /* 101 * Link the directory into the filesystem hierarchy 102 */ 103 if (name) { 104 retval = ext2fs_lookup(fs, parent, name, strlen(name), 0, 105 &scratch_ino); 106 if (!retval) { 107 retval = EXT2_ET_DIR_EXISTS; 108 name = 0; 109 goto cleanup; 110 } 111 if (retval != EXT2_ET_FILE_NOT_FOUND) 112 goto cleanup; 113 retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR); 114 if (retval) 115 goto cleanup; 116 } 117 118 /* 119 * Update parent inode's counts 120 */ 121 if (parent != ino) { 122 parent_inode.i_links_count++; 123 retval = ext2fs_write_inode(fs, parent, &parent_inode); 124 if (retval) 125 goto cleanup; 126 } 127 128 /* 129 * Update accounting.... 130 */ 131 ext2fs_block_alloc_stats2(fs, blk, +1); 132 ext2fs_inode_alloc_stats2(fs, ino, +1, 1); 133 134cleanup: 135 if (block) 136 ext2fs_free_mem(&block); 137 return retval; 138 139} 140 141 142