fusefrontend: report an error if all files in a directory were invalid

Just presenting an empty directory means that the user does not know
that things went wrong unless he checks the syslog or tries to delete
the directory.

It would be nice to report the error even if only some files were
invalid. However, go-fuse does not allow returning the valid
directory entries AND an error.
This commit is contained in:
Jakob Unterwurzacher 2016-06-04 16:39:27 +02:00
parent 4ee612b36e
commit a602e798b1
1 changed files with 30 additions and 12 deletions

View File

@ -226,8 +226,11 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
return nil, fuse.ToStatus(err) return nil, fuse.ToStatus(err)
} }
} }
// Filter and decrypt filenames
// Decrypted directory entries
var plain []fuse.DirEntry var plain []fuse.DirEntry
var errorCount int
// Filter and decrypt filenames
for i := range cipherEntries { for i := range cipherEntries {
cName := cipherEntries[i].Name cName := cipherEntries[i].Name
if dirName == "" && cName == configfile.ConfDefaultName { if dirName == "" && cName == configfile.ConfDefaultName {
@ -244,29 +247,44 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
continue continue
} }
// Handle long file name
isLong := nametransform.LongNameNone
if fs.args.LongNames { if fs.args.LongNames {
isLong := nametransform.NameType(cName) isLong = nametransform.NameType(cName)
if isLong == nametransform.LongNameContent { }
cNameLong, err := nametransform.ReadLongName(filepath.Join(cDirAbsPath, cName)) if isLong == nametransform.LongNameContent {
if err != nil { cNameLong, err := nametransform.ReadLongName(filepath.Join(cDirAbsPath, cName))
toggledlog.Warn.Printf("Could not read long name for file %s, skipping file", cName) if err != nil {
continue toggledlog.Warn.Printf("Skipping file %q in dir %q: Could not read .name: %v",
} cName, cDirName, err)
cName = cNameLong errorCount++
} else if isLong == nametransform.LongNameFilename {
// ignore "gocryptfs.longname.*.name"
continue continue
} }
cName = cNameLong
} else if isLong == nametransform.LongNameFilename {
// ignore "gocryptfs.longname.*.name"
continue
} }
name, err := fs.nameTransform.DecryptName(cName, cachedIV) name, err := fs.nameTransform.DecryptName(cName, cachedIV)
if err != nil { if err != nil {
toggledlog.Warn.Printf("Skipping invalid name '%s' in dir '%s': %s", toggledlog.Warn.Printf("Skipping invalid name %q in dir %q: %s",
cName, cDirName, err) cName, cDirName, err)
errorCount++
continue continue
} }
cipherEntries[i].Name = name cipherEntries[i].Name = name
plain = append(plain, cipherEntries[i]) plain = append(plain, cipherEntries[i])
} }
if errorCount > 0 && len(plain) == 0 {
// Don't let the user stare on an empty directory. Report that things went
// wrong.
toggledlog.Warn.Printf("All %d entries in directory %q were invalid, returning EIO",
errorCount, cDirName)
status = fuse.EIO
}
return plain, status return plain, status
} }