SerCeMan / jnr-fuse

FUSE implementation in Java using Java Native Runtime (JNR)
MIT License
370 stars 88 forks source link

arm support #13

Closed fantom-x closed 8 years ago

fantom-x commented 8 years ago

HI, I would like to make jnr-fuse run on an ARM 32-bit board. I can now compile it and start MemoryFS app. I can see the mount, directories, and files. But the file sizes are zero. Trying to copy a file into it creates a zero-size file. "rm" and "mkdir" work. So it looks like it is almost there, except for the file sizes at this time, although there could be more issues. Two size tests are failing: testFlock (expected:<24> but was:<28>) & testFuseBufvec (expected:<36> but was:<40>). I will make the changes and test myself if you provide some directions.

SerCeMan commented 8 years ago

Tests are trying to get a size of a structure and compare with native size. I used C++ program to understand expected size of the structure. The first step should be small C++ program which will get you the actual size of flock and bufvec on your machine. After that, it will be easier to understand a problem with this data structures in ARM.

fantom-x commented 8 years ago

flock size is '16'

Still trying to figure out where bufvec is defined...

fantom-x commented 8 years ago

Is it "flock" from and "fuse_bufvec" from <fuse/fuse_common.h>?

fantom-x commented 8 years ago

Including "fuse/fuse.h" gave me this error: #error Please add -D_FILE_OFFSET_BITS=64 to your compile flags! And compiling with that flag: fuse_bufvec size is '40'

At the same time using that flag changed the size of "flock" from 16 to 32...

SerCeMan commented 8 years ago

Now to me it looks like this field ru.serce.jnrfuse.struct.FuseBuf#fd may cause wrong behavior. About structures it would be better to compare them field by field.

But in general, if you have wrong behavior in your program it is better to enable debug and look for output. Can you attach debugging logs with the problem?

fantom-x commented 8 years ago

Ok, I am getting two different results for "flock" (fuse/fuse.h can only be included with -D_FILE_OFFSET_BITS=64). My guess here is that the first one is compiled wrong, because l_start and l_len are 32 bit, which limits the file access to 4G, which does not make sense. In the second case I see a 4-byte padding between "l_whence" and "l_start" and a 4-byte padding at the end of the structure.


g++ flock_size.cpp -o flock_size && ./flock_size
flock size is '16'
flock.l_type size is   '2' offset is '0'
flock.l_whence size is '2' offset is '2'
flock.l_start size is  '4' offset is '4'
flock.l_len size is    '4' offset is '8'
flock.l_pid size is    '4' offset is '12'

and

g++ -D_FILE_OFFSET_BITS=64 flock_size.cpp -o flock_size && ./flock_size
flock size is '32'
flock.l_type size is   '2' offset is '0'
flock.l_whence size is '2' offset is '2'
flock.l_start size is  '8' offset is '8'
flock.l_len size is    '8' offset is '16'
flock.l_pid size is    '4' offset is '24'
SerCeMan commented 8 years ago

Frankly, I don't feel like Flock structure can affect basic operations with FS. You mentioned that basic operations performed incorrectly (so the size is 0). That's why I asked for additional debug logs. It is better to reduce an area of searching to a couple of syscalls.

fantom-x commented 8 years ago

Similarly, for fuse_bufvec there is a 4-byte padding between "fuse_bufvec.off" and "fuse_bufvec.buf". Does this make sense?

g++ -D_FILE_OFFSET_BITS=64 fuse_size.cpp -o fuse_size && ./fuse_size

fuse_bufvec size is '40'
fuse_bufvec.count size is '4' offset is '0'
fuse_bufvec.idx   size is '4' offset is '4'
fuse_bufvec.off   size is '4' offset is '8'
fuse_bufvec.buf   size is '24' offset is '16'

fuse_buf size is '24'
fuse_buf.size size is '4' offset is '0'
fuse_buf.flags size is '4' offset is '4'
fuse_buf.mem size is '4' offset is '8'
fuse_buf.fd size is '4' offset is '12'
fuse_buf.pos size is '8' offset is '16'
SerCeMan commented 8 years ago

FuseBufVec is also used only in write_buf call which is disabled by default. FuseBuf looks like a correct structure.

We need to look only for overridden methods in MemoryFS class.

I think it is important to check debugging logs and FileStat structure.

fantom-x commented 8 years ago

Yup, that will be the next step. In the meantime, you are using "Struct.size" to get a size of a structure: how do I get size for a field? I will have to eventually check every single field and paddings...

SerCeMan commented 8 years ago

You can use offset() method

new FileStat(Runtime.getSystemRuntime()).st_ino.offset()
fantom-x commented 8 years ago

So use offset for the fields and offset for the paddings... Ok, that might work...

fantom-x commented 8 years ago

Turned out to be much more work than I expected so decided to go with fuse-jna instead: it already supports arm...

SerCeMan commented 8 years ago

@fantom-x, you can also try https://github.com/puniverse/javafs instead. I have no information about the state of that project, but, as far as I know, it tried to combine architecture of fuse-jna with JNR.