filestore: be more specific when there is a problem reading the backing file.
License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
Kevin Atkinson committed
Feb 3, 2017 at 18:34 UTC
886a6fe166c7144e01da66e8a3822137f6cd9838
2 files changed
+43
-15
filestore/fsrefstore.go
+22
-7
@@ -27,8 +27,18 @@ type FileManager struct {
27
root string
28
}
29
30
+type CorruptReferenceCode int
31
+
32
+const (
33
+ OtherErr CorruptReferenceCode = 0
34
+ FileError CorruptReferenceCode = 1
35
+ FileMissing CorruptReferenceCode = 2
36
+ FileChanged CorruptReferenceCode = 3
37
+)
38
+
39
type CorruptReferenceError struct {
31
- Err error
40
+ Code CorruptReferenceCode
41
+ Err error
42
}
43
44
func (c CorruptReferenceError) Error() string {
@@ -127,20 +137,24 @@ func (f *FileManager) readDataObj(c *cid.Cid, d *pb.DataObj) ([]byte, error) {
137
abspath := filepath.Join(f.root, p)
138
139
fi, err := os.Open(abspath)
130
- if err != nil {
131
- return nil, &CorruptReferenceError{err}
140
+ if os.IsNotExist(err) {
141
+ return nil, &CorruptReferenceError{FileMissing, err}
142
+ } else if err != nil {
143
+ return nil, &CorruptReferenceError{FileError, err}
144
}
145
defer fi.Close()
146
147
_, err = fi.Seek(int64(d.GetOffset()), os.SEEK_SET)
148
if err != nil {
137
- return nil, &CorruptReferenceError{err}
149
+ return nil, &CorruptReferenceError{FileError, err}
150
}
151
152
outbuf := make([]byte, d.GetSize_())
153
_, err = io.ReadFull(fi, outbuf)
142
- if err != nil {
143
- return nil, &CorruptReferenceError{err}
154
+ if err == io.EOF || err == io.ErrUnexpectedEOF {
155
+ return nil, &CorruptReferenceError{FileChanged, err}
156
+ } else if err != nil {
157
+ return nil, &CorruptReferenceError{FileError, err}
158
}
159
160
outcid, err := c.Prefix().Sum(outbuf)
@@ -149,7 +163,8 @@ func (f *FileManager) readDataObj(c *cid.Cid, d *pb.DataObj) ([]byte, error) {
163
}
164
165
if !c.Equals(outcid) {
152
- return nil, &CorruptReferenceError{fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())}
166
+ return nil, &CorruptReferenceError{FileChanged,
167
+ fmt.Errorf("data in file did not match. %s offset %d", d.GetFilePath(), d.GetOffset())}
168
}
169
170
return outbuf, nil
filestore/util.go
+21
-8
@@ -16,12 +16,12 @@ import (
16
type Status int32
17
18
const (
19
- StatusOk Status = 0
20
- StatusFileError Status = 10 // Backing File Error
21
- //StatusFileNotFound Status = 11 // Backing File Not Found
22
- //StatusFileChanged Status = 12 // Contents of the file changed
23
- StatusOtherError Status = 20 // Internal Error, likely corrupt entry
24
- StatusKeyNotFound Status = 30
19
+ StatusOk Status = 0
20
+ StatusFileError Status = 10 // Backing File Error
21
+ StatusFileNotFound Status = 11 // Backing File Not Found
22
+ StatusFileChanged Status = 12 // Contents of the file changed
23
+ StatusOtherError Status = 20 // Internal Error, likely corrupt entry
24
+ StatusKeyNotFound Status = 30
25
)
26
27
func (s Status) String() string {
@@ -30,6 +30,10 @@ func (s Status) String() string {
30
return "ok"
31
case StatusFileError:
32
return "error"
33
+ case StatusFileNotFound:
34
+ return "no-file"
35
+ case StatusFileChanged:
36
+ return "changed"
37
case StatusOtherError:
38
return "ERROR"
39
case StatusKeyNotFound:
@@ -139,8 +143,17 @@ func mkListRes(c *cid.Cid, d *pb.DataObj, err error) *ListRes {
143
if err != nil {
144
if err == ds.ErrNotFound || err == blockstore.ErrNotFound {
145
status = StatusKeyNotFound
142
- } else if _, ok := err.(*CorruptReferenceError); ok {
143
- status = StatusFileError
146
+ } else if err, ok := err.(*CorruptReferenceError); ok {
147
+ switch err.Code {
148
+ case FileError:
149
+ status = StatusFileError
150
+ case FileMissing:
151
+ status = StatusFileNotFound
152
+ case FileChanged:
153
+ status = StatusFileChanged
154
+ default:
155
+ status = StatusOtherError
156
+ }
157
} else {
158
status = StatusOtherError
159
}