Skip to content

Files

Latest commit

 

History

History

ea-file-bundle-handling

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ea-file-bundle-handling

This directory contains scripts to manage files on a Synology share in conjunction with their extended attributes' sidecar files. For every file stored on a Synology share, Synology may maintain a @SynoEAStream and/or @SynoResource file. Which file is present (one, both or none) depends on the file attributes as set by the Finder when copying/creating the file, or added later by the Finder. For extensive information about the gory details on what is stored where and how (and gory they are...), see the separate directory on extended attributes. The general structure on disk (the native Synology ext4 or btrfs file system) is:

  • share/directory/file
  • share/directory/@eaDir/file@SynoEAStream
  • share/directory/@eaDir/file@SynoResource

where file could also be a directory:

  • share/directory/dir/
  • share/directory/@eaDir/dir@SynoEAStream
  • share/directory/@eaDir/dir@SynoResource

The scripts handle these files as a file bundle when they are moved/renamed (mv_with_ea), deleted (rm_with_ea, rmdir_with_ea), check if a directory is truly empty (isemptydir_with_ea) or create a hard link in a different place (ln_with_ea). There is also a script that gets rid of all extraneous @Syno files (cleanup_SynoFiles).

mv_with_ea

The mv_with_ea moves or renames the file or directory to a new location or name and moves/renames the @Syno files with it in a consistent manner. The only thing that is not updated instantly is the corresponding FinderInfo data in the cnid.db database of the afpd, but no worry, I've found that that is updated as soon as the file is exposed to the Finder of a connected Mac OS client and the @Syno files are queried.

rm_with_ea, rmdir_with_ea

These scripts work sort of as expected, I guess.

isemptydir_with_ea

Script to test if a directory is empty, if the @eaDir subdirectory is taken into account (i.e. is ignored - with an @eaDir directory present, the directory would never be empty, even without any regular files or directories in it).

ln_with_ea

The ln_with_ea script creates a hard link of a file in a different directory on the same file system. It works the same as the ln command (without the -s because that's for sissies) but also hardlinks (or even backlinks) its associated @Syno files if they are present. This allows the hard linked file to share the extended attributes (xattr) of the file it was created from (note: as opposed to ln -s, with ln there is no such thing as an original file, only an originating file). The great thing about it is that, after hard linking a file, the extended attributes can be changed on the linked file as well as the originating file.

There's one optimisation added to the mix: the (back)linking of the @SynoEAStream file only takes place if it contains a 'non-bogus' extended attribute. This is maintained in xattrs.lst. This filter was added after I discovered that Apple stores a whole lot of bogus information in the extended attributes (com.apple.quarantine is an annoying one, but com.apple.lastuseddate#PS is probably the worst). For instance, if you want to link the attribute describing 'the file was downloaded from URL', you should add com.apple.metadata:kMDItemWhereFroms and possibly com.apple.metadata:kMDItemDownloadedDate to the xattr.lst. If you don't want this, just edit line 84 in the script.

The most useful xattr for me is the com.apple.metadata:_kMDItemUserTags, which is the xattr in which the user tags are stored (both the 'old-style' labels (Finder colours) and the custom Tags. See the directory with tools for handling extended attributes and Finder tags.

cleanup_SynoFiles

After using the Synology NAS for a while, I found out that it stored literally thousands of files that don't really contribute in a functional way. These files were sometimes left behind after an incomplete cleanup or delete, but are mostly created through Finder extended attributes and resource forks (actually, that's where the pollution started a long time ago). It results in every regular file having at least two additional sidecar files associated with it, and sometimes more. It does slow down the system, hence this script to get rid of them.

The script scans for and cleans a directory for any extraneous @Syno sidecar files. With 'extraneous', I mean:

  • the 'stray' @SynoEAStream and @SynoResource files, i.e. files that don't have a parent (regular) file.
  • any subdirectories inside the @eaDir directories (these are used by Synology to store previews, so if you have Photo Station, Audio Station or Video Station running, you will not want this), SYNO_DTIME delete timestamps (left behind after restoring files from the #recycle bin), and other paraphernalia).
  • the 'bogus' @SynoEAStream and @SynoResource files ('bogus' means the files don't have any of the meaningful xattrs listed in xattrs.lst, as discussed above - this might need some tweaking to your own taste as I can't determine which xattrs you find useful).
  • when deleting, it also cleans up any empty @eaDir directories that are left behind.

When used with -l, it just lists the extraneous files on stdout, and does not delete anything.

After running this script, there will still be some trailing metadata on the file system. This is logical, because any file that has one of the meaningful extended attributes, will also retain any other (non-meaningful) extended attribute. The script deals with the @Syno files, i.e. all attributes (or none) and therefore can not delete extended attributes that are stored amongst other extended attributes. You need to run xattr -d from the Mac OS X Terminal to do this. Here's a bash one-liner for the not-so-faint-of-heart:

xattr -r /Volumes/share/ | grep -v -f xattrs.lst | grep -v com.apple.FinderInfo | while read line ; do file=${line%: com.apple*} ; attr="com.apple.${line#*: com.apple.}" ; echo xattr -d "$attr" "$file" ; done | sort -k 3

After reviewing the output (and be amazed how much garbage is stored in the extended attributes!), remove the echo and the | sort -k 3) and let it rip.