Trash mechanism

Alexander Larsson alexl at redhat.com
Thu Aug 26 15:22:59 EEST 2004


On Thu, 2004-08-26 at 12:49, David Faure wrote:
> On Thursday 26 August 2004 10:14, Alexander Larsson wrote:
> > Well. Lets take a common situation such as removing all the files on a
> > floppy, or in a more modern situation, a SecureDigital flashcard from
> > your camera. 
> > 
> > Removing the files is just a metadata operation that is really fast.
> > However if you copy files to a trash on another disk, this could
> > potentially take a long time. Reading all the images from my SD card
> > takes several minutes. Will the user really expect this normally fast
> > operation to get a progress dialog and take several minutes to execute.
> 
> OK, I see where our difference of opinion on this comes from.
> Nautilus offers only one "Delete" operation in the GUI, and tries to choose
> the best way of deleting the file, either move-to-trash or real-delete.
> Konqueror offers both "Delete" and "Move To Trash", so there's no problem
> with handling removable media: the user can choose between "fast, real deletion"
> and "slow, but safer move-to-trash operation which keeps a copy of the files
> in $HOME/.Trash".

Nautilus does in fact have a preference called "Include a Delete command
that bypasses Trash" that lets you get both operation. But in my opinion
thats not a very elegant solution. You force the user to learn the
difference and think about which one to use when they delete files.
Which one does KDE bind to the delete key btw? Thats likely to be used
often (without thinking about which form of delete that causes).

> > We do mtab parsing too, for instance to detect all mounted systems
> > looking for trash directories. However experience has shown me that mtab
> > parsing is a bit fragile, and its also not very portable (i.e. it needs
> > lot of ifdefs). 
> Yep. But now that it's there and debugged, I might as well use it :)

Sure, we just have to remember that the implementations here might
differ a bit in the exact details, so we can't rely on both getting
things exactly the same.

> > I checked out what OS X does by testing my USB flashcard reader. It uses
> > a way similar to Nautilus. When you trash something on the flash it
> > creates a ".Trashes" directory on the root of the drive, and under that
> > it creates a directory with the name being the uid of the user (I guess
> > that makes some sense, especially on filesystems where you store the
> > owner as a uid), where it stores the files as-is. 
> Doesn't really help making room on the flashcard reader...

No. You have to delete and then empty trash, which also coincidentally
empties the trash on all other disks. Not that great imho.

> > You mention "generated name" for the tempfile, but in like 99% of all
> > cases there won't be a collision, and i think using the real name is
> > helpful if you ever manually look into the trash dir. If the real name
> > doesn't work, using some algorithm like appending " (copy $n)" or
> > something should work fine.
> Hmm. In theory that's opening for race conditions (if multiple programs
> try trashing a file with same name at the same time - this is because we'll 
> be doing this in a kioslave, i.e. letting several programs benefit from this,
> in particular kdesktop and konqueror initially). But of course since trashing
> a file is a user-requested operation, he'd have to be pretty fast with his mouse :)

How is this different from the case of a random filename? Two files
could accidentally pick the same random filename. The race condition is
always there, and is solved the same way mkstemp solves it, by using
O_EXCL. Of course, the race is still there if you use nfs and trash two
files with the same time on two different machines. Thats rather
unlikely though. And if it ever happens in the history of the universe
we still only lost data that is being deleted.

> So, OK, why not. We still need to differenciate fileid and filename
> though (I call fileid the name of the deleted file on disk, and filename the real
> user-visible name, coming from original-location, and used when displaying the 
> contents of the trash and restoring the file). 
> But you're right, if the fileid is still "readable", then we'll have prettier URLs.
> 
> OK... Let's say we use the initial filename as id when possible.
> ~/.Trash/files/foo.png
> ~/.Trash/info/foo.png  (the text file with two lines in it)
> 
> (is it ok if I use info instead of metadata? we use the metadata term already for
> something else in kioslaves and it will get confusing :)

