Bugs: Browse | Submit New | Admin

[#3716] FuseFS exported over samba

Date:
2006-03-03 14:28
Priority:
3
Submitted By:
Julien Perville (mira)
Assigned To:
Greg Millam (walker)
Category:
None
State:
Open
Summary:
FuseFS exported over samba

Detailed description
Hi Greg, and first let me thanks for your great FuseFS library.

I am not going to be much liked here (as I am posting the first bug report) but I do have a bug (or at least a strange
and reproductible behavior) to report.


  - I am developping a file system prototype with FuseFS. This file system will interact with our internal SCM tool.
When I export my mount point over samba and try to copy a file, every file is created with the correct size but some
have garbage content. Used locally, no issue to report.

  - Please note that not all write operations done by the Win2k box through Samba end up generating corrupted files.
As an exemple, if I cd to the FUSE managed directory and invoke 'copy ..\README.txt' (MS command line program), the
file will be saved to disk just fine but if I call 'cp README.txt .' (Cygwin binary) I get garbage in the file.

  - All regular Windows GUI and command line programs work fine. The programs that give me trouble are Cygwin binaries
and java programs, which is unfortunate since the SCM client is written in Java.

  - If I use the raw_* interface, I do can observe that I receive the expected content from the Samba layer (and the
buffer grows just fine in the library's internal rf_write function). However the rf_release never gets called and the
buffer never gets flushed to disk. the write_to hook never gets called and I end up with a junk file of the exact same
size as the real file.

  - I suspect that some interaction is happening between the cygwin/java binaries, Samba and my file system about caching
behavior. Do Cygwin and Windows programs have a different way to close (or not close) files over a network drive?

  - Strangely, if I execute the failing command a 2nd time, I end up with an apparently correct copy of the file. For
example, invoking 'cp ../README.txt . ; cp ../README.txt .' will do it.

  - If I modify the file content between the 2 copies, I get the correct version. The problem seems to happen if the
file does not exist on disk yet?

  - Note that the problem does not happen when working on the network share with OSX or Linux. Only on Windows using
alien binaries.


How to reproduce (step by step):

I wrote an example File System named 'KleptoFS' as it grabs all files that get copied to it and only releases them upon
shutdown (CTRL-C). Permission given to include in FuseFS' sample directory if you find it "useful" (or funny)
enough.


  - mount the KleptoFS, let's say in ~/bottomless-pocket

$ mkdir bottomless-pocket
$ ruby kleptofs.rb bottomless-pocket

  - create some entries in the bottomless hole

$ cd bottomless-pocket
$ echo "Banknotes" > wallet
More wallet for my collection!
$ echo "Old Napoleon coins" > chest
More chest for my collection!
$ echo "Obvious Patents" > IP-portfolio
More IP-portfolio for my collection!

  - play with the File system. end with CTRL-C

  - now try to copy a file from a Windows box configured as samba client.

z:> cd bottomless-pocket
z:> copy \README.txt

  - CTRL-C on the Linux box. We can see the first characters from README.txt

  - Try again with a Cygwin binary:

z:> cp ../README.txt .
cp: ./README.txt: Permission denied

  - CTRL-C on the Linux box, notice that the content of the copied file is memory garbage. Copy twice.

z:> cp ../README.txt .
cp: ./README.txt: Permission denied

z:> cp ../README.txt .

  - CTRL-C. File content is correct on the Linux side. Notice that there was no error message for the 2nd cp command
on Windows side.


Add A Comment: Notepad

Please login


Followup

Message
Date: 2006-03-31 07:35
Sender: Julien Perville

Okay, good news (or should I say, bad news for you Greg!), I
reproduced the bug exactly as I posted earlier here, with
recent and old cygwin binaries.

I had to revert my debian sandbox from testing to stable and
the bug magically reappeared.

The kernel and the FUSE kernel modules are exactly the same,
I did not recompile in between. The FUSE library and the
fusefs were in both cases compiled from the latest sources
(not using the obsolete debian package for FUSE).

I am no specialist of troubleshooting obscure interactions
between the compiler/glibc/ruby/something-else versions that
end up triggering a bug in the fusefs ruby bindings.

I am attaching a log of the debug output of fusefs.

The following is the exact commands that I typed to take the
debug log, so that you can follow

(on Linux side, with my "kleptofs" mounted to ~/cache)
$ cp /etc/hosts ~

(on the Windows side, where the Z: volume maps to a samba
home on the Linux side)
$ z:
$ copy hosts cache\hosts-copy (windows command, works as
expected)
$ cp hosts cache/hosts-cp (cygwin command, copy fails with
"no space left on device" error, but a file still gets
created with junk content)

(back on the Linux side, CTRL-C to exit the FS driver)

The Windows output:

---
C:\>z:

Z:\>copy hosts cache\hosts-copy
        1 file(s) copied.

Z:\>cp hosts cache/hosts-cp
cp: writing `cache/hosts-cp': No space left on device

---

The Linux output:

---
mira@colinux:~$ ruby misc/kleptofs.rb cache/
** notice: truncating content from 71 to 20 bytes.
More hosts-copy for my collection!
** notice: truncating content from 71 to 20 bytes.
More hosts-cp for my collection!
Look what I just found...
... some
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\00
0\000\000\000\000\000"
right in front of my hosts-cp...
... some "127.0.0.1 localhost" lost in my
hosts-copy...
That's it!
---

Please notice the chain of nil characters for the
cygwin-created entry. I had to modify the kleptofs example
to "inspect" the string stored else we would only see
an
"empty string" when we have an empty string of the
same size
as the file which was supposed to be copied.
Date: 2006-03-30 12:54
Sender: Julien Perville

Dear Gred,

I am sorry that I can not reproduce the bug right now. I
have since then upgraded the ancient cygwin and the linux
box and the problem does not show anymore.

I am going to reinstall a debian stable and get a zip of the
company's default cygwin install and will report my progress.

Sincerely,
Julien Perville
Date: 2006-03-30 09:28
Sender: Greg Millam

This is interesting. As I don't have access to a windows box,
can you compile fusefs with debug enabled and email me the output
when using this without the workaround enabled? (walker
at rubyforge.org)

Thanks!

To enable debug: add the following line to the very top
of fusefs_lib.c (not fusefs_fuse.c).

#define DEBUG
Date: 2006-03-03 14:40
Sender: Julien Perville

After 2 days trying to solve the problem, I found a work-around:

Since the bug does not happen if the target already exists
on the disk, I forced creation of a empty file in raw_open,
then return false so that the normal write_to hook gets
called on an existing file and the bug does not trigger anymore.

  def raw_open(path,mode)
    if mode=='w' and not File.exist?(path) then
      puts "## Force creating file #{path} - workaround
##"
      write_to(path,'')
      false
    end
  end

Attached Files:

Name Description Download
kleptofs.rb Sample FuseFS class with write enabled to test the problem Download
klepto-trace.txt Debug-enabled trace reproducing the bug Download

Changes:

Field Old Value Date By
File Added532: klepto-trace.txt2006-03-31 07:43mira
assigned_tonone2006-03-30 09:28walker
File Added496: kleptofs.rb2006-03-03 14:28mira