ialloc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * ialloc.c
  3.  *
  4.  * PURPOSE
  5.  * Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
  6.  *
  7.  * CONTACTS
  8.  * E-mail regarding any portion of the Linux UDF file system should be
  9.  * directed to the development team mailing list (run by majordomo):
  10.  * linux_udf@hpesjro.fc.hp.com
  11.  *
  12.  * COPYRIGHT
  13.  * This file is distributed under the terms of the GNU General Public
  14.  * License (GPL). Copies of the GPL can be obtained from:
  15.  * ftp://prep.ai.mit.edu/pub/gnu/GPL
  16.  * Each contributing author retains all rights to their own work.
  17.  *
  18.  *  (C) 1998-2001 Ben Fennema
  19.  *
  20.  * HISTORY
  21.  *
  22.  *  02/24/99 blf  Created.
  23.  *
  24.  */
  25. #include "udfdecl.h"
  26. #include <linux/fs.h>
  27. #include <linux/locks.h>
  28. #include <linux/quotaops.h>
  29. #include <linux/udf_fs.h>
  30. #include "udf_i.h"
  31. #include "udf_sb.h"
  32. void udf_free_inode(struct inode * inode)
  33. {
  34. struct super_block * sb = inode->i_sb;
  35. int is_directory;
  36. unsigned long ino;
  37. ino = inode->i_ino;
  38. /*
  39.  * Note: we must free any quota before locking the superblock,
  40.  * as writing the quota to disk may need the lock as well.
  41.  */
  42. DQUOT_FREE_INODE(inode);
  43. DQUOT_DROP(inode);
  44. lock_super(sb);
  45. is_directory = S_ISDIR(inode->i_mode);
  46. clear_inode(inode);
  47. if (UDF_SB_LVIDBH(sb))
  48. {
  49. if (is_directory)
  50. UDF_SB_LVIDIU(sb)->numDirs =
  51. cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
  52. else
  53. UDF_SB_LVIDIU(sb)->numFiles =
  54. cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
  55. mark_buffer_dirty(UDF_SB_LVIDBH(sb));
  56. }
  57. unlock_super(sb);
  58. udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
  59. }
  60. struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
  61. {
  62. struct super_block *sb;
  63. struct inode * inode;
  64. int block;
  65. uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
  66. sb = dir->i_sb;
  67. inode = new_inode(sb);
  68. if (!inode)
  69. {
  70. *err = -ENOMEM;
  71. return NULL;
  72. }
  73. *err = -ENOSPC;
  74. block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
  75. start, err);
  76. if (*err)
  77. {
  78. iput(inode);
  79. return NULL;
  80. }
  81. lock_super(sb);
  82. if (UDF_SB_LVIDBH(sb))
  83. {
  84. struct logicalVolHeaderDesc *lvhd;
  85. uint64_t uniqueID;
  86. lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
  87. if (S_ISDIR(mode))
  88. UDF_SB_LVIDIU(sb)->numDirs =
  89. cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
  90. else
  91. UDF_SB_LVIDIU(sb)->numFiles =
  92. cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
  93. UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
  94. if (!(++uniqueID & 0x00000000FFFFFFFFUL))
  95. uniqueID += 16;
  96. lvhd->uniqueID = cpu_to_le64(uniqueID);
  97. mark_buffer_dirty(UDF_SB_LVIDBH(sb));
  98. }
  99. inode->i_mode = mode;
  100. inode->i_uid = current->fsuid;
  101. if (dir->i_mode & S_ISGID)
  102. {
  103. inode->i_gid = dir->i_gid;
  104. if (S_ISDIR(mode))
  105. mode |= S_ISGID;
  106. }
  107. else
  108. inode->i_gid = current->fsgid;
  109. UDF_I_LOCATION(inode).logicalBlockNum = block;
  110. UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
  111. inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
  112. inode->i_blksize = PAGE_SIZE;
  113. inode->i_blocks = 0;
  114. UDF_I_LENEATTR(inode) = 0;
  115. UDF_I_LENALLOC(inode) = 0;
  116. if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
  117. {
  118. UDF_I_EXTENDED_FE(inode) = 1;
  119. UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
  120. }
  121. else
  122. UDF_I_EXTENDED_FE(inode) = 0;
  123. if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
  124. UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
  125. else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
  126. UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
  127. else
  128. UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
  129. inode->i_mtime = inode->i_atime = inode->i_ctime =
  130. UDF_I_CRTIME(inode) = CURRENT_TIME;
  131. UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
  132. UDF_I_UCRTIME(inode) = CURRENT_UTIME;
  133. UDF_I_NEW_INODE(inode) = 1;
  134. insert_inode_hash(inode);
  135. mark_inode_dirty(inode);
  136. unlock_super(sb);
  137. if (DQUOT_ALLOC_INODE(inode))
  138. {
  139. DQUOT_DROP(inode);
  140. inode->i_flags |= S_NOQUOTA;
  141. inode->i_nlink = 0;
  142. iput(inode);
  143. *err = -EDQUOT;
  144. return NULL;
  145. }
  146. *err = 0;
  147. return inode;
  148. }