Thats fine.

> Now if I delete another foo.png file, the internal id could be "foo (copy).png"
> or "foo.png.2" or whatever - this doesn't need to be standardized indeed,
> the ids don't matter. info/foo.png.2 would still say info.png in the original
> location, so we can actually display that name when listing the trash, as long
> as the url for the two files is different.
> So the url scheme would simply be trash:/<fileid> and trash:/<fileid>/file1.txt
> (and trash:/<fileid>/subdir/file2.txt etc.) if <fileid> is actually a directory.
> 
> The only downside of readable fileids is the risk of mixing up fileid and
> filename during implementation, a risk that doesn't exist with tempfilenames :-)
> (mental picture problem).

Yeah, we need to make this very clear in the spec.

> > What about filesystem operations in trash://? For instance, the names
> > presented for the files shown in trash:// are not the real filenames, so
> > if you rename a file then we can't rename the file. Should we instead
> > rewrite the original filename/location in the metadata?
> That could be done. Or we can simply disable renaming of trashed files.
> People can rename the file _after_ restoring it anyway.
> 
> > What if you create a folder there, what do we set the original location to?
> Creating things directly in the trash should simply be forbidden.

Yeah.

> > What about this usage for trash folders:
> > 
> > If the file is on the same device as $home, use $home/.Trash. Otherwise
> > check for an existing writable ".Trash" in the top dir of the filesystem
> > of the file. If it exists, use (create if needed) $topdir/.Trash/$uid as
> > the trash directory. If the .Trash directory doesn't exists, its up to
> > the implementation to either create it if possible (I don't recommend
> > implementations to do this for removable media, but detecting that case
> > is a bit hard and the detection might differ between implementations),
> > use $home/.Trash, or just not support trashing the file.
> How would ownership work with .Trash/$uid instead of .Trash-$uid?
> The user creating the .Trash directory would need to make it world-writable, right?

Yeah. We should probably also make it world unreadable and with sticky
bit (like /tmp) so that you can't look at it, and rename or remove other
peoples trash dirs. Of course, even with the sticky bit set the person
who creates the .Trash dir can still rename/remove other users trash
dirs. I dunno what to do about that.

> But I see the benefit over the .Trash-$uid solution indeed, for cases where
> the sysadmin doesn't want to give write access to everyone in the filesystem root.
> And at the same time, if we auto-create trash dirs that way, we don't have to
> rely on the sysadmin, and this can still be useful (e.g. my /mnt/devel is owned
> by "dfaure", so auto-creating a .Trash in there will mean much faster trashing
> than moving to $home/.Trash, just because I forgot to create .Trash by hand).
> OK for $topdir/.Trash/$uid/ then.

Cool.

> > This way each implementation will always use the same directory,
> > sysadmins *can* set up trash directories for filesystems, and its still
> > up to the implementations to choose how trashing is handled (unless you
> > move media between implementations).
> Well the whole point of this standardization is to be able to move media
> (or open the same trash) between implementations. Why "unless"...?

What i mean by unless is that if you bring something from implemenation
'a' to implementation 'b' and 'a' chose to create a .Trash dir, then 'b'
isn't free to choose whether to use it or not. To be interoperable we
must always use the directory if there is one. When you handle
"pristine" disks/media/whatever implemenation 'b' is free to do whatever
he wants.

> As long as we find the .Trash directories created by the other implementations, 
> we can see all trashed files, it doesn't matter if those files were rename()d
> or actually copied there. I mean if you create a .Trash on removeable media
> and I wouldn't, I'll still see it when opening the trash-can.

Sure.

> OK, it seems to me that we're converging here. I guess we need to write
> a more formal spec than pointing people to this thread? :/

Yes.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl at redhat.com    alla at lysator.liu.se 
He's a lounge-singing hunchbacked boxer on a mission from God. She's a cynical 
kleptomaniac nun from beyond the grave. They fight crime! 




More information about the xdg mailing list