From: <ga...@us...> - 2012-08-10 06:29:28
|
Revision: 5908 http://jnode.svn.sourceforge.net/jnode/?rev=5908&view=rev Author: galatnm Date: 2012-08-10 06:29:21 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Add support to detect Ext4 features. Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java 2012-08-10 06:19:44 UTC (rev 5907) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java 2012-08-10 06:29:21 UTC (rev 5908) @@ -93,6 +93,10 @@ public static final long EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x0001; public static final long EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x0002; public static final long EXT2_FEATURE_RO_COMPAT_BTREE_DIR = 0x0004; + public static final long EXT4_FEATURE_ROCOMPAT_HUGE_FILE = 0x0008; + public static final long EXT4_FEATURE_ROCOMPAT_GDT_CSUM = 0x0010; + public static final long EXT4_FEATURE_ROCOMPAT_DIR_NLINK = 0x0020; + public static final long EXT4_FEATURE_ROCOMPAT_EXTRA_ISIZE = 0x0040; // S_FEATURE_INCOMPAT constants public static final long EXT2_FEATURE_INCOMPAT_COMPRESSION = 0x0001; @@ -100,6 +104,10 @@ public static final long EXT3_FEATURE_INCOMPAT_RECOVER = 0x0004; public static final long EXT3_FEATURE_INCOMPAT_JOURNAL_DEV = 0x0008; public static final long EXT2_FEATURE_INCOMPAT_META_BG = 0x0010; + public static final long EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040; + public static final long EXT4_FEATURE_INCOMPAT_64BIT = 0x0080; + public static final long EXT4_FEATURE_INCOMPAT_MMP = 0x0100; + public static final long EXT4_FEATURE_INCOMPAT_FLEX_BG = 0X0200; // constants specific to this (JNode) implementation /** Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java 2012-08-10 06:19:44 UTC (rev 5907) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java 2012-08-10 06:29:21 UTC (rev 5908) @@ -24,7 +24,6 @@ import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.Date; - import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.driver.Device; @@ -119,16 +118,28 @@ // at all) if (hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_COMPRESSION)) throw new FileSystemException(getDevice().getId() + - " Unsupported filesystem feature (COMPRESSION) disallows mounting"); + " Unsupported filesystem feature (COMPRESSION) disallows mounting"); if (hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_META_BG)) throw new FileSystemException(getDevice().getId() + - " Unsupported filesystem feature (META_BG) disallows mounting"); + " Unsupported filesystem feature (META_BG) disallows mounting"); if (hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) throw new FileSystemException(getDevice().getId() + - " Unsupported filesystem feature (JOURNAL_DEV) disallows mounting"); - if (hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_RECOVER)) + " Unsupported filesystem feature (JOURNAL_DEV) disallows mounting"); +// if (hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_RECOVER)) +// throw new FileSystemException(getDevice().getId() + +// " Unsupported filesystem feature (RECOVER) disallows mounting"); +// if (hasIncompatFeature(Ext2Constants.EXT4_FEATURE_INCOMPAT_EXTENTS)) +// throw new FileSystemException(getDevice().getId() + +// " Unsupported filesystem feature (EXTENTS) disallows mounting"); + if (hasIncompatFeature(Ext2Constants.EXT4_FEATURE_INCOMPAT_64BIT)) throw new FileSystemException(getDevice().getId() + - " Unsupported filesystem feature (RECOVER) disallows mounting"); + " Unsupported filesystem feature (64BIT) disallows mounting"); + if (hasIncompatFeature(Ext2Constants.EXT4_FEATURE_INCOMPAT_MMP)) + throw new FileSystemException(getDevice().getId() + + " Unsupported filesystem feature (MMP) disallows mounting"); + if (hasIncompatFeature(Ext2Constants.EXT4_FEATURE_INCOMPAT_FLEX_BG)) + throw new FileSystemException(getDevice().getId() + + " Unsupported filesystem feature (FLEX_BG) disallows mounting"); // an unsupported RO_COMPAT feature means that the filesystem can only // be mounted readonly @@ -140,6 +151,22 @@ log.info(getDevice().getId() + " Unsupported filesystem feature (BTREE_DIR) forces readonly mode"); setReadOnly(true); } + if (hasROFeature(Ext2Constants.EXT4_FEATURE_ROCOMPAT_HUGE_FILE)) { + log.info(getDevice().getId() + " Unsupported filesystem feature (HUGE_FILE) forces readonly mode"); + setReadOnly(true); + } + if (hasROFeature(Ext2Constants.EXT4_FEATURE_ROCOMPAT_GDT_CSUM)) { + log.info(getDevice().getId() + " Unsupported filesystem feature (GDT_CSUM) forces readonly mode"); + setReadOnly(true); + } + if (hasROFeature(Ext2Constants.EXT4_FEATURE_ROCOMPAT_DIR_NLINK)) { + log.info(getDevice().getId() + " Unsupported filesystem feature (DIR_NLINK) forces readonly mode"); + setReadOnly(true); + } + if (hasROFeature(Ext2Constants.EXT4_FEATURE_ROCOMPAT_EXTRA_ISIZE)) { + log.info(getDevice().getId() + " Unsupported filesystem feature (EXTRA_ISIZE) forces readonly mode"); + setReadOnly(true); + } // if the filesystem has not been cleanly unmounted, mount it readonly if (superblock.getState() == Ext2Constants.EXT2_ERROR_FS) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 06:36:13
|
Revision: 5910 http://jnode.svn.sourceforge.net/jnode/?rev=5910&view=rev Author: galatnm Date: 2012-08-10 06:36:07 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Add initial support for ext4 extents Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/INode.java Added Paths: ----------- trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java Added: trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java 2012-08-10 06:36:07 UTC (rev 5910) @@ -0,0 +1,44 @@ +package org.jnode.fs.ext2; + +/** + * An ext4 extent object. + * + * @author Luke Quinane + */ +public class Extent { + /** + * The length of an extent. + */ + public static final int EXTENT_LENGTH = 12; + + /** + * The data for the extent. + */ + private byte[] data; + + /** + * Create an extent object. + * + * @param data the data for the extent. + */ + public Extent(byte[] data) { + this.data = new byte[EXTENT_LENGTH]; + System.arraycopy(data, 0, this.data, 0, EXTENT_LENGTH); + } + + public long getBlockIndex() { + return Ext2Utils.get32(data, 0); + } + + public int getBlockCount() { + return Ext2Utils.get16(data, 4); + } + + public long getStartLow() { + return Ext2Utils.get32(data, 8); + } + + public int getStartHigh() { + return Ext2Utils.get16(data, 6); + } +} Added: trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java 2012-08-10 06:36:07 UTC (rev 5910) @@ -0,0 +1,134 @@ +package org.jnode.fs.ext2; + +import java.io.IOException; + +/** + * An ext4 extent header. + * + * @author Luke Quinane + */ +public class ExtentHeader { + /** + * The length of an extent header. + */ + public static final int EXTENT_HEADER_LENGTH = 12; + + /** + * The magic number for an extent header. + */ + public static final int MAGIC = 0xf30a; + + /** + * The data for the header. + */ + private byte[] data; + + /** + * The cache copy of the index entries. + */ + private ExtentIndex[] indexEntries; + + /** + * The cache copy of the extent entries. + */ + private Extent[] extentEntries; + + /** + * Create an extent header object. + */ + public ExtentHeader(byte[] data) throws IOException { + this.data = new byte[data.length]; + System.arraycopy(data, 0, this.data, 0, data.length); + + if (getMagic() != ExtentHeader.MAGIC) { + throw new IOException("Extent had the wrong magic: " + getMagic()); + } + } + + public int getMagic() { + return Ext2Utils.get16(data, 0); + } + + public int getEntryCount() { + return Ext2Utils.get16(data, 2); + } + + public int getMaximumEntryCount() { + return Ext2Utils.get16(data, 4); + } + + public int getDepth() { + return Ext2Utils.get16(data, 6); + } + + public ExtentIndex[] getIndexEntries() { + if (getDepth() == 0) { + throw new IllegalStateException("Trying to read index entries from a leaf."); + } + + if (indexEntries == null) { + indexEntries = new ExtentIndex[getEntryCount()]; + int offset = EXTENT_HEADER_LENGTH; + + for (int i = 0; i < getEntryCount(); i++) { + byte[] indexBuffer = new byte[ExtentIndex.EXTENT_INDEX_LENGTH]; + System.arraycopy(data, offset, indexBuffer, 0, indexBuffer.length); + + indexEntries[i] = new ExtentIndex(indexBuffer); + offset += ExtentIndex.EXTENT_INDEX_LENGTH; + } + } + + return indexEntries; + } + + public Extent[] getExtentEntries() { + if (getDepth() != 0) { + throw new IllegalStateException("Trying to read extent entries from a non-leaf."); + } + + if (extentEntries == null) { + extentEntries = new Extent[getEntryCount()]; + int offset = EXTENT_HEADER_LENGTH; + + for (int i = 0; i < getEntryCount(); i++) { + byte[] indexBuffer = new byte[Extent.EXTENT_LENGTH]; + System.arraycopy(data, offset, indexBuffer, 0, indexBuffer.length); + + extentEntries[i] = new Extent(indexBuffer); + offset += Extent.EXTENT_LENGTH; + } + } + + return extentEntries; + } + + public long getBlockNumber(long index) { + if (getDepth() > 0) { + ExtentIndex[] indexes = getIndexEntries(); + + throw new UnsupportedOperationException(); + } + else { + Extent[] extents = getExtentEntries(); + + int lowIndex = 0; + int highIndex = extents.length - 1; + Extent extent = null; + + while (lowIndex <= highIndex) { + int middle = lowIndex + (highIndex - lowIndex) / 2; + extent = extents[middle]; + + if (index < extent.getBlockIndex()) { + highIndex = middle - 1; + } + else { + lowIndex = middle + 1; + } + } + + return extent.getStartLow(); + } + } +} Added: trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java 2012-08-10 06:36:07 UTC (rev 5910) @@ -0,0 +1,40 @@ +package org.jnode.fs.ext2; + +/** + * An ext4 extent index. + * + * @author Luke Quinane + */ +public class ExtentIndex { + /** + * The length of an extent index. + */ + public static final int EXTENT_INDEX_LENGTH = 12; + + /** + * The data for the index. + */ + private byte[] data; + + /** + * Create an extent index object. + * + * @param data the data for the index. + */ + public ExtentIndex(byte[] data) { + this.data = new byte[EXTENT_INDEX_LENGTH]; + System.arraycopy(data, 0, this.data, 0, EXTENT_INDEX_LENGTH); + } + + public long getBlockIndex() { + return Ext2Utils.get32(data, 0); + } + + public long getLeafLow() { + return Ext2Utils.get32(data, 4); + } + + public int getLeafHigh() { + return Ext2Utils.get16(data, 8); + } +} Modified: trunk/fs/src/fs/org/jnode/fs/ext2/INode.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 06:32:22 UTC (rev 5909) +++ trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 06:36:07 UTC (rev 5910) @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.Arrays; - import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.fs.FileSystemException; @@ -60,6 +59,11 @@ private Ext2FileSystem fs; /** + * The cached extent header. + */ + private ExtentHeader extentHeader; + + /** * Create an INode object from an existing inode on the disk. * * @param fs @@ -280,6 +284,36 @@ * @throws IOException */ private long getDataBlockNr(long i) throws IOException { + if ((getFlags() & Ext2Constants.EXT4_INODE_EXTENTS_FLAG) != 0) { + if (extentHeader == null) { + byte[] headerBuffer = new byte[64]; + System.arraycopy(data, 40, headerBuffer, 0, headerBuffer.length); + + extentHeader = new ExtentHeader(headerBuffer); + } + + return extentHeader.getBlockNumber(i); + } + else { + return getDataBlockNrIndirect(i); + } + } + + /** + * Return the number of the block in the filesystem that stores the ith + * block of the inode (i is a sequential index from the beginning of the + * file) using an indirect (ext2 / ext3) lookup. + * + * [Naming convention used: in the code, a <code>...BlockNr</code> always + * means an absolute block nr (of the filesystem), while a + * <code>...BlockIndex</code> means an index relative to the beginning of + * a block] + * + * @param i + * @return the block number + * @throws IOException + */ + private long getDataBlockNrIndirect(long i) throws IOException { final long blockCount = getAllocatedBlockCount(); final int indirectCount = getIndirectCount(); if (i > blockCount - 1) { @@ -910,6 +944,10 @@ public void setDirty(boolean b) { dirty = b; + + if (dirty) { + extentHeader = null; + } } public synchronized boolean isLocked() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 06:37:22
|
Revision: 5911 http://jnode.svn.sourceforge.net/jnode/?rev=5911&view=rev Author: galatnm Date: 2012-08-10 06:37:15 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Detect inodes that use ext4 extents Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java 2012-08-10 06:36:07 UTC (rev 5910) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Constants.java 2012-08-10 06:37:15 UTC (rev 5911) @@ -78,6 +78,7 @@ // behaviour control flags in the inode public static final long EXT2_INDEX_FL = 0x00010000; // hash indexed directory + public static final long EXT4_INODE_EXTENTS_FLAG = 0x00080000; // Filesystem state constants public static final int EXT2_VALID_FS = 0x0001; // cleanly unmounted Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java 2012-08-10 06:36:07 UTC (rev 5910) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java 2012-08-10 06:37:15 UTC (rev 5911) @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; - import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.fs.FSEntry; @@ -56,10 +55,16 @@ this.entry = entry; log.setLevel(Level.DEBUG); boolean readOnly; - if ((iNode.getFlags() & Ext2Constants.EXT2_INDEX_FL) == 1) + if ((iNode.getFlags() & Ext2Constants.EXT2_INDEX_FL) != 0 || + (iNode.getFlags() & Ext2Constants.EXT4_INODE_EXTENTS_FLAG) != 0) { readOnly = true; //force readonly - else + + if ((iNode.getFlags() & Ext2Constants.EXT4_INODE_EXTENTS_FLAG) != 0) + log.info("inode uses extents: " + entry); + } + else { readOnly = fs.isReadOnly(); + } setRights(true, !readOnly); log.debug("directory size: " + iNode.getSize()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 06:41:42
|
Revision: 5913 http://jnode.svn.sourceforge.net/jnode/?rev=5913&view=rev Author: galatnm Date: 2012-08-10 06:41:36 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Add in support for extracting sym-link target and identify block, char, fifo and link obje Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java trunk/fs/src/fs/org/jnode/fs/ext2/INode.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java 2012-08-10 06:39:34 UTC (rev 5912) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java 2012-08-10 06:41:36 UTC (rev 5913) @@ -21,7 +21,6 @@ package org.jnode.fs.ext2; import java.io.IOException; - import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.fs.FSDirectory; @@ -97,7 +96,9 @@ return AbstractFSEntry.ROOT_ENTRY; else if (mode == Ext2Constants.EXT2_S_IFDIR) return AbstractFSEntry.DIR_ENTRY; - else if (mode == Ext2Constants.EXT2_S_IFREG || mode == Ext2Constants.EXT2_FT_SYMLINK) + else if (mode == Ext2Constants.EXT2_S_IFREG || mode == Ext2Constants.EXT2_S_IFLNK || + mode == Ext2Constants.EXT2_S_IFIFO || mode == Ext2Constants.EXT2_S_IFCHR || + mode == Ext2Constants.EXT2_S_IFBLK) return AbstractFSEntry.FILE_ENTRY; else return AbstractFSEntry.OTHER_ENTRY; Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java 2012-08-10 06:39:34 UTC (rev 5912) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java 2012-08-10 06:41:36 UTC (rev 5913) @@ -22,7 +22,6 @@ import java.io.IOException; import java.nio.ByteBuffer; - import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.fs.FileSystemException; @@ -180,20 +179,27 @@ try { if (len + off > getLength()) throw new IOException("Can't read past the file!"); - long blockSize = iNode.getExt2FileSystem().getBlockSize(); - long bytesRead = 0; - while (bytesRead < len) { - long blockNr = (fileOffset + bytesRead) / blockSize; - long blockOffset = (fileOffset + bytesRead) % blockSize; - long copyLength = Math.min(len - bytesRead, blockSize - blockOffset); - log.debug("blockNr: " + blockNr + ", blockOffset: " + blockOffset + ", copyLength: " + copyLength + - ", bytesRead: " + bytesRead); + if ((iNode.getMode() & Ext2Constants.EXT2_S_IFLNK) == Ext2Constants.EXT2_S_IFLNK) { + // Sym-links are a special case: the data seems to be stored inline in the iNode + System.arraycopy(iNode.getINodeBlockData(), 0, dest, 0, Math.min(64, dest.length)); + } + else { + long blockSize = iNode.getExt2FileSystem().getBlockSize(); + long bytesRead = 0; + while (bytesRead < len) { + long blockNr = (fileOffset + bytesRead) / blockSize; + long blockOffset = (fileOffset + bytesRead) % blockSize; + long copyLength = Math.min(len - bytesRead, blockSize - blockOffset); - System.arraycopy(iNode.getDataBlock(blockNr), (int) blockOffset, dest, off + (int) bytesRead, - (int) copyLength); + log.debug("blockNr: " + blockNr + ", blockOffset: " + blockOffset + ", copyLength: " + copyLength + + ", bytesRead: " + bytesRead); - bytesRead += copyLength; + System.arraycopy(iNode.getDataBlock(blockNr), (int) blockOffset, dest, off + (int) bytesRead, + (int) copyLength); + + bytesRead += copyLength; + } } } catch (Throwable ex) { final IOException ioe = new IOException(); Modified: trunk/fs/src/fs/org/jnode/fs/ext2/INode.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 06:39:34 UTC (rev 5912) +++ trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 06:41:36 UTC (rev 5913) @@ -270,6 +270,17 @@ } /** + * Gets the data stored inline in the inode's i_block element. + * + * @return the inode block data. + */ + public byte[] getINodeBlockData() { + byte[] buffer = new byte[64]; + System.arraycopy(data, 40, buffer, 0, buffer.length); + return buffer; + } + + /** * Return the number of the block in the filesystem that stores the ith * block of the inode (i is a sequential index from the beginning of the * file) @@ -286,10 +297,7 @@ private long getDataBlockNr(long i) throws IOException { if ((getFlags() & Ext2Constants.EXT4_INODE_EXTENTS_FLAG) != 0) { if (extentHeader == null) { - byte[] headerBuffer = new byte[64]; - System.arraycopy(data, 40, headerBuffer, 0, headerBuffer.length); - - extentHeader = new ExtentHeader(headerBuffer); + extentHeader = new ExtentHeader(getINodeBlockData()); } return extentHeader.getBlockNumber(i); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 07:08:10
|
Revision: 5918 http://jnode.svn.sourceforge.net/jnode/?rev=5918&view=rev Author: galatnm Date: 2012-08-10 07:08:00 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Add some extra debugging to Ext2File Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java 2012-08-10 06:57:21 UTC (rev 5917) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Directory.java 2012-08-10 07:08:00 UTC (rev 5918) @@ -227,10 +227,10 @@ //so synchronize to the inode. synchronized (iNode) { try { - Ext2File dir = new Ext2File(iNode); //read itself as a file + Ext2File dir = new Ext2File(entry); //read itself as a file //find the last directory record (if any) - Ext2FSEntryIterator iterator = new Ext2FSEntryIterator(iNode); + Ext2FSEntryIterator iterator = new Ext2FSEntryIterator(entry); Ext2DirectoryRecord rec = null; while (iterator.hasNext()) { rec = iterator.nextDirectoryRecord(); @@ -337,9 +337,9 @@ Ext2DirectoryRecord current; - public Ext2FSEntryIterator(INode iNode) throws IOException { + public Ext2FSEntryIterator(Ext2Entry entry) throws IOException { //read itself as a file - Ext2File directoryFile = new Ext2File(iNode); + Ext2File directoryFile = new Ext2File(entry); //read the whole directory data = ByteBuffer.allocate((int) directoryFile.getLength()); @@ -424,7 +424,7 @@ * @return the FSEntryTable containing the directory's entries. */ protected FSEntryTable readEntries() throws IOException { - Ext2FSEntryIterator it = new Ext2FSEntryIterator(iNode); + Ext2FSEntryIterator it = new Ext2FSEntryIterator(entry); ArrayList<FSEntry> entries = new ArrayList<FSEntry>(); while (it.hasNext()) { Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java 2012-08-10 06:57:21 UTC (rev 5917) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2File.java 2012-08-10 07:08:00 UTC (rev 5918) @@ -34,13 +34,15 @@ */ public class Ext2File extends AbstractFSFile { + Ext2Entry entry; INode iNode; private final Logger log = Logger.getLogger(getClass()); - public Ext2File(INode iNode) { - super(iNode.getExt2FileSystem()); - this.iNode = iNode; + public Ext2File(Ext2Entry entry) { + super(entry.getINode().getExt2FileSystem()); + this.iNode = entry.getINode(); + this.entry = entry; log.setLevel(Level.DEBUG); } @@ -170,6 +172,12 @@ // different INode instances) iNode.incLocked(); } + + if (log.isDebugEnabled()) { + log.info("File:" + entry.getName() + " size:" + getLength() + " read offset: " + fileOffset + " len: " + + dest.length); + } + //a single inode may be represented by more than one Ext2Directory // instances, //but each will use the same instance of the underlying inode (see Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java 2012-08-10 06:57:21 UTC (rev 5917) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2FileSystem.java 2012-08-10 07:08:00 UTC (rev 5918) @@ -898,7 +898,7 @@ */ protected FSFile createFile(FSEntry entry) throws IOException { Ext2Entry e = (Ext2Entry) entry; - return new Ext2File(e.getINode()); + return new Ext2File(e); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 07:12:07
|
Revision: 5919 http://jnode.svn.sourceforge.net/jnode/?rev=5919&view=rev Author: galatnm Date: 2012-08-10 07:12:00 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Fix a bug in extent block lookups Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java 2012-08-10 07:08:00 UTC (rev 5918) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Extent.java 2012-08-10 07:12:00 UTC (rev 5919) @@ -24,6 +24,11 @@ public Extent(byte[] data) { this.data = new byte[EXTENT_LENGTH]; System.arraycopy(data, 0, this.data, 0, EXTENT_LENGTH); + + // Safety check + if (getStartHigh() != 0) { + throw new UnsupportedOperationException("Extents that use the high bits aren't supported yet"); + } } public long getBlockIndex() { @@ -41,4 +46,10 @@ public int getStartHigh() { return Ext2Utils.get16(data, 6); } + + @Override + public String toString() { + return String.format("Extent: blockindex:%d count:%d start(low:%d high:%d)", getBlockIndex(), getBlockCount(), + getStartLow(), getStartHigh()); + } } Modified: trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java 2012-08-10 07:08:00 UTC (rev 5918) +++ trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java 2012-08-10 07:12:00 UTC (rev 5919) @@ -128,7 +128,12 @@ } } - return extent.getStartLow(); + return index - extent.getBlockIndex() + extent.getStartLow(); } } + + @Override + public String toString() { + return String.format("ExtentHeader: depth:%d entries:%d/%d", getDepth(), getEntryCount(), getMaximumEntryCount()); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 07:18:28
|
Revision: 5921 http://jnode.svn.sourceforge.net/jnode/?rev=5921&view=rev Author: galatnm Date: 2012-08-10 07:18:21 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Make inode public Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java trunk/fs/src/fs/org/jnode/fs/ext2/INode.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java 2012-08-10 07:15:24 UTC (rev 5920) +++ trunk/fs/src/fs/org/jnode/fs/ext2/Ext2Entry.java 2012-08-10 07:18:21 UTC (rev 5921) @@ -87,7 +87,7 @@ return type; } - INode getINode() { + public INode getINode() { return iNode; } Modified: trunk/fs/src/fs/org/jnode/fs/ext2/INode.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 07:15:24 UTC (rev 5920) +++ trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 07:18:21 UTC (rev 5921) @@ -105,7 +105,7 @@ log.setLevel(Level.DEBUG); } - protected int getINodeNr() { + public int getINodeNr() { return desc.getINodeNr(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-10 07:26:29
|
Revision: 5925 http://jnode.svn.sourceforge.net/jnode/?rev=5925&view=rev Author: galatnm Date: 2012-08-10 07:26:22 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Further support for ext4 extents and bug fixes Modified Paths: -------------- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java trunk/fs/src/fs/org/jnode/fs/ext2/INode.java Modified: trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java 2012-08-10 07:23:31 UTC (rev 5924) +++ trunk/fs/src/fs/org/jnode/fs/ext2/ExtentHeader.java 2012-08-10 07:26:22 UTC (rev 5925) @@ -103,33 +103,74 @@ return extentEntries; } - public long getBlockNumber(long index) { + public long getBlockNumber(Ext2FileSystem fs, long index) throws IOException { if (getDepth() > 0) { - ExtentIndex[] indexes = getIndexEntries(); + ExtentIndex extentIndex = binarySearchIndexes(index, getIndexEntries()); + byte[] indexData = fs.getBlock(extentIndex.getLeafLow()); - throw new UnsupportedOperationException(); + ExtentHeader indexHeader = new ExtentHeader(indexData); + return indexHeader.getBlockNumber(fs, index); } else { - Extent[] extents = getExtentEntries(); + Extent extent = binarySearchExtents(index, getExtentEntries()); + return index - extent.getBlockIndex() + extent.getStartLow(); + } + } - int lowIndex = 0; - int highIndex = extents.length - 1; - Extent extent = null; + /** + * Performs a binary search in the extent indexes. + * + * @param index the index of the block to match. + * @param indexes the indexes to search in. + * @return the matching index. + */ + private ExtentIndex binarySearchIndexes(long index, ExtentIndex[] indexes) + { + int lowIndex = 0; + int highIndex = indexes.length - 1; + ExtentIndex extentIndex = null; - while (lowIndex <= highIndex) { - int middle = lowIndex + (highIndex - lowIndex) / 2; - extent = extents[middle]; + while (lowIndex <= highIndex) { + int middle = lowIndex + (highIndex - lowIndex) / 2; + extentIndex = indexes[middle]; - if (index < extent.getBlockIndex()) { - highIndex = middle - 1; - } - else { - lowIndex = middle + 1; - } + if (index < extentIndex.getBlockIndex()) { + highIndex = middle - 1; } + else { + lowIndex = middle + 1; + } + } - return index - extent.getBlockIndex() + extent.getStartLow(); + return indexes[Math.max(0, lowIndex - 1)]; + } + + /** + * Performs a binary search in the extents. + * + * @param index the index of the block to match. + * @param extents the extents to search in. + * @return the matching extent. + */ + private Extent binarySearchExtents(long index, Extent[] extents) + { + int lowIndex = 0; + int highIndex = extents.length - 1; + Extent extent = null; + + while (lowIndex <= highIndex) { + int middle = lowIndex + (highIndex - lowIndex) / 2; + extent = extents[middle]; + + if (index < extent.getBlockIndex()) { + highIndex = middle - 1; + } + else { + lowIndex = middle + 1; + } } + + return extents[Math.max(0, lowIndex - 1)]; } @Override Modified: trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java 2012-08-10 07:23:31 UTC (rev 5924) +++ trunk/fs/src/fs/org/jnode/fs/ext2/ExtentIndex.java 2012-08-10 07:26:22 UTC (rev 5925) @@ -24,6 +24,11 @@ public ExtentIndex(byte[] data) { this.data = new byte[EXTENT_INDEX_LENGTH]; System.arraycopy(data, 0, this.data, 0, EXTENT_INDEX_LENGTH); + + // Safety check + if (getLeafHigh() != 0) { + throw new UnsupportedOperationException("Extent indexes that use the high bits aren't supported yet"); + } } public long getBlockIndex() { @@ -37,4 +42,10 @@ public int getLeafHigh() { return Ext2Utils.get16(data, 8); } + + @Override + public String toString() { + return String.format("ExtentIndex: blockindex:%d leaf(low:%d high:%d)", getBlockIndex(), getLeafLow(), + getLeafHigh()); + } } Modified: trunk/fs/src/fs/org/jnode/fs/ext2/INode.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 07:23:31 UTC (rev 5924) +++ trunk/fs/src/fs/org/jnode/fs/ext2/INode.java 2012-08-10 07:26:22 UTC (rev 5925) @@ -300,7 +300,7 @@ extentHeader = new ExtentHeader(getINodeBlockData()); } - return extentHeader.getBlockNumber(i); + return extentHeader.getBlockNumber(fs, i); } else { return getDataBlockNrIndirect(i); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |