Merge branch 'master' into 3112-report-bug
[arvados.git] / services / keepstore / volume_unix.go
index 6960098c5a44166f2b1173d679625b3993d0567c..75a75229a6861f83f45b9264bab9d577d7d0f880 100644 (file)
@@ -103,13 +103,24 @@ func (v *UnixVolume) Touch(loc string) error {
        if err != nil {
                return err
        }
-       lockfile(f)
+       if e := lockfile(f); e != nil {
+               return e
+       }
        defer unlockfile(f)
        now := time.Now().Unix()
        utime := syscall.Utimbuf{now, now}
        return syscall.Utime(p, &utime)
 }
 
+func (v *UnixVolume) Mtime(loc string) (time.Time, error) {
+       p := v.blockPath(loc)
+       if fi, err := os.Stat(p); err != nil {
+               return time.Time{}, err
+       } else {
+               return fi.ModTime(), nil
+       }
+}
+
 // Read retrieves a block identified by the locator string "loc", and
 // returns its contents as a byte slice.
 //
@@ -248,19 +259,21 @@ func (v *UnixVolume) Delete(loc string) error {
        if err != nil {
                return err
        }
-       lockfile(f)
+       if e := lockfile(f); e != nil {
+               return e
+       }
        defer unlockfile(f)
 
-       // Return PermissionError if the block has been PUT more recently
-       // than -permission_ttl.  This guards against a race condition
-       // where a block is old enough that Data Manager has added it to
-       // the trash list, but the user submitted a PUT for the block
-       // since then.
+       // If the block has been PUT more recently than -permission_ttl,
+       // return success without removing the block.  This guards against
+       // a race condition where a block is old enough that Data Manager
+       // has added it to the trash list, but the user submitted a PUT
+       // for the block since then.
        if fi, err := os.Stat(p); err != nil {
                return err
        } else {
                if time.Since(fi.ModTime()) < permission_ttl {
-                       return PermissionError
+                       return nil
                }
        }
        return os.Remove(p)