About LeanFS

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

About LeanFS

Post by bzt »

TL;DR leanfs is part of a dead project that never actually used it, doesn't have a working mkfs tool, and the reference implementation is non-portable, bloated, heavy on dependencies and doesn't even compile.
BenLunt wrote:Anyway, if you are writing for a hard drive, I would actually recommend the LEAN file system. I had/have the honor of working with the original author and have added and implemented a lot of its current format. I believe he (we) are ready to release version 0.7 soon.
Then maybe you can help me.
BenLunt wrote:The LeanFS has a lot of advantages: Large files, long filenames, extents, forks, etc.
And some disadvantages too, like no support for this file system of any kind, which is quite a big roadblock. I mean, I've searched the web all over and over again, and come up with nothing useful. I couldn't find any leanfs driver that's actually been used (to be precise, even FreeDOS-32 can't use leanfs formatted partitions, only FAT supported. The separate leanfs directory outside of "src" is NOT being used at all.) Then I've learned that FreeDOS-32 actually has nothing to do with FreeDOS, it is a separate project stealing the name and it was actually abandoned (last update in 2011 about 10 years ago). Obviously this also means no drivers nor tools for leanfs under FreeDOS (I mean, in the original FreeDOS).

Okay, not having a driver not a big thing for me, if I can generate images I can reverse-engineer the format in no time. So next step, in lack of a working driver example, I've searched for a tool to create and dump leanfs images.
1. I've found mkfs.c in the aforementioned unrelated leanfs folder, but while it compiles without problems and is dependency-free, actually isn't a tool at all, just a quick-n-dirty toy to handle one image with a hardcoded file name, size and parameters.
2. okay, I've seen worse, I could work with that, but being over 10 years old, it's for "The LEAN File System Driver version 0.1", something very very old and outdated.
3. then I've tried leanfsgui, which is in C++. That's a big no-go for library as well as for a command line tool, but there are even bigger problems with it.
4. it is a non-portable horror, requiring TONS of Windows-related dependencies (mingw, CodeBlock build environment, boost, wxWidgets, gdmd (whatever that is) etc.). There's nothing wrong with providing IDE project files as long as there's a working Makefile too, but the one shipped doesn't work (if you can find it, because it's hidden in a sub-directory of a sub-directory). The way how 0.1's mkfs.c and the FreeDOS FAT createfs.c was written is the way to do it, not like this.
5. if this isn't enough, that leanfsgui is abandoned too, hasn't been updated for more than 9 years, and throws several pages of warnings and errors with the latest compilers.

So my question is, if you're recommending this file system, do you have a simple, small, portable image creator for it? Because I can't even find one. (Proprietary and closed-source, or windows-only out of question.) I'd be happy with the 0.6 version of the mkfs.c too, even though it isn't a tool just a toy (as it compiles, dependency-free, written in portable C and simple. Simple is good.)

Any working driver example would be nice too (fuse, grub-module, linux kernel module, dokan driver what ever).

Cheers,
bzt
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

Hi bzt,

First let me explain the reason I recommend the LeanFS, in an abstract kind of way. Most of us here, especially myself, are here for the enjoyment of creating something with our own hands, so to speak. Yes, we could grab a copy of Grub, then port someone else's kernel and drivers, compiler, and other tools, and combine them to make something. But where is the fun in that?

Therefore, I have created my own legacy boot code for many file systems. Then I created a loader which supported the same many file systems. The boot code is in assembly and the original loader code was as well. So what did I do? I wrote an assembler. I then updated and bug-fixed this assembler while writing these boot sectors. Why? Because I wanted to see if I could, and for the enjoyment of it.

So, why the LeanFS? There are no other utilities or driver code. I have to make everything myself. From scratch. It is the enjoyment of doing so.

You know about my (open source) utility, but yes it is Windows only. However, on that same page is an image (or two) that has a LeanFS partition. You could easily test your code with it. If you need another image, please let me know what kind of details you would like on it, and I will create it and post it.

I recommended the LeanFS to the original post in the hope that the poster would try something that isn't already done by every other project here, that they might get the satisfaction of creating something new, rather than stealing someone else's code. I learn(ed) a lot more when I start from scratch, coding the project myself, than copying someone else's code, and simply modifying it for my taste.

