home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / ext2tool.exe / EXT2FS / MKDIR.C < prev    next >
C/C++ Source or Header  |  1995-05-10  |  3KB  |  136 lines

  1. /*
  2.  * mkdir.c --- make a directory in the filesystem
  3.  * 
  4.  * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
  5.  * under the terms of the GNU Public License.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <sys/stat.h>
  15. #include <errno.h>
  16. #include <sys/types.h>
  17.  
  18. #include <linux/ext2_fs.h>
  19.  
  20. #include "ext2fs.h"
  21.  
  22. errcode_t ext2fs_mkdir(ext2_filsys fs, ino_t parent, ino_t inum,
  23.                const char *name)
  24. {
  25.     errcode_t        retval;
  26.     struct ext2_inode    inode;
  27.     ino_t            ino = inum;
  28.     ino_t            scratch_ino;
  29.     blk_t            blk;
  30.     char            *block = 0;
  31.     int            group;
  32.  
  33.     EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
  34.  
  35.     /*
  36.      * Allocate an inode, if necessary
  37.      */
  38.     if (!ino) {
  39.         retval = ext2fs_new_inode(fs, parent, S_IFDIR | 0755, 0, &ino);
  40.         if (retval)
  41.             goto cleanup;
  42.     }
  43.  
  44.     /*
  45.      * Allocate a data block for the directory
  46.      */
  47.     retval = ext2fs_new_block(fs, 0, 0, &blk);
  48.     if (retval)
  49.         goto cleanup;
  50.  
  51.     /*
  52.      * Create a scratch template for the directory
  53.      */
  54.     retval = ext2fs_new_dir_block(fs, ino, parent, &block);
  55.     if (retval)
  56.         goto cleanup;
  57.  
  58.     /*
  59.      * Create the inode structure....
  60.      */
  61.     memset(&inode, 0, sizeof(struct ext2_inode));
  62.     inode.i_mode = S_IFDIR | 0755;
  63.     inode.i_uid = inode.i_gid = 0;
  64.     inode.i_blocks = fs->blocksize / 512;
  65.     inode.i_block[0] = blk;
  66.     inode.i_links_count = 2;
  67.     inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
  68.     inode.i_size = fs->blocksize;
  69.  
  70.     /*
  71.      * Write out the inode and inode data block
  72.      */
  73.     retval = io_channel_write_blk(fs->io, blk, 1, block);
  74.     if (retval)
  75.         goto cleanup;
  76.     retval = ext2fs_write_inode(fs, ino, &inode); 
  77.     if (retval)
  78.         goto cleanup;
  79.  
  80.     /*
  81.      * Update parent inode's counts
  82.      */
  83.     if (parent != ino) {
  84.         retval = ext2fs_read_inode(fs, parent, &inode);
  85.         if (retval)
  86.             goto cleanup;
  87.         inode.i_links_count++;
  88.         retval = ext2fs_write_inode(fs, parent, &inode);
  89.         if (retval)
  90.             goto cleanup;
  91.     }
  92.     
  93.     /*
  94.      * Link the directory into the filesystem hierarchy
  95.      */
  96.     if (name) {
  97.         retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
  98.                        &scratch_ino);
  99.         if (!retval) {
  100.             retval = EEXIST;
  101.             name = 0;
  102.             goto cleanup;
  103.         }
  104.         if (retval != ENOENT)
  105.             goto cleanup;
  106.         retval = ext2fs_link(fs, parent, name, ino, 0);
  107.         if (retval)
  108.             goto cleanup;
  109.     }
  110.  
  111.     /*
  112.      * Update accounting....
  113.      */
  114.     ext2fs_mark_block_bitmap(fs->block_map, blk);
  115.     ext2fs_mark_bb_dirty(fs);
  116.     ext2fs_mark_inode_bitmap(fs->inode_map, ino);
  117.     ext2fs_mark_ib_dirty(fs);
  118.  
  119.     group = ext2fs_group_of_blk(fs, blk);
  120.     fs->group_desc[group].bg_free_blocks_count--;
  121.     group = ext2fs_group_of_ino(fs, ino);
  122.     fs->group_desc[group].bg_free_inodes_count--;
  123.     fs->group_desc[group].bg_used_dirs_count++;
  124.     fs->super->s_free_blocks_count--;
  125.     fs->super->s_free_inodes_count--;
  126.     ext2fs_mark_super_dirty(fs);
  127.     
  128. cleanup:
  129.     if (block)
  130.         free(block);
  131.     return retval;
  132.  
  133. }
  134.  
  135.  
  136.