[Geany-devel] Changed file saving implementation for systems with GIO

Dimitar Zhekov dimitar.zhekov at xxxxx
Fri Nov 5 19:08:39 UTC 2010


On Thu, 04 Nov 2010 23:37:28 +0100
Colomban Wendling <lists.ban at herbesfolles.org> wrote:

> Le 04/11/2010 21:42, Dimitar Zhekov a ecrit :
> > 
> > For more than 20 years now, the only safe save is to write the data
> > into a temporary file in the same directory, and then rename it over
> > the target file. Even if the rename fails, you still have the temporary
> > file. That changes the onwership and permissions, which is exactly the
> > behaviour of the safe g_file_set_contents().
> Well... stop me if I'm saying bullshit but what about:

No, you are not; I should have been more specific. It's the only way
which requires 2x disk space (that is unavoidable) but not 2x I/O. For
Geany the latter doesn't matter so much, but glib is a general purpose
library, and that's why it includes a safe method that modifies the
metadata and links, and an unsafe method (documented as "the safest way
possible", no less!), which preserves them.

Our choices are:

1. The unsafe old or GIO method. Already supported.
2. The safe glib method which modifies the metadata/links. Supported
for GIO = false, easy to include for GIO = true.
3. Our own method, which is safe, but generates 2x the I/O (minimum).
4. Our own method, based on the safe glib method, which preserves at
least the ownership and permissions (but even that fails sometimes).

> backup = path + '~' # or whatever
> if copy (path, backup_path): # COPY file to the backup
>   if not write (path, data): # write in original file
>     move (backup_path, path) # if write failed, restore backup
>   elif not make_backup:
>     unlink (backup_path) # if no backup is to be done, delete backup

That'll be fine if backups are on, but as Lex pointed out, does too much
I/O if they are off. So for backups = false we can:

a. Create filename-foo, write data to it, abort and unlink on failure.
b. Write data to filename. On failure, rename filename-foo to filename,
and notify the user that the metadata and links are lost.
c. If even the rename fails, which is highly unlikely for files in the
same directory, inform the user that the original file is _probably_
lost, and if so, filename-foo contains the data, but lacks the
metadata and links.

(probably, because remote filesystems may do the rename but fail to
report it; that's specially mentioned for NFS in rename(2):BUGS)

(filename-foo and not filename~, because we don't our insurance file
containing the _new_ data to be replaced by some accidential backup, be
it Geany's (if the user subsequently turned backups on) or cp's, mv's
etc.)

> The problems I see are:
>  1) needs at least 2 times the size of the file in the target directory
>     (but it's the same anytime we bake backups)

Unavoidable.

>  2) backup file may have altered permissions/attrs

...links, ACL-s etc. Unavoidable.

>  3) ...so if write fails, we have changed the permissions/attrs on the
>     original file

Unavoidable.

> In the worst case, the original file has another name and lost its
> permissions/attrs.

Unavoidable. Alas, no miracles for us.

Being a bit lazy, I'd prefer to include the safe glib method in the GIO
code path (with the use_safe_file_saving option, as before) and be
done with it. So for limited disk space and/or unstable connections,
just turn the option on, we even have a GUI for that now. It's a
compromise, but what isn't?..

-- 
E-gards: Jimmy



More information about the Devel mailing list