Yes, the original author of the LeanFS has moved on to other projects. I don't blame him. In fact, if it wasn't for my persuasion, he probably wouldn't have even got as far as he did. However, when I have the time (and interest), I come back to it and add function to my code. Therefore, if you need help with your implementation, I am more than happy to answer any questions you have, look over your code, and run my tests on your image(s).

The term "re-inventing the wheel" has been used a lot in this forum over the years, but I believe that if we build a new wheel for ourselves, we can learn how to do it and possibly make it better. Why not start with the LeanFS?

Anyway, thank you for your interest. As the original author has told me many times, and I agree, this file system has been an enjoyment for the both of us. It would be exciting for myself, as with the original author, if others would implement this file system in their own projects, giving feedback throughout.

Thank you,
Ben
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

Okay, maybe I wasn't clear. LeanFS spec is pretty good, that's why I'm interested in it. But to my experience the spec isn't enough to implement a read-write driver.
BenLunt wrote:So, why the LeanFS? There are no other utilities or driver code. I have to make everything myself. From scratch. It is the enjoyment of doing so.
I agree, the problem here is, there must be a way a validate if your generated image (or partition) actually complies with the spec and validates as a correct LeanFS. Without you can't be sure that your driver is correct.
BenLunt wrote:You know about my (open source) utility, but yes it is Windows only.
Yes, it's a pretty amazing tool, and my only issue with it is that I don't use Windows, only Open Source. Have you ever thought about porting it to GTK for example? Pure X11 would be the best, but that's a lot to ask I know, as that is a low-level library.
BenLunt wrote:However, on that same page is an image (or two) that has a LeanFS partition. You could easily test your code with it. If you need another image, please let me know what kind of details you would like on it, and I will create it and post it.
Thank you very much, but it's the other way around. Comparing my image to a known-to-be good image is just the first step, what I'm actually interested in is testing and dumping my images. (While for me it's okay to generate a dozen test images per hour and compare them to my own generated image, it would be overwhelming to ask someone else to do that for me. You see, I don't know in advance what part I want to test, I generate the "compare with" images as the test goes.)
BenLunt wrote:I recommended the LeanFS to the original post in the hope that the poster would try something that isn't already done by every other project here, that they might get the satisfaction of creating something new, rather than stealing someone else's code. I learn(ed) a lot more when I start from scratch, coding the project myself, than copying someone else's code, and simply modifying it for my taste.
I absolutely and 100% percent agree. I don't want to use someone else's code, I need it to test my image (or put a bunch of printfs in it as well as in my code too, and compare the outputs). For example with ext2, I've created an empty image with mke2fs. Then I adjusted my code until I could generate the same bit by bit (wasn't trivial, because the ext2 doc does not say how to calculate the maximum number of inodes for example, and that inode 6 (undelete) isn't actually used for "lost+found" etc.) Then when I could generate a perfect empty image, I started to add contents and checked the image with debugfs and dumpfs. I'm looking for similar tools for LeanFS.
BenLunt wrote:Yes, the original author of the LeanFS has moved on to other projects. I don't blame him. In fact, if it wasn't for my persuasion, he probably wouldn't have even got as far as he did. However, when I have the time (and interest), I come back to it and add function to my code. Therefore, if you need help with your implementation, I am more than happy to answer any questions you have, look over your code, and run my tests on your image(s).
Thank you very much, I might take on your word :-) I'm planning to add LeanFS in my disk image creator. So far it can generate almost every Beginner filesystems. The exception is BMFS, I like very much how it was done, there's a separate library, fuse driver, etc., but it's so limited that I don't really think anybody would want to use it for real (the lack of directories is pretty awkward these days.)
BenLunt wrote:The term "re-inventing the wheel" has been used a lot in this forum over the years, but I believe that if we build a new wheel for ourselves, we can learn how to do it and possibly make it better. Why not start with the LeanFS?
Exactly that was my thought! I want to add LeanFS to my image creator because if a beginner thinks the same way, then I want to provide a tool for them that can generate such partitions out of a directory, so they can focus implementing their drivers. Actually I find LeanFS pretty good for beginners, because it's featured enough (everything that an OS might need is supported, like UNIX privileges, fragmentation, symbolic links etc.), yet it's a lot simpler than ext2 for example. FAT is easy to implement, but lacking way too many features (protection bits, hardlinks, symlinks, etc.) I would say LeanFS gets the best of both the FAT and i-node worlds, that's why I'm interested in it.
BenLunt wrote:Anyway, thank you for your interest. As the original author has told me many times, and I agree, this file system has been an enjoyment for the both of us. It would be exciting for myself, as with the original author, if others would implement this file system in their own projects, giving feedback throughout.
Let's see how far I can get with the specification alone, without validating the results. The imager tool is here, and I'm planning to call the partition type with this format "lean" if that's okay with you (and the original author). FYI, I have also wanted to add SFS because it's OSDev.org's file system, and with your help and example images I could implement a read-only driver (in the boot loader), however I've would the specification insufficient for creating a proper image creator. At first glimpse this won't be the case with LeanFS, as it's much better documented.

