Skip to content

Commit e6e8f4b

Browse files
committed
Properly map method errors
1 parent ac5a50b commit e6e8f4b

24 files changed

+507
-286
lines changed

errors.go

+6
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ func basicErrorFormatter(err error) RPCError {
167167
// NFSStatusError represents an error at the NFS level.
168168
type NFSStatusError struct {
169169
NFSStatus
170+
WrappedErr error
170171
}
171172

172173
// Error is The wrapped error
@@ -186,6 +187,11 @@ func (s *NFSStatusError) MarshalBinary() (data []byte, err error) {
186187
return resp[:], nil
187188
}
188189

190+
// Unwrap unpacks wrapped errors
191+
func (s *NFSStatusError) Unwrap() error {
192+
return s.WrappedErr
193+
}
194+
189195
// StatusErrorWithBody is an NFS error with a payload.
190196
type StatusErrorWithBody struct {
191197
NFSStatusError

file.go

+35-15
Original file line numberDiff line numberDiff line change
@@ -136,29 +136,49 @@ func tryStat(fs billy.Filesystem, path []string) *FileAttribute {
136136
}
137137

138138
// WriteWcc writes the `wcc_data` representation of an object.
139-
func WriteWcc(writer io.Writer, pre *FileCacheAttribute, post *FileAttribute) {
139+
func WriteWcc(writer io.Writer, pre *FileCacheAttribute, post *FileAttribute) error {
140140
if pre == nil {
141-
_ = xdr.Write(writer, uint32(0))
141+
if err := xdr.Write(writer, uint32(0)); err != nil {
142+
return err
143+
}
142144
} else {
143-
_ = xdr.Write(writer, uint32(1))
144-
_ = xdr.Write(writer, *pre)
145+
if err := xdr.Write(writer, uint32(1)); err != nil {
146+
return err
147+
}
148+
if err := xdr.Write(writer, *pre); err != nil {
149+
return err
150+
}
145151
}
146152
if post == nil {
147-
_ = xdr.Write(writer, uint32(0))
153+
if err := xdr.Write(writer, uint32(0)); err != nil {
154+
return err
155+
}
148156
} else {
149-
_ = xdr.Write(writer, uint32(1))
150-
_ = xdr.Write(writer, *post)
157+
if err := xdr.Write(writer, uint32(1)); err != nil {
158+
return err
159+
}
160+
if err := xdr.Write(writer, *post); err != nil {
161+
return err
162+
}
151163
}
164+
return nil
152165
}
153166

154167
// WritePostOpAttrs writes the `post_op_attr` representation of a files attributes
155-
func WritePostOpAttrs(writer io.Writer, post *FileAttribute) {
168+
func WritePostOpAttrs(writer io.Writer, post *FileAttribute) error {
156169
if post == nil {
157-
_ = xdr.Write(writer, uint32(0))
170+
if err := xdr.Write(writer, uint32(0)); err != nil {
171+
return err
172+
}
158173
} else {
159-
_ = xdr.Write(writer, uint32(1))
160-
_ = xdr.Write(writer, *post)
174+
if err := xdr.Write(writer, uint32(1)); err != nil {
175+
return err
176+
}
177+
if err := xdr.Write(writer, *post); err != nil {
178+
return err
179+
}
161180
}
181+
return nil
162182
}
163183

164184
// SetFileAttributes represents a command to update some metadata
@@ -185,7 +205,7 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
185205
mode := os.FileMode(*s.SetMode) & os.ModePerm
186206
if mode != curr.Mode().Perm() {
187207
if changer == nil {
188-
return &NFSStatusError{NFSStatusNotSupp}
208+
return &NFSStatusError{NFSStatusNotSupp, os.ErrPermission}
189209
}
190210
if err := changer.Chmod(file, mode); err != nil {
191211
return err
@@ -203,7 +223,7 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
203223
}
204224
if euid != curr.UID || egid != curr.GID {
205225
if changer == nil {
206-
return &NFSStatusError{NFSStatusNotSupp}
226+
return &NFSStatusError{NFSStatusNotSupp, os.ErrPermission}
207227
}
208228
if err := changer.Lchown(file, int(euid), int(egid)); err != nil {
209229
return err
@@ -212,7 +232,7 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
212232
}
213233
if s.SetSize != nil {
214234
if curr.Mode()&os.ModeSymlink != 0 {
215-
return &NFSStatusError{NFSStatusNotSupp}
235+
return &NFSStatusError{NFSStatusNotSupp, os.ErrInvalid}
216236
}
217237
fp, err := fs.Open(file)
218238
if err != nil {
@@ -237,7 +257,7 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
237257
}
238258
if atime != curr.Atime.Native() || mtime != curr.Mtime.Native() {
239259
if changer == nil {
240-
return &NFSStatusError{NFSStatusNotSupp}
260+
return &NFSStatusError{NFSStatusNotSupp, os.ErrPermission}
241261
}
242262
if err := changer.Chtimes(file, *atime, *mtime); err != nil {
243263
return err

go.mod

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ require (
66
github.com/go-git/go-billy/v5 v5.0.0
77
github.com/google/uuid v1.1.1
88
github.com/hashicorp/golang-lru v0.5.4
9-
github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 // indirect
109
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93
10+
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a // indirect
1111
github.com/willscott/go-nfs-client v0.0.0-20200605172546-271fa9065b33
1212
github.com/willscott/memphis v0.0.0-20200912205913-768fef98189f
13-
go.polydawn.net/go-timeless-api v0.0.0-00010101000000-000000000000 // indirect
14-
go.polydawn.net/rio v0.0.0-00010101000000-000000000000
1513
)
1614

1715
replace go.polydawn.net/go-timeless-api => github.com/polydawn/go-timeless-api v0.0.0-20190707220600-0ece408663ed

go.sum

+9
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agR
33
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
44
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
55
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
67
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
78
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
89
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
10+
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
911
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
1012
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
1113
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
14+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1215
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
16+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
1317
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
1418
github.com/polydawn/go-timeless-api v0.0.0-20190707220600-0ece408663ed h1:WzzCCfq6k2m5d+FT2JRoeH+knLiA1aNWDuqTy6CZnDs=
1519
github.com/polydawn/go-timeless-api v0.0.0-20190707220600-0ece408663ed/go.mod h1:z2fMUifgtqrZiNLgzF4ZR8pX+YFLCmAp1jJTSTvyDMM=
@@ -19,10 +23,14 @@ github.com/polydawn/rio v0.0.0-20200325050149-e97d9995e350 h1:4fkF5MLSMdVPu+Or1+
1923
github.com/polydawn/rio v0.0.0-20200325050149-e97d9995e350/go.mod h1:mwZtAu36D3fSNzVLN1we6PFdRU4VeE+RXLTZiOiQlJ0=
2024
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 h1:UVArwN/wkKjMVhh2EQGC0tEc1+FqiLlvYXY5mQ2f8Wg=
2125
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93/go.mod h1:Nfe4efndBz4TibWycNE+lqyJZiMX4ycx+QKV8Ta0f/o=
26+
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
2227
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
28+
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
2329
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
2430
github.com/warpfork/go-errcat v0.0.0-20180917083543-335044ffc86e h1:FIB2fi7XJGHIdf5rWNsfFQqatIKxutT45G+wNuMQNgs=
2531
github.com/warpfork/go-errcat v0.0.0-20180917083543-335044ffc86e/go.mod h1:/qe02xr3jvTUz8u/PV0FHGpP8t96OQNP7U9BJMwMLEw=
32+
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w=
33+
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
2634
github.com/willscott/go-nfs-client v0.0.0-20200605172546-271fa9065b33 h1:Wd8wdpRzPXskyHvZLyw7Wc1fp5oCE2mhBCj7bAiibUs=
2735
github.com/willscott/go-nfs-client v0.0.0-20200605172546-271fa9065b33/go.mod h1:cOUKSNty+RabZqKhm5yTJT5Vq/Fe83ZRWAJ5Kj8nRes=
2836
github.com/willscott/memphis v0.0.0-20200912205913-768fef98189f h1:b+G0cnCRLaSCGLPV/mXpDaqVrPdOIKx0y59wENVFUBI=
@@ -35,4 +43,5 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0
3543
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3644
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
3745
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
46+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
3847
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

nfs_onaccess.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,20 @@ import (
1111
func onAccess(ctx context.Context, w *response, userHandle Handler) error {
1212
roothandle, err := xdr.ReadOpaque(w.req.Body)
1313
if err != nil {
14-
// TODO: wrap
15-
return err
14+
return &NFSStatusError{NFSStatusInval, err}
1615
}
1716
fs, path, err := userHandle.FromHandle(roothandle)
1817
if err != nil {
19-
return &NFSStatusError{NFSStatusStale}
18+
return &NFSStatusError{NFSStatusStale, err}
2019
}
2120
mask, err := xdr.ReadUint32(w.req.Body)
2221
if err != nil {
23-
// TODO: wrap
24-
return err
22+
return &NFSStatusError{NFSStatusInval, err}
2523
}
2624

2725
writer := bytes.NewBuffer([]byte{})
2826
if err := xdr.Write(writer, uint32(NFSStatusOk)); err != nil {
29-
return err
27+
return &NFSStatusError{NFSStatusServerFault, err}
3028
}
3129
WritePostOpAttrs(writer, tryStat(fs, path))
3230

@@ -35,7 +33,10 @@ func onAccess(ctx context.Context, w *response, userHandle Handler) error {
3533
}
3634

3735
if err := xdr.Write(writer, mask); err != nil {
38-
return err
36+
return &NFSStatusError{NFSStatusServerFault, err}
3937
}
40-
return w.Write(writer.Bytes())
38+
if err := w.Write(writer.Bytes()); err != nil {
39+
return &NFSStatusError{NFSStatusServerFault, err}
40+
}
41+
return nil
4142
}

nfs_oncommit.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package nfs
33
import (
44
"bytes"
55
"context"
6+
"os"
67

78
"github.com/go-git/go-billy/v5"
89
"github.com/willscott/go-nfs-client/nfs/xdr"
@@ -13,17 +14,16 @@ func onCommit(ctx context.Context, w *response, userHandle Handler) error {
1314
w.errorFmt = wccDataErrorFormatter
1415
handle, err := xdr.ReadOpaque(w.req.Body)
1516
if err != nil {
16-
// TODO: wrap
17-
return err
17+
return &NFSStatusError{NFSStatusInval, err}
1818
}
1919
// The conn will drain the unread offset and count arguments.
2020

2121
fs, path, err := userHandle.FromHandle(handle)
2222
if err != nil {
23-
return &NFSStatusError{NFSStatusStale}
23+
return &NFSStatusError{NFSStatusStale, err}
2424
}
2525
if !billy.CapabilityCheck(fs, billy.WriteCapability) {
26-
return &NFSStatusError{NFSStatusServerFault}
26+
return &NFSStatusError{NFSStatusServerFault, os.ErrPermission}
2727
}
2828

2929
writer := bytes.NewBuffer([]byte{})
@@ -33,13 +33,16 @@ func onCommit(ctx context.Context, w *response, userHandle Handler) error {
3333

3434
// no pre-op cache data.
3535
if err := xdr.Write(writer, uint32(0)); err != nil {
36-
return err
36+
return &NFSStatusError{NFSStatusServerFault, err}
3737
}
3838
WritePostOpAttrs(writer, tryStat(fs, path))
3939
// write the 8 bytes of write verification.
4040
if err := xdr.Write(writer, w.Server.ID); err != nil {
41-
return err
41+
return &NFSStatusError{NFSStatusServerFault, err}
4242
}
4343

44-
return w.Write(writer.Bytes())
44+
if err := w.Write(writer.Bytes()); err != nil {
45+
return &NFSStatusError{NFSStatusServerFault, err}
46+
}
47+
return nil
4548
}

nfs_oncreate.go

+31-24
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"log"
7+
"os"
78

89
"github.com/go-git/go-billy/v5"
910
"github.com/willscott/go-nfs-client/nfs/xdr"
@@ -20,98 +21,104 @@ func onCreate(ctx context.Context, w *response, userHandle Handler) error {
2021
obj := DirOpArg{}
2122
err := xdr.Read(w.req.Body, &obj)
2223
if err != nil {
23-
// TODO: wrap
24-
return err
24+
return &NFSStatusError{NFSStatusInval, err}
2525
}
2626
how, err := xdr.ReadUint32(w.req.Body)
2727
if err != nil {
28-
return err
28+
return &NFSStatusError{NFSStatusInval, err}
2929
}
3030
var attrs *SetFileAttributes
3131
if how == createModeUnchecked || how == createModeGuarded {
3232
sattr, err := ReadSetFileAttributes(w.req.Body)
3333
if err != nil {
34-
return err
34+
return &NFSStatusError{NFSStatusInval, err}
3535
}
3636
attrs = sattr
3737
} else if how == createModeExclusive {
3838
// read createverf3
3939
var verf [8]byte
4040
if err := xdr.Read(w.req.Body, &verf); err != nil {
41-
return err
41+
return &NFSStatusError{NFSStatusInval, err}
4242
}
4343
log.Printf("failing create to indicate lack of support for 'exclusive' mode.")
4444
// TODO: support 'exclusive' mode.
45-
return &NFSStatusError{NFSStatusNotSupp}
45+
return &NFSStatusError{NFSStatusNotSupp, os.ErrPermission}
4646
} else {
4747
// invalid
48-
return &NFSStatusError{NFSStatusNotSupp}
48+
return &NFSStatusError{NFSStatusNotSupp, os.ErrInvalid}
4949
}
5050

5151
fs, path, err := userHandle.FromHandle(obj.Handle)
5252
if err != nil {
53-
return &NFSStatusError{NFSStatusStale}
53+
return &NFSStatusError{NFSStatusStale, err}
5454
}
5555
if !billy.CapabilityCheck(fs, billy.WriteCapability) {
56-
return &NFSStatusError{NFSStatusROFS}
56+
return &NFSStatusError{NFSStatusROFS, os.ErrPermission}
5757
}
5858

5959
if len(string(obj.Filename)) > PathNameMax {
60-
return &NFSStatusError{NFSStatusNameTooLong}
60+
return &NFSStatusError{NFSStatusNameTooLong, nil}
6161
}
6262

6363
newFilePath := fs.Join(append(path, string(obj.Filename))...)
6464
if s, err := fs.Stat(newFilePath); err == nil {
6565
if s.IsDir() {
66-
return &NFSStatusError{NFSStatusExist}
66+
return &NFSStatusError{NFSStatusExist, nil}
6767
}
6868
if how == createModeGuarded {
69-
return &NFSStatusError{NFSStatusExist}
69+
return &NFSStatusError{NFSStatusExist, os.ErrPermission}
7070
}
7171
} else {
7272
if s, err := fs.Stat(fs.Join(path...)); err != nil {
73-
return &NFSStatusError{NFSStatusAccess}
73+
return &NFSStatusError{NFSStatusAccess, err}
7474
} else if !s.IsDir() {
75-
return &NFSStatusError{NFSStatusNotDir}
75+
return &NFSStatusError{NFSStatusNotDir, nil}
7676
}
7777
}
7878

7979
file, err := fs.Create(newFilePath)
8080
if err != nil {
8181
log.Printf("Error Creating: %v", err)
82-
return &NFSStatusError{NFSStatusAccess}
82+
return &NFSStatusError{NFSStatusAccess, err}
8383
}
8484
if err := file.Close(); err != nil {
8585
log.Printf("Error Creating: %v", err)
86-
return &NFSStatusError{NFSStatusAccess}
86+
return &NFSStatusError{NFSStatusAccess, err}
8787
}
8888

8989
fp := userHandle.ToHandle(fs, append(path, file.Name()))
9090
changer := userHandle.Change(fs)
9191
if err := attrs.Apply(changer, fs, newFilePath); err != nil {
9292
log.Printf("Error applying attributes: %v\n", err)
93-
return &NFSStatusError{NFSStatusIO}
93+
return &NFSStatusError{NFSStatusIO, err}
9494
}
9595

9696
writer := bytes.NewBuffer([]byte{})
9797
if err := xdr.Write(writer, uint32(NFSStatusOk)); err != nil {
98-
return err
98+
return &NFSStatusError{NFSStatusServerFault, err}
9999
}
100100

101101
// "handle follows"
102102
if err := xdr.Write(writer, uint32(1)); err != nil {
103-
return err
103+
return &NFSStatusError{NFSStatusServerFault, err}
104104
}
105105
if err := xdr.Write(writer, fp); err != nil {
106-
return err
106+
return &NFSStatusError{NFSStatusServerFault, err}
107+
}
108+
if err := WritePostOpAttrs(writer, tryStat(fs, append(path, file.Name()))); err != nil {
109+
return &NFSStatusError{NFSStatusServerFault, err}
107110
}
108-
WritePostOpAttrs(writer, tryStat(fs, append(path, file.Name())))
109111

110112
// dir_wcc (we don't include pre_op_attr)
111113
if err := xdr.Write(writer, uint32(0)); err != nil {
112-
return err
114+
return &NFSStatusError{NFSStatusServerFault, err}
115+
}
116+
if err := WritePostOpAttrs(writer, tryStat(fs, path)); err != nil {
117+
return &NFSStatusError{NFSStatusServerFault, err}
113118
}
114-
WritePostOpAttrs(writer, tryStat(fs, path))
115119

116-
return w.Write(writer.Bytes())
120+
if err := w.Write(writer.Bytes()); err != nil {
121+
return &NFSStatusError{NFSStatusServerFault, err}
122+
}
123+
return nil
117124
}

0 commit comments

Comments
 (0)