<br><br>
<div class="gmail_quote">2010/4/2 áÌÅËÓÅÊ áÎÔÉÐÏ× <span dir="ltr"><<a href="mailto:1a_antipov@mail.ru">1a_antipov@mail.ru</a>></span><br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">As goes from GLib sources, the final replace strategy is backend-dependent.<br>For local files: (from GLib sources, gio/glocalfileoutputstream.c, handle_overwrite_open):<br>
š/* We use two backup strategies.<br>š * The first one (which is faster) consist in saving to a<br>š * tmp file then rename the original file to the backup and the<br>š * tmp file to the original name. This is fast but doesn't work<br>
š * when the file is a link (hard or symbolic) or when we can't<br></blockquote>
<div>š</div>
<div>I don't understand why it fails with a hard link, all filesš*are* hard links so that means it would never work, do you understand what they mean?</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">š * write to the current dir or can't set the permissions on the<br>š * new file.<br>š * The second strategy consist simply in copying the old file<br>
š * to a backup file and rewrite the contents of the file.<br>š */<br></blockquote>
<div>š</div>
<div>Yup, thats as I understand the process</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">For smb:// files (from GVFS sources, daemon/gvfsbackendsmb.c, do_replace)<br>š/* Backup strategy:<br>š š š *<br>
š š š * By default we:<br>š š š * š1) save to a tmp file (that doesn't exist already)<br>š š š * š2) rename orig file to backup file<br>š š š * š š (or delete it if no backup)<br>š š š * š3) rename tmp file to orig file<br>
š š š *<br>š š š * However, this can fail if we can't write to the directory.<br>š š š * In that case we just truncate the file, after having<br>š š š * copied directly to the backup filename.<br>š š š */<br></blockquote>

<div>š</div>
<div>I don't like the bit about truncating the file, how did it copy the backup if it can't write?</div>
<div>š</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">SFTP backend strategy is much more complex<br>So, let's sum it all up<br><br>1. There are (at least) 3 different ways to save a file:<br>
š- Use POSIX fopen()/fwrite() API<br>š- Use g_file_set_contents()<br>š- Use GIO API<br><br>2. On remote filesystems at least first (and probably second) API relies on GIO (via virtual filesystem calls or direct<br>GIO calls in newer GLib versions)</blockquote>

<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>3. No API guarantees that data on remote filesystem won't be lost and the save would be "atomic", as the implementation<br>
is in the backend, which can be buggy etc.<br></blockquote>
<div>š</div>
<div>Yes, so Geany should be careful but not paranoid, some things it just can't control.</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>4. The strategy used by GIO on local filesystem seems satisfactory for "safe file saving" needs.<br>
</blockquote>
<div>š</div>
<div>Yes, its probably the best.</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>5. All we can do is minimize the probability of data loss due to our code issues. We cannot directly affect troubles in<br>
GLib and GVFS (IMHO they are messy, but one should contact these projects' teams to improve that)<br></blockquote>
<div>š</div>
<div>Agree</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>6. The less (buggy) code there is between Geany and final data transfers (either to disk, or via HTTP/FTP/SMB/SSH/whatever-else), the more reliable our project is<br>
</blockquote>
<div>š</div>
<div>Agree</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>7. That's why the use of direct GIO calls instead of fopen() or g_file_set_contents() is attractive. Consider the chains:<br>
(1) fopen()/fwrite() -> VFS call -> GIO g_file_do_something() -> Backend -> Final data transfer<br></blockquote>
<div>š</div>
<div>I don't understand why the C library calls fopen and fwrite call GIO, for file systems supported natively on the platform they should directly perform actions on that file system, for others they would have to go via fuse and the path you have shown, unless GVFS is taking over the whole file system and forcing all file system operations via itself :-( very bad if so.š Impacts performance, reliability and maintainability.</div>

<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">OR<br>(2a) g_file_set_contents -> fopen()/fwrite() -> VFS call -> GIO g_file_do_something() -> Backend -> Final data transfer<br>
OR<br></blockquote>
<div>š</div>
<div>As per note above.</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">(2b) g_file_set_contents -> GIO g_file_do_something() -> Backend -> Final data transfer<br>OR<br>
(3) GIO g_file_do_something() -> Backend -> Final data transfer<br><br>8. The only alternative for g_file_replace here is to write our own backup algorithm implementation, preferably based on direct GIO calls.<br><br>
</blockquote>
<div>š</div>
<div>As I said above Geany needs to be careful, not paranoid, so I don't think adding another layer is sensible.š Geany also needs to be portable so it needs to handle GIO when available and non-GIO when not and windows with similar levels of competence.š If there are problems in the backends I would not expect Geany to compensate for them.</div>

<div>š</div>
<div>Cheers</div>
<div>Lex</div>
<div>š</div>
<div>š</div>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">Fri, 2 Apr 2010 21:35:49 +1100 ÐÉÓØÍÏ ÏÔ Lex Trotman <<a href="mailto:elextr@gmail.com">elextr@gmail.com</a>>:<br>

<div>
<div></div>
<div class="h5"><br>> On 2 April 2010 03:07, Nick Treleaven <<a href="mailto:nick.treleaven@btinternet.com">nick.treleaven@btinternet.com</a>> wrote:<br>><br>> > On Thu, 1 Apr 2010 12:41:13 +0100<br>> > Nick Treleaven <<a href="mailto:nick.treleaven@btinternet.com">nick.treleaven@btinternet.com</a>> wrote:<br>
> ><br>> > > > Btw, the bugs with GVFS didn't appear with GNOME 2.26 (and probably<br>> > before), so I think we can safely use fopen() and fprintf()/fwrite() there.<br>> > Then, your proposal about version separation (use GIO with GLib>=2.16 and<br>
> > fopen()/g_file_set_contents() with other) is extremely attractive. Do you<br>> > know if there is a way to get GLib version at runtime, not at compile-time<br>> > (so that there is no need to rebuild all the packages for different<br>
> > versions)?<br>> > > ><br>> > > > I'm going to start working on it; if this is OK, I'll send a patch<br>> > ASAP.<br>> > ><br>> > > BTW There is another problem that file saving should solve - not<br>
> > > losing existing file data when there is no space to save the new file.<br>> > > Does g_file_replace_contents() handle this problem? (g_file_set_contents<br>> > > () does handle this but as you mention has other problems).<br>
> ><br>> > According to the docs for g_file_replace, which g_file_replace_contents<br>> > uses internally, this case may be handled:<br>> ><br>> > "This will try to replace the file in the safest way possible so that<br>
> > any errors during the writing will not affect an already existing copy<br>> > of the file. For instance, for local files it may write to a temporary<br>> > file and then atomically rename over the destination when the stream is<br>
> > closed."<br>> > <a href="http://library.gnome.org/devel/gio/unstable/GFile.html#g-file-replace" target="_blank">http://library.gnome.org/devel/gio/unstable/GFile.html#g-file-replace</a><br>> ><br>
> > Hopefully it still keeps permissions if the rename is done(!)<br>> ><br>><br>> I would doubt it :-( its creating the new temporary file then renaming that<br>> to the original name. šThis leaves it with the permissions of the temporary<br>
> file ie those of a new file.<br>> It might work if it copies the attributes of the old file to the temporary<br>> first, but thats a backend dependent action since permissions depend on the<br>> filesystem..<br>
> But it does leave the old file unharmed on out of space :-)<br>><br>> The problem is that remote file systems (most anyway) šdo not actually have<br>> an atomic rename and delete operation. šIn fact many actually have race<br>
> conditions when you try to remove the old file and then rename the temporary<br>> as a non-atomic pair of operations. šSo just because it seems to work for<br>> one application doesn't mean it will allways work for it with a different<br>
> remote file system. šSomething like that can be the cause of an empty file.<br>><br>> Cheers<br>> Lex<br>><br>><br>> > Regards,<br>> > Nick<br>> > _______________________________________________<br>
> > Geany-devel mailing list<br>> > <a href="mailto:Geany-devel@uvena.de">Geany-devel@uvena.de</a><br>> > <a href="http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel" target="_blank">http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel</a><br>
> ><br>><br>> _______________________________________________<br>> Geany-devel mailing list<br>> <a href="mailto:Geany-devel@uvena.de">Geany-devel@uvena.de</a><br>> <a href="http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel" target="_blank">http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel</a><br>
><br>><br><br><br></div></div>"âÁÒÁÈÏÌËÁ" ÎÁ ôÏ×ÁÒÙ@Mail.Ru. ðÏËÕÐÁÊ ÄÅÛÅ×Ï, ÐÒÏÄÁ×ÁÊ ×ÙÇÏÄÎÏ. <a href="http://r.mail.ru/cln4270/torg.mail.ru/used/" target="_blank">http://r.mail.ru/cln4270/torg.mail.ru/used/</a><br>

<div>
<div></div>
<div class="h5">_______________________________________________<br>Geany-devel mailing list<br><a href="mailto:Geany-devel@uvena.de">Geany-devel@uvena.de</a><br><a href="http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel" target="_blank">http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel</a><br>
</div></div></blockquote></div><br>