From: <ga...@us...> - 2009-03-19 16:23:56
|
Revision: 5118 http://jnode.svn.sourceforge.net/jnode/?rev=5118&view=rev Author: galatnm Date: 2009-03-19 16:23:45 +0000 (Thu, 19 Mar 2009) Log Message: ----------- Rewrite and javadocs. Also fix extent descriptor creation. Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusFile.java trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusForkData.java trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java trunk/fs/src/fs/org/jnode/fs/hfsplus/catalog/Catalog.java trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/Extent.java trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentDescriptor.java trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentKey.java trunk/fs/src/fs/org/jnode/fs/hfsplus/tree/BTHeaderRecord.java Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusFile.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusFile.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusFile.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -52,7 +52,7 @@ HfsPlusFileSystem fs = (HfsPlusFileSystem) getFileSystem(); for (ExtentDescriptor d : file.getDatas().getExtents()) { if (!d.isEmpty()) { - long firstOffset = d.getStartBlock() * fs.getVolumeHeader().getBlockSize(); + long firstOffset = d.getStartOffset(fs.getVolumeHeader().getBlockSize()); fs.getApi().read(firstOffset, dest); } } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusForkData.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusForkData.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusForkData.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -68,14 +68,21 @@ this.clumpSize = clumpSize; this.totalBlock = totalBlock; this.extents = new ExtentDescriptor[8]; + for (int i = 0; i < extents.length; i++) { + extents[i] = new ExtentDescriptor(); + } } - - public byte[] getBytes() { + + public byte[] write(byte[] dest, int destOffSet){ byte[] data = new byte[FORK_DATA_LENGTH]; BigEndian.setInt64(data, 0, totalSize); BigEndian.setInt32(data, 8, clumpSize); BigEndian.setInt32(data, 12, totalBlock); - return data; + for (int i = 0; i < extents.length; i++) { + extents[i].write(data, EXTENT_OFFSET + (i * ExtentDescriptor.EXTENT_DESCRIPTOR_LENGTH)); + } + System.arraycopy(data, 0, dest, destOffSet, FORK_DATA_LENGTH); + return dest; } /* Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -284,4 +284,9 @@ public int getExtentNodeSize() { return extentNodeSize; } + + public int getInitializeNumRecords(){ + return journaled ? 6 : 2; + } + } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -62,7 +62,6 @@ */ public final void read() throws FileSystemException { sb = new Superblock(this, false); - if (!sb.isAttribute(Superblock.HFSPLUS_VOL_UNMNT_BIT)) { log .info(getDevice().getId() @@ -100,11 +99,12 @@ @Override protected final HFSPlusEntry createRootEntry() throws IOException { + log.info("Create root entry."); LeafRecord record = catalog.getRecord(CatalogNodeId.HFSPLUS_POR_CNID); if (record != null) { return new HFSPlusEntry(this, null, "/", record); } - log.debug("Root entry : No record found."); + log.error("Root entry : No record found."); return null; } @@ -155,6 +155,7 @@ params.initializeDefaultsValues(this.getApi().getLength(), this .getFSApi().getSectorSize()); sb.create(params); + log.debug(sb.toString()); // --- long volumeBlockUsed = sb.getTotalBlocks() - sb.getFreeBlocks() - ((sb.getBlockSize() == 512) ? 2 : 1); @@ -163,7 +164,7 @@ writeAllocationFile((int) volumeBlockUsed); // --- log.debug("Write Catalog to disk."); - long offset = sb.getCatalogFile().getExtent(0).getStartBlock() * sb.getBlockSize(); + long offset = sb.getCatalogFile().getExtent(0).getStartOffset(sb.getBlockSize()); Catalog catalog = new Catalog(params); this.getApi().write(offset, catalog.getBytes()); log.debug("Write volume header to disk."); Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -79,6 +79,7 @@ data = new byte[SUPERBLOCK_LENGTH]; try { if (!create) { + log.info("load HFS+ volume header."); // skip the first 1024 bytes (boot sector) and read the volume // header. ByteBuffer b = ByteBuffer.allocate(SUPERBLOCK_LENGTH); @@ -89,6 +90,7 @@ throw new FileSystemException("Not hfs+ volume header (" + getMagic() + ": bad magic)"); } + log.debug(this.toString()); } } catch (IOException e) { throw new FileSystemException(e); @@ -100,10 +102,13 @@ * * @param params * + * @throws IOException * @throws ApiNotFoundException + * @throws FileSystemException */ public void create(HFSPlusParams params) throws IOException, ApiNotFoundException, FileSystemException { + log.info("Create new HFS+ volume header (" + params.getVolumeName() + ") with block size of " + params.getBlockSize() + " bytes."); int burnedBlocksBeforeVH = 0; int burnedBlocksAfterAltVH = 0; /* @@ -117,7 +122,6 @@ } else if (blockSize == 1024) { burnedBlocksBeforeVH = 1; } - // Populate volume header. this.setMagic(HFSPLUS_SUPER_MAGIC); this.setVersion(HFSPLUS_MIN_VERSION); @@ -126,7 +130,7 @@ this.setLastMountedVersion(0x446534a); Calendar now = Calendar.getInstance(); now.setTime(new Date()); - int macDate = (int) HFSUtils.getDate(now.getTimeInMillis() / 1000, true); + int macDate = HFSUtils.getNow(); this.setCreateDate(macDate); this.setModifyDate(macDate); this.setBackupDate(0); @@ -141,51 +145,48 @@ this.setDataClumpSize(params.getDataClumpSize()); this.setNextCatalogId(CatalogNodeId.HFSPLUS_FIRSTUSER_CNID.getId()); // Allocation file creation + log.info("Init allocation file."); long allocationClumpSize = getClumpSize(params.getBlockCount()); long bitmapBlocks = allocationClumpSize / blockSize; long blockUsed = 2 + burnedBlocksBeforeVH + burnedBlocksAfterAltVH + bitmapBlocks; - int startBlock = 1 + burnedBlocksBeforeVH; int blockCount = (int) bitmapBlocks; - HFSPlusForkData forkdata = new HFSPlusForkData(allocationClumpSize, (int) allocationClumpSize, (int) bitmapBlocks); ExtentDescriptor desc = new ExtentDescriptor(startBlock, blockCount); forkdata.addDescriptor(0, desc); - System.arraycopy(forkdata.getBytes(), 0, data, 112, HFSPlusForkData.FORK_DATA_LENGTH); + forkdata.write(data, 112); // Journal creation int nextBlock = 0; if (params.isJournaled()) { this.setFileCount(2); this.setAttribute(HFSPLUS_VOL_JOURNALED_BIT); this.setNextCatalogId(this.getNextCatalogId() + 2); - this.setJournalInfoBlock(desc.getStartBlock() + desc.getBlockCount()); + this.setJournalInfoBlock(desc.getNext()); blockUsed = blockUsed + 1 + (params.getJournalSize() / blockSize); } else { this.setJournalInfoBlock(0); - nextBlock = desc.getStartBlock() + desc.getBlockCount(); + nextBlock = desc.getNext(); } // Extent B-Tree initialization + log.info("Init extent file."); forkdata = new HFSPlusForkData(params.getExtentClumpSize(), params.getExtentClumpSize(), (params.getExtentClumpSize() / blockSize)); desc = new ExtentDescriptor(nextBlock, forkdata.getTotalBlocks()); forkdata.addDescriptor(0, desc); - System.arraycopy(forkdata.getBytes(), 0, data, 192, HFSPlusForkData.FORK_DATA_LENGTH); + forkdata.write(data, 192); blockUsed += forkdata.getTotalBlocks(); + nextBlock = desc.getNext(); // Catalog B-Tree initialization - forkdata = - new HFSPlusForkData(params.getCatalogClumpSize(), params.getCatalogClumpSize(), - (params.getCatalogClumpSize() / blockSize)); - startBlock = - this.getExtentsFile().getExtent(0).getStartBlock() + - this.getExtentsFile().getExtent(0).getBlockCount(); - blockCount = forkdata.getTotalBlocks(); - desc = new ExtentDescriptor(startBlock, blockCount); + log.info("Init catalog file."); + int totalBlocks = params.getCatalogClumpSize() / blockSize; + forkdata = new HFSPlusForkData(params.getCatalogClumpSize(), params.getCatalogClumpSize(), totalBlocks); + desc = new ExtentDescriptor(nextBlock, totalBlocks); forkdata.addDescriptor(0, desc); - System.arraycopy(forkdata.getBytes(), 0, data, 272, HFSPlusForkData.FORK_DATA_LENGTH); - blockUsed += forkdata.getTotalBlocks(); + forkdata.write(data, 272); + blockUsed += totalBlocks; this.setFreeBlocks(this.getFreeBlocks() - (int) blockUsed); this.setNextAllocation((int) blockUsed - 1 - burnedBlocksAfterAltVH + 10 * Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/catalog/Catalog.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/catalog/Catalog.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/catalog/Catalog.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -61,12 +61,12 @@ * @throws IOException */ public Catalog(final HfsPlusFileSystem fs) throws IOException { - log.debug("Load B-Tree catalog file.\n"); + log.info("Load B-Tree catalog file."); this.fs = fs; Superblock sb = fs.getVolumeHeader(); ExtentDescriptor firstExtent = sb.getCatalogFile().getExtent(0); - catalogHeaderNodeOffset = firstExtent.getStartBlock() * sb.getBlockSize(); - if (firstExtent.getStartBlock() != 0 && firstExtent.getBlockCount() != 0) { + catalogHeaderNodeOffset = firstExtent.getSize(sb.getBlockSize()); + if (!firstExtent.isEmpty()) { buffer = ByteBuffer.allocate(NodeDescriptor.BT_HEADER_NODE + BTHeaderRecord.BT_HEADER_RECORD_LENGTH); @@ -74,7 +74,7 @@ buffer.rewind(); byte[] data = ByteBufferUtils.toArray(buffer); btnd = new NodeDescriptor(data, 0); - bthr = new BTHeaderRecord(data, BTHeaderRecord.BT_HEADER_RECORD_LENGTH); + bthr = new BTHeaderRecord(data, NodeDescriptor.BT_HEADER_NODE); } } @@ -85,28 +85,34 @@ * @param params */ public Catalog(HFSPlusParams params) { - log.debug("Create B-Tree catalog file.\n"); - + log.info("Create B-Tree catalog file."); int nodeSize = params.getCatalogNodeSize(); - int bufferLength = 0; btnd = new NodeDescriptor(0, 0, NodeDescriptor.BT_HEADER_NODE, 0, 3); bufferLength += NodeDescriptor.BT_HEADER_NODE; // - int leafRecords = params.isJournaled() ? 6 : 2; int totalNodes = params.getCatalogClumpSize() / params.getCatalogNodeSize(); int freeNodes = totalNodes - 2; - bthr = - new BTHeaderRecord(1, 1, leafRecords, 1, 1, nodeSize, 0, totalNodes, freeNodes, - params.getCatalogClumpSize(), 0, 0, 0); + bthr = new BTHeaderRecord(1, + 1, + params.getInitializeNumRecords(), + 1, + 1, + nodeSize, + CatalogKey.MAXIMUM_KEY_LENGTH, + totalNodes, + freeNodes, + params.getCatalogClumpSize(), + BTHeaderRecord.BT_TYPE_HFS, + BTHeaderRecord.KEY_COMPARE_TYPE_CASE_FOLDING, + BTHeaderRecord.BT_VARIABLE_INDEX_KEYS_MASK + BTHeaderRecord.BT_BIG_KEYS_MASK); bufferLength += BTHeaderRecord.BT_HEADER_RECORD_LENGTH; // Create root node int rootNodePosition = bthr.getRootNode() * nodeSize; bufferLength += (rootNodePosition - bufferLength); // Create node descriptor - int numRecords = params.isJournaled() ? 6 : 2; - NodeDescriptor nd = new NodeDescriptor(0, 0, NodeDescriptor.BT_LEAF_NODE, 1, numRecords); + NodeDescriptor nd = new NodeDescriptor(0, 0, NodeDescriptor.BT_LEAF_NODE, 1, params.getInitializeNumRecords()); CatalogNode rootNode = new CatalogNode(nd, nodeSize); int offset = NodeDescriptor.BT_HEADER_NODE; // First record (folder) @@ -140,7 +146,7 @@ public final LeafRecord getRecord(final CatalogNodeId parentID) throws IOException { int currentOffset = 0; LeafRecord lr = null; - int nodeSize = getBTHeaderRecord().getNodeSize(); + int nodeSize = bthr.getNodeSize(); ByteBuffer nodeData = ByteBuffer.allocate(nodeSize); fs.getApi().read(catalogHeaderNodeOffset + (getBTHeaderRecord().getRootNode() * nodeSize), nodeData); Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/Extent.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/Extent.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/Extent.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -20,22 +20,26 @@ package org.jnode.fs.hfsplus.extent; +import org.apache.log4j.Logger; import org.jnode.fs.hfsplus.HFSPlusParams; import org.jnode.fs.hfsplus.tree.BTHeaderRecord; import org.jnode.fs.hfsplus.tree.NodeDescriptor; public class Extent { + private final Logger log = Logger.getLogger(getClass()); + private NodeDescriptor btnd; private BTHeaderRecord bthr; public Extent(HFSPlusParams params) { + log.info("Create B-Tree extent file."); btnd = new NodeDescriptor(0, 0, NodeDescriptor.BT_HEADER_NODE, 0, 3); // int totalNodes = params.getExtentClumpSize() / params.getExtentNodeSize(); int freeNodes = totalNodes - 1; bthr = - new BTHeaderRecord(0, 0, 0, 0, 0, params.getExtentNodeSize(), ExtentKey.KEY_LENGTH, - totalNodes, freeNodes, params.getExtentClumpSize(), 0, 0, 0); + new BTHeaderRecord(0, 0, 0, 0, 0, params.getExtentNodeSize(), ExtentKey.MAXIMUM_KEY_LENGTH, + totalNodes, freeNodes, params.getExtentClumpSize(),BTHeaderRecord.BT_TYPE_HFS, BTHeaderRecord.KEY_COMPARE_TYPE_CASE_FOLDING, BTHeaderRecord.BT_BIG_KEYS_MASK); } } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentDescriptor.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentDescriptor.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentDescriptor.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -29,6 +29,11 @@ private int startBlock; /** The length in allocation blocks of the extent. */ private int blockCount; + + public ExtentDescriptor() { + this.startBlock = 0; + this.blockCount = 0; + } /** * Create a new extent descriptor. @@ -64,19 +69,49 @@ BigEndian.setInt32(data, 4, blockCount); return data; } + + public byte[] write(byte[] dest, int destOffSet){ + byte[] data = new byte[EXTENT_DESCRIPTOR_LENGTH]; + BigEndian.setInt32(data, 0, startBlock); + BigEndian.setInt32(data, 4, blockCount); + System.arraycopy(data, 0, dest, destOffSet, EXTENT_DESCRIPTOR_LENGTH); + return dest; + } public final String toString() { return "Start block : " + startBlock + "\tBlock count : " + blockCount + "\n"; } - - public int getStartBlock() { - return startBlock; + + /** + * Returns start position in bytes of the extent. + * @param nodeSize the size of a node. + * @return offset of the extent. + */ + public int getStartOffset(int nodeSize){ + return startBlock * nodeSize; } - - public int getBlockCount() { - return blockCount; + + /** + * Returns block number of the next extent. + * @return block number of the next extent. + */ + public int getNext(){ + return startBlock + blockCount; } + + /** + * Returns size in byte of the extent. + * @param nodeSize the size of a node. + * @return size of the extent. + */ + public int getSize(int nodeSize){ + return blockCount * nodeSize; + } + /** + * Returns <tt>true</tt> if the extent is empty. + * @return <tt>true</tt> if the extent is empty. + */ public boolean isEmpty() { return (startBlock == 0 || blockCount == 0); } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentKey.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentKey.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/extent/ExtentKey.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -30,6 +30,7 @@ public static final byte DATA_FORK = (byte) 0x00; public static final byte RESOURCE_FORK = (byte) 0xFF; public static final int KEY_LENGTH = 12; + public static final int MAXIMUM_KEY_LENGTH = 10; private int forkType; private int pad; Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/tree/BTHeaderRecord.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/tree/BTHeaderRecord.java 2009-03-19 14:10:46 UTC (rev 5117) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/tree/BTHeaderRecord.java 2009-03-19 16:23:45 UTC (rev 5118) @@ -23,6 +23,17 @@ import org.jnode.util.BigEndian; public class BTHeaderRecord { + + public static final int KEY_COMPARE_TYPE_CASE_FOLDING = 0xCF; + /** B-Tree was not closed correctly and need check for consistency. */ + public static final int BT_BAD_CLOSE_MASK = 0x00000001; + public static final int BT_BIG_KEYS_MASK = 0x00000002; + public static final int BT_VARIABLE_INDEX_KEYS_MASK = 0x00000004; + + public static final int BT_TYPE_HFS = 0; + public static final int BT_TYPE_USER = 128; + public static final int BT_TYPE_RESERVED = 256; + public static final int BT_HEADER_RECORD_LENGTH = 106; /** The depth of the current B-Tree. */ private int treeDepth; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |