* @param preferredBlockBroup first try to allocate the inode in this block group
* @return the INode
*/
protected INode createINode(int preferredBlockBroup, int fileFormat, int accessRights, int uid, int gid)
throws FileSystemException, IOException {
if (preferredBlockBroup >= superblock.getBlocksCount()) throw new FileSystemException("Block group "
+ preferredBlockBroup + " does not exist");
int groupNr = preferredBlockBroup;
// first check the preferred block group, if it has any free inodes
INodeReservation res = findFreeINode(groupNr);
// if no free inode has been found in the preferred block group, then
// try the others
if (!res.isSuccessful()) {
for (groupNr = 0; groupNr < superblock.getBlockGroupNr(); groupNr++) {
res = findFreeINode(groupNr);
if (res.isSuccessful()) {
break;
}
}
}
if (!res.isSuccessful()) throw new FileSystemException("No free inodes found!");
// a free inode has been found: create the inode and write it into the
// inode table
INodeTable iNodeTable = iNodeTables[preferredBlockBroup];
// byte[] iNodeData = new byte[INode.INODE_LENGTH];
int iNodeNr = res.getINodeNr((int) superblock.getINodesPerGroup());
INode iNode = new INode(this, new INodeDescriptor(iNodeTable, iNodeNr, groupNr, res.getIndex()));
iNode.create(fileFormat, accessRights, uid, gid);
// trigger a write to disk
iNode.update();
log.debug("** NEW INODE ALLOCATED: inode number: " + iNode.getINodeNr());
// put the inode into the cache
synchronized (inodeCache) {
Integer key = Integer.valueOf(iNodeNr);
if (inodeCache.containsKey(key)) throw new FileSystemException(
"Newly allocated inode is already in the inode cache!?");
else inodeCache.put(key, iNode);
}
return iNode;