Cheers,
bzt
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

Okay, I see what you are asking. I am in the process of adding more documentation to the specification, in preparation for the next version release. I will take your comments, which are completely justified, into consideration. A few example images for comparison is a simple task.

Thanks again. I appreciate and agree with your comments.

Ben

P.S. You did see that the author has a test suite and driver suite for Linux at http://freedos-32.sourceforge.net/lean/downloads.php, though you need wxWidgets as well.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

Hi Ben,
BenLunt wrote:Okay, I see what you are asking. I am in the process of adding more documentation to the specification, in preparation for the next version release. I will take your comments, which are completely justified, into consideration.
Thanks! Is the 0.7 version spec available somewhere? A pre-release version perhaps?
BenLunt wrote:A few example images for comparison is a simple task.
Not that few... With the ext2 driver for example I've generated more than a hundred images with different mke2fs options.
BenLunt wrote:Thanks again. I appreciate and agree with your comments.
You're welcome! I'm glad I could help!
BenLunt wrote:P.S. You did see that the author has a test suite and driver suite for Linux at http://freedos-32.sourceforge.net/lean/downloads.php, though you need wxWidgets as well.
Yeah, that's the reference implementation that I'm unable to compile because of bloatware and non-portable syntax.


On the other hand, I've found mleanfs and lean_chk instead. Even though I can't compile the ultimate gui, I was able to separate these two from your repo, liberate them from the MSVC horror and replace everything with nice C++ standard, and compile under Linux with gcc. I'm having some issues running them, though.

My resource file looks like this:

Code: Select all

