From: <ga...@us...> - 2009-01-09 13:43:30
|
Revision: 4838 http://jnode.svn.sourceforge.net/jnode/?rev=4838&view=rev Author: galatnm Date: 2009-01-09 13:43:21 +0000 (Fri, 09 Jan 2009) Log Message: ----------- Complete HFSPlusParams. Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusConstants.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/command/FormatHfsPlusCommand.java Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java 2009-01-09 12:27:13 UTC (rev 4837) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HFSPlusParams.java 2009-01-09 13:43:21 UTC (rev 4838) @@ -1,33 +1,260 @@ package org.jnode.fs.hfsplus; +import org.jnode.fs.FileSystemException; + public class HFSPlusParams { + + public static final int MINIMAL_BLOCK_SIZE = 512; + public static final int DEFAULT_BLOCK_SIZE = 4096; + public static final int OPTIMAL_BLOCK_SIZE = 4096; + public static final int DATA_CLUMP_FACTOR = 16; + public static final int RESOURCE_CLUMP_FACTOR = 16; + public static final int DEFAULT_JOURNAL_SIZE = 8 * 1024 * 1024; + public static final int DEFAULT_CATALOG_NODE_SIZE = 8192; + public static final int DEFAULT_EXTENT_NODE_SIZE = 4096; + public static final int DEFAULT_ATTRIBUTE_NODE_SIZE = 4096; + + private long blockDeviceSize; + private String volumeName; private int blockSize; + private int resourceClumpBlocks; + private int dataClumpBlocks; + private int catalogClumpBlocks; + private int extentClumpBlocks; + private int attributeClumpBlocks; + private int bitmapClumpBlocks; private boolean journaled; private int journalSize; + + private int resourceClumpSize; + private int dataClumpSize; + private int catalogClumpSize; + private int catalogNodeSize; + private int extentClumpSize; + private int extentNodeSize; + private int attributeClumpSize; + private int attributeNodeSize; + private int allocationClumpSize; + + /** + * Default constructor. + */ + public HFSPlusParams() { + this.catalogNodeSize = DEFAULT_CATALOG_NODE_SIZE; + this.extentNodeSize = DEFAULT_EXTENT_NODE_SIZE; + } + + /** + * + * @param blockDeviceSize + * @param sectorSize + * + * @throws FileSystemException + * + */ + public void initializeDefaultsValues(long blockDeviceSize, long sectorSize) + throws FileSystemException { + long clumpSize = 0; + this.blockDeviceSize = blockDeviceSize; + if (resourceClumpBlocks == 0) { + if (blockSize > DEFAULT_BLOCK_SIZE) { + clumpSize = round(RESOURCE_CLUMP_FACTOR * DEFAULT_BLOCK_SIZE, blockSize); + } else { + clumpSize = RESOURCE_CLUMP_FACTOR * blockSize; + } + } else { + clumpSize = clumpSizeCalculation(resourceClumpBlocks); + } + resourceClumpSize = (int) clumpSize; + if (dataClumpBlocks == 0) { + if (blockSize > DEFAULT_BLOCK_SIZE) { + clumpSize = round(DATA_CLUMP_FACTOR * DEFAULT_BLOCK_SIZE, blockSize); + } else { + clumpSize = DATA_CLUMP_FACTOR * blockSize; + } + } else { + clumpSize = clumpSizeCalculation(dataClumpBlocks); + } + + if (blockSize < OPTIMAL_BLOCK_SIZE || blockDeviceSize < 0x40000000) { + catalogNodeSize = 4096; + } + long sectorCount = blockDeviceSize / sectorSize; + if (catalogClumpBlocks == 0) { + clumpSize = getBTreeClumpSize(blockSize, catalogNodeSize, + sectorCount, true); + } else { + clumpSize = clumpSizeCalculation(catalogClumpBlocks); + if (clumpSize % catalogNodeSize != 0) { + throw new FileSystemException( + "clump size is not a multiple of node size"); + } + } + catalogClumpSize = (int) clumpSize; + if (extentClumpBlocks == 0) { + clumpSize = getBTreeClumpSize(blockSize, extentNodeSize, + sectorCount, false); + } else { + clumpSize = clumpSizeCalculation(extentClumpBlocks); + } + extentClumpSize = (int) clumpSize; + + if(attributeClumpBlocks == 0){ + clumpSize = 0; + } else { + clumpSize = clumpSizeCalculation(attributeClumpBlocks); + if(clumpSize % attributeNodeSize != 0){ + throw new FileSystemException("clump size is not a multiple of attribute node size"); + } + } + attributeClumpSize = (int)clumpSize; + + long totalBlocks = this.getBlockCount(); + long minClumpSize = this.getBlockCount() >> 3; + if ((totalBlocks & 7) == 0) { + ++minClumpSize; + } + if(bitmapClumpBlocks == 0){ + clumpSize = minClumpSize; + } else { + clumpSize = clumpSizeCalculation(bitmapClumpBlocks); + if(clumpSize < minClumpSize){ + throw new FileSystemException("bitmap clump size is too small."); + } + } + allocationClumpSize = (int)clumpSize; + + } + + private int[] extentClumpTable = new int[] { 4, 4, 4, 5, 5, 6, 7, 8, 9, 11, + 14, 16, 20, 25, 32 }; + private int[] catalogClumpTable = new int[] { 4, 6, 8, 11, 14, 19, 25, 34, + 45, 60, 80, 107, 144, 192, 256 }; + + /** + * + * @param blockSize + * @param nodeSize + * @param sectors + * @param catalog + * @return + */ + private long getBTreeClumpSize(int blockSize, int nodeSize, long sectors, + boolean catalog) { + long clumpSize = 0; + if (sectors < 0x200000) { + clumpSize = (sectors << 2); + if (clumpSize < (8 * nodeSize)) { + clumpSize = (8 * nodeSize); + } + } else { + sectors = sectors >> 22; + for (int i = 0; sectors != 0 && (i < 14); ++i) { + if (catalog) { + clumpSize = catalogClumpTable[i] * 1024 * 1024; + } else { + clumpSize = extentClumpTable[i] * 1024 * 1024; + } + sectors = sectors >> 1; + } + } + + return clumpSize; + } + + /** + * + * @param clumpBlocks + * + * @return + */ + private int clumpSizeCalculation(long clumpBlocks) throws FileSystemException { + long clumpSize = clumpBlocks * blockSize; + if ((clumpSize & 0XFFFFFFFF00000000L) == 0) { + throw new FileSystemException("Too many blocks (" + clumpBlocks + ") for clump size (" + clumpSize +")."); + } + return (int) clumpSize; + } + private long round(long x, long y){ + return (((x+y)-1)/y*y); + } + public String getVolumeName() { return volumeName; } + public void setVolumeName(String volumeName) { this.volumeName = volumeName; } + public int getBlockSize() { return blockSize; } + public void setBlockSize(int blockSize) { this.blockSize = blockSize; } + public boolean isJournaled() { return journaled; } + public void setJournaled(boolean journaled) { this.journaled = journaled; } + public int getJournalSize() { return journalSize; } + public void setJournalSize(int journalSize) { this.journalSize = journalSize; } + + public int getCatalogNodeSize() { + + return catalogNodeSize; + } + + public long getBlockCount() { + return blockDeviceSize / blockSize; + } + + public int getCatalogClumpSize() { + return catalogClumpSize; + } + + public int getExtentClumpSize() { + return extentClumpSize; + } + + public int getResourceClumpSize() { + return resourceClumpSize; + } + + public int getDataClumpSize() { + return dataClumpSize; + } + + public int getAttributeClumpSize() { + return attributeClumpSize; + } + + public int getAttributeNodeSize() { + return attributeNodeSize; + } + + public void setAttributeClumpBlocks(int attributeClumpBlocks) { + this.attributeClumpBlocks = attributeClumpBlocks; + } + + public int getAllocationClumpSize() { + return allocationClumpSize; + } + + public void setBitmapClumpBlocks(int bitmapClumpBlocks) { + this.bitmapClumpBlocks = bitmapClumpBlocks; + } } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusConstants.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusConstants.java 2009-01-09 12:27:13 UTC (rev 4837) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusConstants.java 2009-01-09 13:43:21 UTC (rev 4838) @@ -33,12 +33,6 @@ public static final byte EK_DATA_FORK = (byte) 0x00; public static final byte EK_RESOURCE_FORK = (byte) 0xFF; - public static final int MINIMAL_BLOCK_SIZE = 512; - public static final int OPTIMAL_BLOCK_SIZE = 4096; - - public static final int DATA_CLUMP_FACTOR = 16; - public static final int RESOURCE_CLUMP_FACTOR = 16; - public static final int DEFAULT_JOURNAL_SIZE = 8 * 1024 * 1024; } Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java 2009-01-09 12:27:13 UTC (rev 4837) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/HfsPlusFileSystem.java 2009-01-09 13:43:21 UTC (rev 4838) @@ -109,11 +109,14 @@ /** * + * @param params + * * @throws FileSystemException */ public void create(HFSPlusParams params) throws FileSystemException { sb = new Superblock(this, true); try { + params.initializeDefaultsValues(this.getApi().getLength(), this.getFSApi().getSectorSize()); sb.create(params); this.getApi().write(1024, ByteBuffer.wrap(sb.getBytes())); flush(); Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java 2009-01-09 12:27:13 UTC (rev 4837) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/Superblock.java 2009-01-09 13:43:21 UTC (rev 4838) @@ -87,12 +87,7 @@ } else if (blockSize == 1024) { burnedBlocksBeforeVH = 1; } - long size = fs.getApi().getLength(); - long sectorCount = size / fs.getFSApi().getSectorSize(); - long blocks = size / blockSize; - long allocationClumpSize = getClumpSize(blocks); - long bitmapBlocks = allocationClumpSize / blockSize; - long blockUsed = 2 + burnedBlocksBeforeVH + burnedBlocksAfterAltVH + bitmapBlocks; + // Populate volume header. this.setMagic(HfsPlusConstants.HFSPLUS_SUPER_MAGIC); this.setVersion(HfsPlusConstants.HFSPLUS_MIN_VERSION); @@ -110,16 +105,27 @@ this.setFileCount(0); this.setFolderCount(0); this.setBlockSize(blockSize); - this.setTotalBlocks((int) blocks); - this.setFreeBlocks((int) blocks); - this.setRsrcClumpSize(HfsPlusConstants.RESOURCE_CLUMP_FACTOR * blockSize); - this.setDataClumpSize(HfsPlusConstants.DATA_CLUMP_FACTOR * blockSize); + this.setTotalBlocks((int) params.getBlockCount()); + this.setFreeBlocks((int) params.getBlockCount()); + this.setRsrcClumpSize(params.getResourceClumpSize()); + this.setDataClumpSize(params.getDataClumpSize()); this.setNextCatalogId(CatalogNodeId.HFSPLUS_FIRSTUSER_CNID.getId()); // Allocation file creation - initAllocationFile((int) allocationClumpSize, (int) bitmapBlocks, burnedBlocksBeforeVH); - int nextBlock = 0; + long allocationClumpSize = getClumpSize(params.getBlockCount()); + long bitmapBlocks = allocationClumpSize / blockSize; + long blockUsed = 2 + burnedBlocksBeforeVH + burnedBlocksAfterAltVH + bitmapBlocks; + HFSPlusForkData forkdata = new HFSPlusForkData(); + forkdata.setTotalSize(allocationClumpSize); + forkdata.setClumpSize((int)allocationClumpSize); + forkdata.setTotalBlocks((int)bitmapBlocks); + ExtentDescriptor desc = new ExtentDescriptor(); + desc.setStartBlock(1 + burnedBlocksBeforeVH); + desc.setBlockCount(0); + forkdata.setExtentDescriptor(0, desc); + System.arraycopy(forkdata.getBytes(), 0, data, 112, forkdata.FORK_DATA_LENGTH); // Journal creation - ExtentDescriptor desc = this.getAllocationFile().getExtents()[0]; + int nextBlock = 0; + if (params.isJournaled()) { this.setFileCount(2); this.setAttribute(HFSPLUS_VOL_JOURNALED_BIT); @@ -130,103 +136,36 @@ this.setJournalInfoBlock(0); nextBlock = desc.getStartBlock() + desc.getBlockCount(); } - blockUsed += initExtents(0, blockSize, nextBlock, (int) sectorCount, blockUsed); - blockUsed += initCatalog(0, blockSize, nextBlock, (int) sectorCount, blockUsed); - this.setFreeBlocks(this.getFreeBlocks() - (int) blockUsed); - this.setNextAllocation((int) blockUsed - 1 - burnedBlocksAfterAltVH + 10 - * (this.getCatalogFile().getClumpSize() / this.getBlockSize())); - } - - /** - * - * @param clumpSize - * @param bitmapBlocks - * @param burnedBlocksBeforeVH - * @return - */ - private void initAllocationFile(int clumpSize, int bitmapBlocks, int burnedBlocksBeforeVH) { - HFSPlusForkData forkdata = new HFSPlusForkData(); - forkdata.setTotalSize(clumpSize); - forkdata.setClumpSize(clumpSize); - forkdata.setTotalBlocks(bitmapBlocks); - ExtentDescriptor desc = new ExtentDescriptor(); - desc.setStartBlock(1 + burnedBlocksBeforeVH); - desc.setBlockCount(0); - forkdata.setExtentDescriptor(0, desc); - System.arraycopy(forkdata.getBytes(), 0, data, 112, forkdata.FORK_DATA_LENGTH); - } - - /** - * - * @param extentsClumpBlock - * @param blockSize - * @param nextBlock - * @return - */ - private long initExtents(int extentsClumpBlock, int blockSize, int nextBlock, int sectorCount, long blockUsed) { - int extentNodeSize = 4096; - long clumpSize = 0; - if (extentsClumpBlock == 0) { - clumpSize = getBTreeClumpSize(blockSize, extentNodeSize, sectorCount, false); - } else { - clumpSize = clumpSizeCalculation(extentsClumpBlock, blockSize); - } - HFSPlusForkData forkdata = new HFSPlusForkData(); - forkdata.setTotalSize(clumpSize); - forkdata.setClumpSize((int) clumpSize); - forkdata.setTotalBlocks((int) (clumpSize / blockSize)); - ExtentDescriptor desc = new ExtentDescriptor(); + // Extent B-Tree initialization + forkdata = new HFSPlusForkData(); + forkdata.setTotalSize(params.getExtentClumpSize()); + forkdata.setClumpSize(params.getExtentClumpSize()); + forkdata.setTotalBlocks((params.getExtentClumpSize() / blockSize)); + desc = new ExtentDescriptor(); desc.setStartBlock(nextBlock); desc.setBlockCount(forkdata.getTotalBlocks()); forkdata.setExtentDescriptor(0, desc); System.arraycopy(forkdata.getBytes(), 0, data, 192, forkdata.FORK_DATA_LENGTH); - return blockUsed + forkdata.getTotalBlocks(); + blockUsed += forkdata.getTotalBlocks(); + // Catalog B-Tree initialization + forkdata = new HFSPlusForkData(); + forkdata.setTotalSize(params.getCatalogClumpSize()); + forkdata.setClumpSize(params.getCatalogClumpSize()); + forkdata.setTotalBlocks(params.getCatalogClumpSize() / blockSize); + desc = new ExtentDescriptor(); + desc.setStartBlock(this.getExtentsFile().getExtents()[0].getStartBlock() + + this.getExtentsFile().getExtents()[0].getBlockCount()); + desc.setBlockCount(forkdata.getTotalBlocks()); + forkdata.setExtentDescriptor(0, desc); + System.arraycopy(forkdata.getBytes(), 0, data, 272, forkdata.FORK_DATA_LENGTH); + blockUsed += forkdata.getTotalBlocks(); + + this.setFreeBlocks(this.getFreeBlocks() - (int) blockUsed); + this.setNextAllocation((int) blockUsed - 1 - burnedBlocksAfterAltVH + 10 + * (this.getCatalogFile().getClumpSize() / this.getBlockSize())); } - + /** - * - * @param extentsClumpBlock - * @param blockSize - * @param nextBlock - * @param sectorCount - * @param blockUsed - * @return - * @throws IOException - */ - private long initCatalog(int catalogClumpBlock, int blockSize, int nextBlock, int sectorCount, long blockUsed) - throws FileSystemException { - int catalogNodeSize = 8192; - try { - if (blockSize < HfsPlusConstants.OPTIMAL_BLOCK_SIZE || fs.getApi().getLength() < 0x40000000) { - catalogNodeSize = 4096; - } - long clumpSize = 0; - if (catalogClumpBlock == 0) { - clumpSize = getBTreeClumpSize(blockSize, catalogNodeSize, sectorCount, true); - } else { - clumpSize = clumpSizeCalculation(catalogClumpBlock, blockSize); - if (clumpSize % catalogNodeSize != 0) { - throw new FileSystemException("clump size is not a multiple of node size"); - } - } - - HFSPlusForkData forkdata = new HFSPlusForkData(); - forkdata.setTotalSize(clumpSize); - forkdata.setClumpSize((int) clumpSize); - forkdata.setTotalBlocks((int) (clumpSize / blockSize)); - ExtentDescriptor desc = new ExtentDescriptor(); - desc.setStartBlock(this.getExtentsFile().getExtents()[0].getStartBlock() - + this.getExtentsFile().getExtents()[0].getBlockCount()); - desc.setBlockCount(forkdata.getTotalBlocks()); - forkdata.setExtentDescriptor(0, desc); - System.arraycopy(forkdata.getBytes(), 0, data, 272, forkdata.FORK_DATA_LENGTH); - return blockUsed + forkdata.getTotalBlocks(); - } catch (IOException e) { - throw new FileSystemException(e); - } - } - - /** * Calculate the number of blocks needed for bitmap. * * @param totalBlocks @@ -246,48 +185,6 @@ return clumpSize; } - /** - * - * @param blockSize - * @param nodeSize - * @param sectors - * @param catalog - * @return - */ - - private int[] extentClumpTable = new int[] {4, 4, 4, 5, 5, 6, 7, 8, 9, 11, 14, 16, 20, 25, 32 }; - private int[] catalogClumpTable = new int[] {4, 6, 8, 11, 14, 19, 25, 34, 45, 60, 80, 107, 144, 192, 256 }; - - private long getBTreeClumpSize(int blockSize, int nodeSize, long sectors, boolean catalog) { - long clumpSize = 0; - if (sectors < 0x200000) { - clumpSize = (sectors << 2); - if (clumpSize < (8 * nodeSize)) { - clumpSize = (8 * nodeSize); - } - } else { - sectors = sectors >> 22; - for (int i = 0; sectors != 0 && (i < 14); ++i) { - if (catalog) { - clumpSize = catalogClumpTable[i] * 1024 * 1024; - } else { - clumpSize = extentClumpTable[i] * 1024 * 1024; - } - sectors = sectors >> 1; - } - } - - return clumpSize; - } - - private int clumpSizeCalculation(long clumpBlocks, int blockSize) { - long clumpSize = clumpBlocks * blockSize; - if ((clumpSize & 0XFFFFFFFF00000000L) == 0) { - // ERROR - } - return (int) clumpSize; - } - // Getters/setters public final int getMagic() { Modified: trunk/fs/src/fs/org/jnode/fs/hfsplus/command/FormatHfsPlusCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/hfsplus/command/FormatHfsPlusCommand.java 2009-01-09 12:27:13 UTC (rev 4837) +++ trunk/fs/src/fs/org/jnode/fs/hfsplus/command/FormatHfsPlusCommand.java 2009-01-09 13:43:21 UTC (rev 4838) @@ -27,9 +27,9 @@ protected Formatter<HfsPlusFileSystem> getFormatter() { HFSPlusParams params = new HFSPlusParams(); params.setVolumeName(ARG_VOLUME_NAME.getValue()); - params.setBlockSize(HfsPlusConstants.OPTIMAL_BLOCK_SIZE); + params.setBlockSize(params.OPTIMAL_BLOCK_SIZE); params.setJournaled(false); - params.setJournalSize(HfsPlusConstants.DEFAULT_JOURNAL_SIZE); + params.setJournalSize(params.DEFAULT_JOURNAL_SIZE); return new HfsPlusFileSystemFormatter(params); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |