Package: gvfs-fuse Version: 1.12.3-1+b1 Severity: critical Tags: upstream Justification: causes serious data loss
Dear Maintainer, * What led up to the situation? After some of my files got truncated at 4096 bytes when saved in leafpad over agvfs sftp mount, I did some debug, and found that the bug was apparently in gvfs fuse sftp module. * What exactly did you do that was effective? I wrote a small C soft that could reproduce the bug when trying to write a 5k txt file over the sftp gvfs mount : - Mount a sftp location with gvfs : gvfs-mount "sftp://${USER}@localhost" - compile and run the small piece of software : - The fwrite() posix call returns a number of bytes of the expected len, - But the gvfs layer buffers it and does not write the totality of the data immediatly, - The software opens the same file in append mode, and that seems to invalidate the subsequent write calls of the gvfs layer. - As a result the text file is truncated at 4kbyte on the remote disk * What outcome did you expect instead? the text file should weight 5kbyte as "gfvs-fuse also supports exposing the gvfs mounts to non-gio applications using fuse. " The bug with leafpad + sftp + gvfs also exist in ubuntu as I found bug report on launchpad, so it's probably upstream. I joined the commented C code of my debug case. I hope it can help a little, and I apologise for my bad English. Thank you for reading this. -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (550, 'testing'), (550, 'stable'), (500, 'stable-updates'), (500, 'proposed-updates'), (33, 'unstable') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-2-amd64 (SMP w/2 CPU cores) Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages gvfs-fuse depends on: ii fuse 2.9.0-2 ii gvfs 1.12.3-1+b1 ii libc6 2.13-33 ii libdbus-1-3 1.6.0-1 ii libfuse2 2.9.0-2 ii libglib2.0-0 2.32.3-1 gvfs-fuse recommends no packages. gvfs-fuse suggests no packages. -- no debconf information
/// Filename : write5kfile.c /// Compile with : /// gcc `pkg-config --cflags glib-2.0 gtk+-2.0` `pkg-config --libs glib-2.0 gtk+-2.0` write5kfile.c -o write5kfile #include <gtk/gtk.h> #include <stdio.h> #include <string.h> /// Functions adapted from original leafpad source code gboolean check_file_writable(gchar *filename) { FILE *fp; if ((fp = fopen(filename, "a")) != NULL) { fclose(fp); return TRUE; } return FALSE; } int save(char* filename) { FILE *fp; gchar *str, *cstr; gsize len; gsize written; /// We want to write this 5k of text str = g_strnfill(5 * 1024, '*'); len = strlen(str); fp = fopen(filename, "w"); if (!fp) { printf("Can't open file to write\n"); return -1; } written = fwrite(str, 1, len, fp); /// The call to fwrite returns written == len == 5120 /// But at first the underlaying gvfs mount only write 4096 bytes : // [ 7f6343c62500] open("~/.gvfs/${mounted_ssh_dir}/tmp/5k.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 // [ 7f6343c62750] write(3, "********************************"..., 4096) = 4096 /// The soft then open the same file in append mode before the file is closed /// (indirectly caused by gtk_text_buffer_set_modified(buffer, FALSE); in original leafpad) check_file_writable(filename); // [ 7f6343c62500] open("~/.gvfs/${mounted_ssh_dir}/tmp/5k.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4 // [ 7f6343c62690] close(4) = 0 /// Then the underlaying gvfs mount try to write the remaining 1024 bytes, but fails ! // [ 7f6343c62750] write(3, "********************************"..., 1024) = -1 EOPNOTSUPP (Operation not supported) // [ 7f6343c62690] close(3) = 0 /// The file is then closed fclose(fp); g_free(str); printf("written=%d, expected=%d\n", written, len); /// As expected the software think all was correctly written // [ 7f6343c62750] write(1, "written=5120, expected=5120\n", 28written=5120, expected=5120 if (written != len) { printf("Can't write file\n"); return -1; } return 0; } int main(int argc, char *argv[]) { if(argc != 2){ printf("How to use :\n"); printf(" * First mount a sftp with gvfs : \n"); printf(" gvfs-mount \"sftp://${USER}@localhost\"\n"); printf(" * Then run the soft (optionaly with strace) :\n"); printf(" strace -i -e trace=write,open,stat,read,close,signal \\\n"); printf(" %s ~/.gvfs/your_mounted_ssh_dir/tmp/5k.txt\n", argv[0]); } else { char* filename = argv[1]; save(filename); } }