Skip to content

Conversation

@AssafTzurEl
Copy link

BTreeExtentHeader.LeftSibling's size is 8 bytes. Therefore, RightSibling's offset should be +8, which is 16 (0x10) and not 12 (0xc).

While I was there, I added Inode.ToString() to help me differentiate beween inodes: In Linux, inodes are identified by a unique ID.

Assaf Tzur-El added 2 commits September 12, 2019 16:41
In XFS source code, bb_leftsib and bb_rightsib (declared in xfs_format.h) are both of type __be32, which is an unsigned int32 (and not 64).
While I was there, I added Inode.ToString() to help me differentiate beween inodes: In Linux, inodes are identified by a unique ID.

Branch: [xfs-btree-bugfix]
BTreeExtentHeader.LeftSibling's size is 8 bytes. Therefore, RightSibling's offset should be +8, which is 16 (0x10) and not 12 (0xc).

Branch: [xfs-btree-bugfix]
@qmfrederik
Copy link
Contributor

@AssafTzurEl Any chance you could add a small unit test which would cover this case?

@AssafTzurEl
Copy link
Author

@qmfrederik I hope so... turns out the file "huge\1" in xfs.zip is a b+Tree. Is there a way to retrieve its inode object? If I can do that, I'll be able to assert its inode.LeftSibling and .RightSibling.

@zivillian
Copy link
Contributor

@AssafTzurEl Create a virtual machine, with the vhdx attached to it - mount the filesystem and take a look with xfs_db
That's how I verified and debugged the implementation.

@AssafTzurEl
Copy link
Author

@zivillian As I wrote, I found an existing VHDX with a candidate file. What I need is a way to retrieve the files's inode programatically, something like GetInode(string fileName) - from there I'll be able to assert the inode's sibling properties. Since I'm not a DiscUtils expert, I asked for help on how to retrieve the inode in code.

@zivillian
Copy link
Contributor

I'm sorry, I totally misunderstood your reply. I came up with the following change, to get the inode.

The idea is to make VfsFileSystemFacade.GetRealFileSystem protected internal and use xunit Assert.IsType to cast the various filesystems to their real implementations.

 Library/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs |  2 +-
 Tests/LibraryTests/Xfs/SampleDataTests.cs         | 31 +++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Library/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs b/Library/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs
index 97887f80..643989c5 100644
--- a/Library/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs
+++ b/Library/DiscUtils.Core/Vfs/VfsFileSystemFacade.cs
@@ -543,7 +543,7 @@ namespace DiscUtils.Vfs
         /// <typeparam name="TDirectory">The concrete type representing directories.</typeparam>
         /// <typeparam name="TContext">The concrete type holding global state.</typeparam>
         /// <returns>The actual file system instance.</returns>
-        protected VfsFileSystem<TDirEntry, TFile, TDirectory, TContext> GetRealFileSystem
+        protected internal VfsFileSystem<TDirEntry, TFile, TDirectory, TContext> GetRealFileSystem
             <TDirEntry, TFile, TDirectory, TContext>()
             where TDirEntry : VfsDirEntry
             where TFile : IVfsFile
diff --git a/Tests/LibraryTests/Xfs/SampleDataTests.cs b/Tests/LibraryTests/Xfs/SampleDataTests.cs
index 68d2e946..740827b6 100644
--- a/Tests/LibraryTests/Xfs/SampleDataTests.cs
+++ b/Tests/LibraryTests/Xfs/SampleDataTests.cs
@@ -79,6 +79,37 @@ namespace LibraryTests.Xfs
             }
         }
 
+        [Fact]
+        public void GetInode()
+        {
+            SetupHelper.SetupComplete();
+            using (FileStream fs = File.OpenRead(Path.Combine("..", "..", "..", "Xfs", "Data", "xfs.zip")))
+            using (Stream vhdx = ZipUtilities.ReadFileFromZip(fs))
+            using (var diskImage = new DiskImageFile(vhdx, Ownership.Dispose))
+            using (var disk = new Disk(new List<DiskImageFile> { diskImage }, Ownership.Dispose))
+            {
+                var manager = new VolumeManager(disk);
+                var logicalVolumes = manager.GetLogicalVolumes();
+                Assert.Single(logicalVolumes);
+
+                var volume = logicalVolumes[0];
+                var filesystems = FileSystemManager.DetectFileSystems(volume);
+                Assert.Single(filesystems);
+
+                var filesystem = filesystems[0];
+                Assert.Equal("xfs", filesystem.Name);
+
+                using (var xfs = filesystem.Open(volume))
+                {
+                    var xfsfs = Assert.IsType<XfsFileSystem>(xfs);
+                    var vfs = xfsfs.GetRealFileSystem<DirEntry, DiscUtils.Xfs.File, DiscUtils.Xfs.Directory, Context>();
+                    var xfsvfs = Assert.IsType<VfsXfsFileSystem>(vfs);
+                    var dirEntry = xfsvfs.GetDirectoryEntry("huge\\1");
+                    dirEntry.Inode; //<- that's the inode you asked for with RelativeInodeNumber = 202
+                }
+            }
+        }
+
         private void ValidateContent(DiscFileSystem xfs)
         {
             Assert.True(xfs.DirectoryExists(""));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants