Bug#680418: gvfs-fuse: Wrongly sucessful posix fwrite call on a gvfs sftp mount can lead to data loss

Andreas Henriksson andreas at fatal.se
Thu Jul 12 19:16:46 UTC 2012


Hi Nicolas!

I've only had the chance to briefly look at your bug report.
Looks like it could be a valid bug, but your analysis seems a bit confused!

Please see my comments inline below...

On Thu, Jul 05, 2012 at 08:18:29PM +0200, Nicolas Anonyme wrote:
[...]
> /// 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 :

That's glibc... not gvfs.
Try a simple test program that does an fwrite >4096 bytes you can see it's
being split up without gvfs being involved at all.

> 	// [    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

Opening the same file again, before closing it, in append mode seems like a
recepie for disaster... but ok.... anyway, you probably want to make sure to
fsync your file handle before doing this to make sure the data is actually
written out.

> 	/// (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)

This seems interesting.... but your description is not correct.
You're not tracing the gvfs writes here.. you're tracing your own applications
writes....

Please note that you have TWO additional layers involved here.
At the bottom, you have the gvfs sftp backend, then on top of that you have
the gvfs fuse daemon (and then ofcourse you have your own application at the
top). All these run in separate processes and you're only tracing your own
proccess.... you can't really see how gvfs behaves from only tracing
your own process.


> 	// [    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);
>   }
> }

Given that the strace is tracing the order of your writes against the gvfs
fuse daemon, then I don't think it's much gvfs can do when the writes
arrive in this order... Could very well be considered an application bug.
On the other hand if it's possible to actually track down a problem in gvfs,
it wouldn't be the first time the fuse backend wasn't perfect so I wouldn't
be surprised in that case either...

-- 
Andreas Henriksson





More information about the pkg-gnome-maintainers mailing list