|
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.
|