X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b7f7878f8f0648ba5a53e24abb109ce9ad59bfc3..fbd54468b13466839c24d880a3d041d0a49371af:/services/keepstore/volume_unix.go diff --git a/services/keepstore/volume_unix.go b/services/keepstore/volume_unix.go index 98c31d1eab..0dd1d82a98 100644 --- a/services/keepstore/volume_unix.go +++ b/services/keepstore/volume_unix.go @@ -23,6 +23,9 @@ type unixVolumeAdder struct { } func (vs *unixVolumeAdder) Set(value string) error { + if trashLifetime != 0 { + return ErrNotImplemented + } if dirs := strings.Split(value, ","); len(dirs) > 1 { log.Print("DEPRECATED: using comma-separated volume list.") for _, dir := range dirs { @@ -189,7 +192,7 @@ func (v *UnixVolume) Get(loc string) ([]byte, error) { path := v.blockPath(loc) stat, err := v.stat(path) if err != nil { - return nil, err + return nil, v.translateError(err) } buf := bufs.Get(int(stat.Size())) err = v.getFunc(path, func(rdr io.Reader) error { @@ -209,7 +212,7 @@ func (v *UnixVolume) Get(loc string) ([]byte, error) { func (v *UnixVolume) Compare(loc string, expect []byte) error { path := v.blockPath(loc) if _, err := v.stat(path); err != nil { - return err + return v.translateError(err) } return v.getFunc(path, func(rdr io.Reader) error { return compareReaderWithBuf(rdr, expect, loc[:32]) @@ -292,6 +295,7 @@ func (v *UnixVolume) Status() *VolumeStatus { } var blockDirRe = regexp.MustCompile(`^[0-9a-f]+$`) +var blockFileRe = regexp.MustCompile(`^[0-9a-f]{32}$`) // IndexTo writes (to the given Writer) a list of blocks found on this // volume which begin with the specified prefix. If the prefix is an @@ -348,6 +352,9 @@ func (v *UnixVolume) IndexTo(prefix string, w io.Writer) error { if !strings.HasPrefix(name, prefix) { continue } + if !blockFileRe.MatchString(name) { + continue + } _, err = fmt.Fprint(w, name, "+", fileInfo[0].Size(), @@ -359,7 +366,7 @@ func (v *UnixVolume) IndexTo(prefix string, w io.Writer) error { } // Delete deletes the block data from the unix storage -func (v *UnixVolume) Delete(loc string) error { +func (v *UnixVolume) Trash(loc string) error { // Touch() must be called before calling Write() on a block. Touch() // also uses lockfile(). This avoids a race condition between Write() // and Delete() because either (a) the file will be deleted and Touch() @@ -371,6 +378,9 @@ func (v *UnixVolume) Delete(loc string) error { if v.readonly { return MethodDisabledError } + if trashLifetime != 0 { + return ErrNotImplemented + } if v.locker != nil { v.locker.Lock() defer v.locker.Unlock() @@ -401,6 +411,12 @@ func (v *UnixVolume) Delete(loc string) error { return os.Remove(p) } +// Untrash moves block from trash back into store +// TBD +func (v *UnixVolume) Untrash(loc string) error { + return ErrNotImplemented +} + // blockDir returns the fully qualified directory name for the directory // where loc is (or would be) stored on this volume. func (v *UnixVolume) blockDir(loc string) string { @@ -479,3 +495,16 @@ func lockfile(f *os.File) error { func unlockfile(f *os.File) error { return syscall.Flock(int(f.Fd()), syscall.LOCK_UN) } + +// Where appropriate, translate a more specific filesystem error to an +// error recognized by handlers, like os.ErrNotExist. +func (v *UnixVolume) translateError(err error) error { + switch err.(type) { + case *os.PathError: + // stat() returns a PathError if the parent directory + // (not just the file itself) is missing + return os.ErrNotExist + default: + return err + } +}