7121: 7218: Get the serialize lock before opening a file.
authorTom Clegg <tom@curoverse.com>
Tue, 8 Sep 2015 15:05:45 +0000 (11:05 -0400)
committerTom Clegg <tom@curoverse.com>
Tue, 8 Sep 2015 15:05:45 +0000 (11:05 -0400)
In certain error cases (Stat() succeeds but Open() fails) this can
cause a failure to wait behind the serialize lock, but in normal
operation ("success" and "not found") it conserves open file handles
when there's a lot of contention for the serialize lock.

services/keepstore/volume_unix.go

index f91861a507018b64199efd0bdc5387bbb7e0e242..68ab06b5afa1ce7f8452cfe1ceda179d1f7745f1 100644 (file)
@@ -58,18 +58,18 @@ func (v *UnixVolume) Mtime(loc string) (time.Time, error) {
        }
 }
 
-// Open the given file, lock the "serialize" locker if enabled, and
+// Lock the locker (if one is in use), open the file for reading, and
 // call the given function if and when the file is ready to read.
 func (v *UnixVolume) getFunc(path string, fn func(io.Reader) error) error {
+       if v.locker != nil {
+               v.locker.Lock()
+               defer v.locker.Unlock()
+       }
        f, err := os.Open(path)
        if err != nil {
                return err
        }
        defer f.Close()
-       if v.locker != nil {
-               v.locker.Lock()
-               defer v.locker.Unlock()
-       }
        return fn(f)
 }