mbrfile=../bootboot/dist/boot.bin
bootfile=../bootboot/dist/bootboot.bin
imgfile=../bootboot/images/test.bin
base_lba=0
tot_sects=32768
param0=12
head=16
spt=63
mleanfs: it does not accept the "tot_sects", complaining about "Total Sectors does not end on cylinder boundary", which is strange, because I'm pretty sure 32768 is multiple of 4096 (1<<param0). I've also tried with spt=64 (in case cylinder here means head*sectorpertrack, so make sure 32768 is multiple of 1024), but the same result. This is just a minor issue, if I remove the check (USB sticks and SSDs don't use tracks nor cylinders anyway) everything seems to be working just fine.

lean_chk: this is the bigger problem. I've tried it on the image generated by mleanfs, and it complains about "Found version number 0.6. *Only version 0.7 is supported." and there's an error for incorrect inode size. Not sure what to do with this.

BTW, I like these two very much, these are exactly the tools I need. If you do a few adjustments (it already has ifdef guards for DJGPP, and both tool should use the same leanfs header file), it could be the portable, dependency-free tool that I lacked so much. (Note: tweaks for DJGPP almost the same as gcc's, the biggest difference is the memory model difference. That's why you shouldn't define the types yourself, instead include stdint.h. For example with DJGPP (as Win32 uses LLP64) both "int" and "long" are the same size, 32 bits, and 64 bits requires "long long"; while gcc under Linux uses LP, "int" being 32 bit, and "long" 64 bit, therefore "long long" isn't supported (could mean 128 bit), just like the "ll" modifier in printf formatting that throws a warning. Other than that I had issues with "time_t", "time()" and "localtime()" has a different prototype, there's no "strcpy_s" (but the prototype otherwise ok) and "fopen_s" is also missing and uses a different prototype (returns FILE* not error code). That covers it all I think, there were no big issues, just a bunch of repeating minor ones.

Cheers,
bzt
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

Hi Ben,

Okay, I've implemented LeanFS, you can find the code in the repo. https://gitlab.com/bztsrc/bootboot/-/bl ... img/lean.c.
I've attached a generated image, can you please take a look at it?

Here are my findings that should be addressed in the new spec (minor issues really):
  • It is unclear if bitmaps are allowed to record sectors which are *before* the bitmap itself. It seems from your code that they can.
  • According to the spec, sectorCount in inode includes "The number of data sectors (thus excluding indirect sectors, and including the first sector with the inode structure) allocated for the file." (meaning empty file would have sectorCount = 1)
  • However your tool seems to only record the number of actual file content data sectors (meaning empty file would have sectorCount = 0, which makes more sense imho, this field should either include all allocated sectors (including inode and indirect sectors) or it should only include the number of data sectors. Including inode but not the indirect sectors seems odd)
  • It is not very well specified what bytes make up the inode checksum. I've finally gave this up, and used the same define as in your code.
  • The spec should be more specific than "The checksum value for the inode structure. Any inline extended attributes following the inode structure are not part of the inode structure itself, thus must not be included in checksum calculation.", it should read as "checksum from bytes 4 to 176" or something.
  • I think there's no reason why not to include the extended attributes in the checksum. Would be more robust, and you'll have to read and write the entire inode sector anyway for those.
  • The size of the inode field (which I think grows when you add extended attributes) included in the checksum, so the checksum needs to be updated already when extended attributes change.
I've run into problems with lean_chk, so I couldn't use it after all. This means I've compared the image hexdump with the spec, looks okay to me, but wasn't verified otherwise.
One issue I've noticed that when lean_chk compares the bitmaps, it assumes blindly that the first 33 sectors are reserved, which isn't always the case. On format, I set bits from 0 to superblock->root_inode (which is loader + superblock + bitmap size) for the first band, and 0 to bitmap_size for all the other bands, therefore the bitmap check always failed for me, I had to remove it.
Another issue is this:

Code: Select all

LEAN_CHK  v2.00.00    Forever Young Software 1984-2019
 Super found at LBA 1 with a checksum of 0xD0AE3DEC.
 Found version number 0.7.
 PreAllocate Count is 0
   Count would be more logical as an odd number, calculating to an even number.
 Logical Sectors per band is 12 (4096 sectors per band)
 State is 0x00000001
 Volume sector count is 32768
 Free sector count is 32745
 Bitmap starts at 2
 Super indicates root inode is at 14
 Super indicates bad sector inode is at 0
 Checking the backup Super Block sector...
  Found backup super at sector: 4095
 Total bands found: 8
 Each bands bitmap size in sectors: 1
 Counted 32745 free sectors.  Super reported 32745 free sectors
 Checking: \
Inode Number: 14
*Found unknown or illegal type in directory entry.  Type = 0x21
 Found 0 orphand sectors.
 Found 0 unmarked sectors.

 Extent Sectors used: 1
     Total Directors: 1
         Total Files: 0

        Errors Found: 0
   Diagnostics Found: 1
The problem with this, I don't know what lean_chk is actually checking, but the fact is, there's no 0x21 character in my entire image. If I set 7 for pre-allocated sectors, then this error goes away.

Cheers,
bzt
Attachments
test.bin.gz
(16.29 KiB) Downloaded 60 times
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

I had completely forgot about those two utilities. Thanks for reminding me.

I will have a look at the errors you show and the image you gave. Give me a little while and I will get back with you on all of this.

Thanks,
Ben
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

bzt wrote:

Code: Select all

Inode Number: 14
*Found unknown or illegal type in directory entry.  Type = 0x21
Just a quick test of your image and found the first Inode within a directory is at 14. This tells me quite a bit, so:
  • - An inode must not be less than (32 + size of the first bitmap). LBAs 0 through 32 are reserved for the boot code and the Superblock. If you have a single sector for the bitmap, this means that the lowest Inode number must be no less than 34.
    - If I look at your Superblock, it has the following:

    Code: Select all

                   ...
              Total Sectors: 0x0000000000008000  (32768)
               Free Sectors: 0x0000000000007FE9  (32745)
          Primary Super LBA: 0x0000000000000001  (1)
           Backup Super LBA: 0x0000000000000FFF  (4095)
           Bitmap Start LBA: 0x0000000000000002  (2)
             Root Start LBA: 0x000000000000000E  (14)
              Bad Start LBA: 0x0000000000000000  (0)
                   ...
    - The Bitmap Start LBA must not be less than 33. You have it as 2.
    - The Root Start LBA must not be less than 32 + size of first bitmap. You have it as 14.
    - Next, I looked at the Inode at LBA 14, which is the Inode of the root directory:

    Code: Select all

                      ...
       Last Indirect Sector: 0x0000000000000000 (0)
                       Fork: 0x0000000000000000 (0)
                   Extent 0:  start 0x000000000000000F (15), size 0x00000001 (1)
                   Extent 1:  start 0x0000000000000000 (0), size 0x00000000 (0)
                   ...
    
    - The starting extent value must be the same as the Inode LBA. You have it as 15 (14+1).
    - I haven't looked why, but your code is placing a value of 0x2C in the first byte of the reserved[3] field within the inode.
    - You also place a value of 4 in the Links Count field. Currently there is only 1 link pointing to this file. When deleting a file, you first decrement this value. If, and only if, this value becomes zero, do you actually remove (delete) the inode.
The two utilities you mention, especially the test utility, is a little behind and obviously didn't test that the first bitmap LBA was at least 33. I will have to fix this.

Give me a few days and I will see about updating the utilities and the documentation. In the meantime, if you fix your code and update the image, please post it and I will check it again.

Thanks,
Ben

P.S.:
mleanfs: it does not accept the "tot_sects", complaining about "Total Sectors does not end on cylinder boundary", which is strange, because I'm pretty sure 32768 is multiple of 4096 (1<<param0). I've also tried with spt=64 (in case cylinder here means head*sectorpertrack, so make sure 32768 is multiple of 1024), but the same result. This is just a minor issue, if I remove the check (USB sticks and SSDs don't use tracks nor cylinders anyway) everything seems to be working just fine.

lean_chk: this is the bigger problem. I've tried it on the image generated by mleanfs, and it complains about "Found version number 0.6. *Only version 0.7 is supported." and there's an error for incorrect inode size. Not sure what to do with this.
The error that tot_sects doesn't end on cylinder boundary is due to the MBR. The MBR LBA + 32768 sectors is 32769 total sectors. Either use a sector count of 32767 or ignore this error.
The incorrect inode size is due to the fact that you have 15 for the starting lba in the extents, when it should be 14. Therefore, when reading in the Inode for the check, it is reading LBA 15 instead of 14, and since there is not a valid INODE at LBA 15, you will get the error.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

BenLunt wrote:- An inode must not be less than (32 + size of the first bitmap). LBAs 0 through 32 are reserved for the boot code and the Superblock.
Are you sure? The specification doesn't say anything like that. It says

Code: Select all

The superblock must be stored in one of any sector in range from 1 to 32, inclusive.
and about the bitmapStart field:

Code: Select all

uint64_t bitmapStart	The address of the sector where the bitmap of the first band (that is, band 0) starts. This is usually the sector right after the superblock.
Now if superblock can be at sector 1, and bitmap starts at the sector right after the superblock, this means the lowest root inode number cloud be at sector 3.
BenLunt wrote:The Bitmap Start LBA must not be less than 33. You have it as 2.
I haven't seen this written anywhere in the spec. It only says that bitmap should start at the sector right after the superblock.
BenLunt wrote:The starting extent value must be the same as the Inode LBA.
Are you sure? No other file system does that, and the specification says:

Code: Select all

Besides being unused, each sector in the data area can be either a data sector or an indirect sector. The former contains actual data, the latter contains book keeping. Data sectors are grouped together to form extents when they are contiguous.
I interpret this as neither inode nor indirect sectors are part of the extents, because they are not storing actual data, rather book keeping data, and extents only store actual data sectors.

It makes a lot more sense not to include inode in the extents, and you haven't counted it as one with inode->sectorCount.
BenLunt wrote:I haven't looked why, but your code is placing a value of 0x2C in the first byte of the reserved[3] field within the inode.
Because your tool checks for it? From your code:

Code: Select all

struct S_LEAN_INODE {
  bit32u checksum;                // bit32u sum of all fields before this one.
  bit32u magic;                   // 0x45444F4E  ('NODE')
  bit8u  extent_count;            // count of extents in this inode struct.
  bit8u  inode_size;              // Inode size in dwords (176 / 4)        <-------------- used to be reserved in 0.6
  bit16u reserved;                // reserved
BenLunt wrote:You also place a value of 4 in the Links Count field. Currently there is only 1 link pointing to this file.
Nope, link calculation is accurate. There are 4 directory entries pointing to the root inode: there's "." and ".." in the root directory, that's 2, and there are "a" and "b" directories which have a ".." entry pointing to the root directory. That's 4 links in total.

Cheers,
bzt
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

bzt wrote:
BenLunt wrote:- An inode must not be less than (32 + size of the first bitmap). LBAs 0 through 32 are reserved for the boot code and the Superblock.
Are you sure? The specification doesn't say anything like that. It says

Code: Select all

The superblock must be stored in one of any sector in range from 1 to 32, inclusive.
and about the bitmapStart field:

Code: Select all

uint64_t bitmapStart	The address of the sector where the bitmap of the first band (that is, band 0) starts. This is usually the sector right after the superblock.
Now if superblock can be at sector 1, and bitmap starts at the sector right after the superblock, this means the lowest root inode number cloud be at sector 3.
BenLunt wrote:The Bitmap Start LBA must not be less than 33. You have it as 2.
I haven't seen this written anywhere in the spec. It only says that bitmap should start at the sector right after the superblock.
You're right. It doesn't actually specify this. I guess it was just implied that it was. This is something that I will need to clarify. I guess in all reality, it can be just as you state. However, the idea was that if you ever modified the boot code, you wouldn't have to move any of the data blocks if the current size was not large enough. The only thing you would have to do is move the Superblock.
bzt wrote:
BenLunt wrote:The starting extent value must be the same as the Inode LBA.
Are you sure? No other file system does that, and the specification says:

Code: Select all

Besides being unused, each sector in the data area can be either a data sector or an indirect sector. The former contains actual data, the latter contains book keeping. Data sectors are grouped together to form extents when they are contiguous.
I interpret this as neither inode nor indirect sectors are part of the extents, because they are not storing actual data, rather book keeping data, and extents only store actual data sectors.
This I am absolutely sure on, since the Inode is only 176 bytes in size, *and* the file data can start directly after the Inode, thereby using the first sector as data as well. It also states right in the specs under the extentStarts[] definition:

Code: Select all

 Note that the first element of this array is also -by definition- the address of the sector containing this inode structure.
bzt wrote:
BenLunt wrote:I haven't looked why, but your code is placing a value of 0x2C in the first byte of the reserved[3] field within the inode.
Because your tool checks for it? From your code:

Code: Select all

struct S_LEAN_INODE {
  bit32u checksum;                // bit32u sum of all fields before this one.
  bit32u magic;                   // 0x45444F4E  ('NODE')
  bit8u  extent_count;            // count of extents in this inode struct.
  bit8u  inode_size;              // Inode size in dwords (176 / 4)        <-------------- used to be reserved in 0.6
  bit16u reserved;                // reserved
Oh, sorry. This was a rat dropping from an old draft. I (we) haven't decided if it will remain or not.
bzt wrote:
BenLunt wrote:You also place a value of 4 in the Links Count field. Currently there is only 1 link pointing to this file.
Nope, link calculation is accurate. There are 4 directory entries pointing to the root inode: there's "." and ".." in the root directory, that's 2, and there are "a" and "b" directories which have a ".." entry pointing to the root directory. That's 4 links in total.
Since my tests concluded that the inode was invalid, due to a value of 15 and not 14, my tests didn't make it that far. All I could see was the invalid root entry.

For example, the current image file you posted has the iaInlineExtAttr (bit 19) as zero. This indicates the opposite of "The remaining bytes after the inode structure in the first sector are reserved for inline extended attributes". Since this bit is zero, meaning do not place the extended attributes after the inode, the file data is to start after the inode. Therefore, your root directory, using only 64 bytes, will start at offset 176 in the first sector and not occupy any other sectors. Therefore, a driver could read the one and only sector and retrieve the whole inode and all of the file data with a single sector read. The ExtentStart[0] entry should be the same as the inode lba, and the size entry as you have it (1).

Code: Select all

Actual file data start right after the inode structure or, if the iaInlineExtAttr attribute is set, at the beginning of the subsequent data sector (perhaps in the same extent).
I will have to add clarification for the first few notes you mention.

Thanks,
Ben
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

BenLunt wrote:You're right. It doesn't actually specify this. I guess it was just implied that it was. This is something that I will need to clarify. I guess in all reality, it can be just as you state. However, the idea was that if you ever modified the boot code, you wouldn't have to move any of the data blocks if the current size was not large enough. The only thing you would have to do is move the Superblock.
That's not the case with BOOTBOOT, but okay, I'll make more space for the loader. I think I'll move the superblock to the 32th sector to put it at a fixed location.
BenLunt wrote:This I am absolutely sure on, since the Inode is only 176 bytes in size, *and* the file data can start directly after the Inode, thereby using the first sector as data as well. It also states right in the specs under the extentStarts[] definition:

Code: Select all

 Note that the first element of this array is also -by definition- the address of the sector containing this inode structure.
I had an impression this is only so with inlined data.
BenLunt wrote:Oh, sorry. This was a rat dropping from an old draft. I (we) haven't decided if it will remain or not.
Actually I was very surprised at first when the check complained about a reserved byte not being set :-) Let me know if it remains or goes, and I'll change the inode accordingly. But for the records, since the inode size is fixed and can be detected by the fs version field, I see no much point having it in every inode.
BenLunt wrote:For example, the current image file you posted has the iaInlineExtAttr (bit 19) as zero. This indicates the opposite of "The remaining bytes after the inode structure in the first sector are reserved for inline extended attributes". Since this bit is zero, meaning do not place the extended attributes after the inode, the file data is to start after the inode. Therefore, your root directory, using only 64 bytes, will start at offset 176 in the first sector and not occupy any other sectors. Therefore, a driver could read the one and only sector and retrieve the whole inode and all of the file data with a single sector read. The ExtentStart[0] entry should be the same as the inode lba, and the size entry as you have it (1).

Code: Select all

Actual file data start right after the inode structure or, if the iaInlineExtAttr attribute is set, at the beginning of the subsequent data sector (perhaps in the same extent).
I will have to add clarification for the first few notes you mention.
While I can make this modification easily, I'd like to ask you to think this again and probably address it in 0.7

I think, the best is:
not inlined:
- ExtentStart[0] points to the first data sector (with the file's content)
- ExtentCount is 0 for empty files
- SectorCount is 0 for empty files (even though there's one sector allocated for the file, the inode, but that's not part of the data)

Inlined:
- ExtentStart[0] points to the inode, if iaInlineExtAttr is set and then file data starts at offset sizeof(inode struct)
- ExtentCount is 1 for empty files
- SectorCount is 0 for empty files

This makes more sense to me than including the i-node in the file data with different size (sizeof(inode) without iaInlineExtAttr and 512 otherwise), especially since no other meta data is included and no other file system does that. I think the offset should be sizeof(inode) with iaInlineExtAttr and 0 otherwise, that would make implementations simpler. (In other words do not store if extra attributes inlined, instead store if the data is inlined).

Cheers,
bzt
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

Ok, here's the list of modifications I've made:

1. superblock moved to sector 32
2. bitmap of the first band moved to sector 33
3. attribute iaInlineExtAttr is constantly set (so that data starts at the first sector right after the inode)
4. removed inode->inodeSize (keep it as a reserved byte)
5. inode->sectorCount can't be zero not even for empty files
6. now inode->extentCount can't be zero under no circumstances
7. inode->extentStart[0] points to the inode
8. I've changed the fs version back to 0.6 for now (in lack of a 0.7 spec link and because inode size not set)

Cheers,
bzt
Attachments
test.bin.gz
(16.29 KiB) Downloaded 79 times
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: About LeanFS

Post by BenLunt »

This image passes all the tests I just threw at it. I will look at it some more at a later time.

I believe the version 0.7 specification is nearly complete. After a few more details, I just need permission to finalize it and post it.

Thanks again for your comments. They are appreciated.
Ben
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: About LeanFS

Post by bzt »

BenLunt wrote:This image passes all the tests I just threw at it. I will look at it some more at a later time.
Cool! :-D
BenLunt wrote:I believe the version 0.7 specification is nearly complete. After a few more details, I just need permission to finalize it and post it.
Let me know when that happens, and I'll change the code to generate for 0.7.
BenLunt wrote:Thanks again for your comments. They are appreciated.
And I appreciate your help! It was nice working with you again! You helped a lot with the ISO9660 too!

Cheers,
bzt
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: About LeanFS

Post by Ethin »

I'm confused about why you'd need perms, especially if the FS is abandoned, as it seems to be here. Why not take over the project entirely?
Post Reply