Overlayfs copy-up creates an empty file

345 Views Asked by At

I'm doing something which is kind of weird, creating an overlayfs mount in which the lower directory is a FUSE volume (which I've implemented). This seems to mostly work, I can read files from the FUSE mount through the overlayfs mount, and they have the right content. I can also create new files in the overlayfs mount, which is unsurprising since that should just require that the lower FUSE layer return an ENOENT response when you try to LOOKUP that file. What fails is when I attempt to append to an existing file, instead of getting the existing content followed by the appended content, I just get the appended content. I'm assuming that there must be something that my FUSE volume is supposed to be doing that it isn't, that's causing this error. However looking at logs it's not complaining about any unimplemented methods and nothing is erroring. Here are the logs for the relevent file ("foo").

2020/04/15 10:35:42 rx 9: LOOKUP i9223372036854775808 ["foo"] 4b
2020/04/15 10:35:42 tx 9:     OK, {i9223372036854775809 g0 tE=0s tA=0s {M0100644 SZ=0 L=0 0:0 B0*0 i0:9223372036854775809 A 0.000000 M 0.000000 C 0.000000}}
2020/04/15 10:35:42 rx 10: OPEN i9223372036854775809 {O_RDONLY,0x8000}
2020/04/15 10:35:42 tx 10:     OK, {Fh 1 }
2020/04/15 10:35:42 rx 11: GETATTR i9223372036854775809 {Fh 0}
2020/04/15 10:35:42 tx 11:     OK, {tA=0s {M0100600 SZ=4 L=1 0:0 B8*4096 i0:9223372036854775809 A 1586972142.827290 M 1586972142.855292 C 1586972142.855292}}
2020/04/15 10:35:42 rx 12: GETATTR i9223372036854775809 {Fh 1}
2020/04/15 10:35:42 tx 12:     OK, {tA=0s {M0100600 SZ=4 L=1 0:0 B8*4096 i0:9223372036854775809 A 1586972142.827290 M 1586972142.855292 C 1586972142.855292}}
2020/04/15 10:35:42 rx 13: READ i9223372036854775809 {Fh 1 [0 +4096)  L 0 NONBLOCK,0x8000}
2020/04/15 10:35:42 tx 13:     OK,  4096b data (fd data)
2020/04/15 10:35:42 rx 14: GETATTR i9223372036854775809 {Fh 1}
2020/04/15 10:35:42 tx 14:     OK, {tA=0s {M0100600 SZ=4 L=1 0:0 B8*4096 i0:9223372036854775809 A 1586972142.855292 M 1586972142.855292 C 1586972142.855292}}
2020/04/15 10:35:42 rx 15: FLUSH i9223372036854775809 {Fh 1}
2020/04/15 10:35:42 tx 15:     OK
2020/04/15 10:35:42 rx 16: RELEASE i9223372036854775809 {Fh 1 NONBLOCK,0x8000  L0}
2020/04/15 10:35:42 tx 16:     OK
2020/04/15 10:35:42 rx 17: GETATTR i9223372036854775808 {Fh 0}
2020/04/15 10:35:42 tx 17:     OK, {tA=0s {M040755 SZ=0 L=0 0:0 B0*0 i0:9223372036854775808 A 0.000000 M 0.000000 C 0.000000}}
2020/04/15 10:35:42 rx 18: LISTXATTR i9223372036854775808 {sz 0}
2020/04/15 10:35:42 tx 18:     OK
2020/04/15 10:35:42 rx 19: GETATTR i9223372036854775809 {Fh 0}
2020/04/15 10:35:42 tx 19:     OK, {tA=0s {M0100644 SZ=0 L=0 0:0 B0*0 i0:9223372036854775809 A 0.000000 M 0.000000 C 0.000000}}
2020/04/15 10:35:42 rx 20: LISTXATTR i9223372036854775809 {sz 0}
2020/04/15 10:35:42 tx 20:     OK

The fuse layer is written in go if that matters at all.

1

There are 1 best solutions below

0
On

First of all, this setup is not so weird. Second, you will have much better chance of getting an answer on [email protected].

But anyway, as far as I can tell, the problem seems to be in your fuse fs:

2020/04/15 10:35:42 rx 9: LOOKUP i9223372036854775808 ["foo"] 4b 2020/04/15 10:35:42 tx 9: OK, {i9223372036854775809 g0 tE=0s tA=0s {M0100644 SZ=0 L=0 0:0 B0*0 i0:9223372036854775809 A 0.000000 M 0.000000 C 0.000000}}

2020/04/15 10:35:42 rx 19: GETATTR i9223372036854775809 {Fh 0} 2020/04/15 10:35:42 tx 19: OK, {tA=0s {M0100644 SZ=0 L=0 0:0 B0*0 i0:9223372036854775809 A 0.000000 M 0.000000 C 0.000000}}

Not sure why, but your fs reports the size of the file found on lookup as zero, while later when reading the file, the size is reported correctly as 4.

I expect if you run stat(1) or ls -l on your fuse fs you may also observe this problem. It could be that you implemented fstat(2) correctly but not lstat(2)?

Thanks, Amir.