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