mkdir.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. #include <stdio.h>
  13. #include <string.h>
  14. #if HAVE_UNISTD_H
  15. #include <unistd.h>
  16. #endif
  17. #include <fcntl.h>
  18. #include <time.h>
  19. #if HAVE_SYS_STAT_H
  20. #include <sys/stat.h>
  21. #endif
  22. #if HAVE_SYS_TYPES_H
  23. #include <sys/types.h>
  24. #endif
  25. #include "ext2_fs.h"
  26. #include "ext2fs.h"
  27. #ifndef EXT2_FT_DIR
  28. #define EXT2_FT_DIR 2
  29. #endif
  30. errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
  31. const char *name)
  32. {
  33. errcode_t retval;
  34. struct ext2_inode parent_inode, inode;
  35. ext2_ino_t ino = inum;
  36. ext2_ino_t scratch_ino;
  37. blk_t blk;
  38. char *block = 0;
  39. EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
  40. /*
  41. * Allocate an inode, if necessary
  42. */
  43. if (!ino) {
  44. retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755,
  45. 0, &ino);
  46. if (retval)
  47. goto cleanup;
  48. }
  49. /*
  50. * Allocate a data block for the directory
  51. */
  52. retval = ext2fs_new_block(fs, 0, 0, &blk);
  53. if (retval)
  54. goto cleanup;
  55. /*
  56. * Create a scratch template for the directory
  57. */
  58. retval = ext2fs_new_dir_block(fs, ino, parent, &block);
  59. if (retval)
  60. goto cleanup;
  61. /*
  62. * Get the parent's inode, if necessary
  63. */
  64. if (parent != ino) {
  65. retval = ext2fs_read_inode(fs, parent, &parent_inode);
  66. if (retval)
  67. goto cleanup;
  68. } else
  69. memset(&parent_inode, 0, sizeof(parent_inode));
  70. /*
  71. * Create the inode structure....
  72. */
  73. memset(&inode, 0, sizeof(struct ext2_inode));
  74. inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
  75. inode.i_uid = inode.i_gid = 0;
  76. inode.i_blocks = fs->blocksize / 512;
  77. inode.i_block[0] = blk;
  78. inode.i_links_count = 2;
  79. inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
  80. inode.i_size = fs->blocksize;
  81. /*
  82. * Write out the inode and inode data block
  83. */
  84. retval = ext2fs_write_dir_block(fs, blk, block);
  85. if (retval)
  86. goto cleanup;
  87. retval = ext2fs_write_new_inode(fs, ino, &inode);
  88. if (retval)
  89. goto cleanup;
  90. /*
  91. * Link the directory into the filesystem hierarchy
  92. */
  93. if (name) {
  94. retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
  95. &scratch_ino);
  96. if (!retval) {
  97. retval = EXT2_ET_DIR_EXISTS;
  98. name = 0;
  99. goto cleanup;
  100. }
  101. if (retval != EXT2_ET_FILE_NOT_FOUND)
  102. goto cleanup;
  103. retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR);
  104. if (retval)
  105. goto cleanup;
  106. }
  107. /*
  108. * Update parent inode's counts
  109. */
  110. if (parent != ino) {
  111. parent_inode.i_links_count++;
  112. retval = ext2fs_write_inode(fs, parent, &parent_inode);
  113. if (retval)
  114. goto cleanup;
  115. }
  116. /*
  117. * Update accounting....
  118. */
  119. ext2fs_block_alloc_stats(fs, blk, +1);
  120. ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
  121. cleanup:
  122. ext2fs_free_mem(&block);
  123. return retval;
  124. }