mkdir.c revision 32138187f08d1f1dc03feb269f987982db76f3db
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/* 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * mkdir.c --- make a directory in the filesystem 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Copyright (C) 1994, 1995 Theodore Ts'o. 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * %Begin-Header% 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * This file may be redistributed under the terms of the GNU Public 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * License. 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * %End-Header% 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdio.h> 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string.h> 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if HAVE_UNISTD_H 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <unistd.h> 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <fcntl.h> 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <time.h> 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if HAVE_SYS_STAT_H 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sys/stat.h> 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if HAVE_SYS_TYPES_H 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sys/types.h> 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ext2_fs.h" 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ext2fs.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef EXT2_FT_DIR 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define EXT2_FT_DIR 2 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdocherrcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char *name) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errcode_t retval; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct ext2_inode parent_inode, inode; 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2_ino_t ino = inum; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2_ino_t scratch_ino; 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blk_t blk; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char *block = 0; 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Allocate an inode, if necessary 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!ino) { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755, 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, &ino); 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Allocate a data block for the directory 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_new_block(fs, 0, 0, &blk); 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Create a scratch template for the directory 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_new_dir_block(fs, ino, parent, &block); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Get the parent's inode, if necessary 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (parent != ino) { 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_read_inode(fs, parent, &parent_inode); 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch memset(&parent_inode, 0, sizeof(parent_inode)); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Create the inode structure.... 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch memset(&inode, 0, sizeof(struct ext2_inode)); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask); 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_uid = inode.i_gid = 0; 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_blocks = fs->blocksize / 512; 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_block[0] = blk; 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_links_count = 2; 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_ctime = inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(NULL); 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inode.i_size = fs->blocksize; 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Write out the inode and inode data block 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_write_dir_block(fs, blk, block); 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_write_new_inode(fs, ino, &inode); 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Link the directory into the filesystem hierarchy 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (name) { 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_lookup(fs, parent, name, strlen(name), 0, 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &scratch_ino); 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!retval) { 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = EXT2_ET_DIR_EXISTS; 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch name = 0; 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval != EXT2_ET_FILE_NOT_FOUND) 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR); 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Update parent inode's counts 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (parent != ino) { 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parent_inode.i_links_count++; 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_write_inode(fs, parent, &parent_inode); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto cleanup; 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Update accounting.... 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_block_alloc_stats(fs, blk, +1); 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_inode_alloc_stats2(fs, ino, +1, 1); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochcleanup: 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (block) 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_free_mem(&block); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return retval; 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch