Skip to content

Commit 767fb8e

Browse files
committed
fix bugs to allow successful creating, setting attributes, writing
1 parent 16f58a7 commit 767fb8e

7 files changed

+65
-42
lines changed

conn.go

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func (c *conn) handle(ctx context.Context, w *response) error {
129129
return drainErr
130130
}
131131
if appError != nil && !w.responded {
132+
log.Printf("call to %+v failed: %v", handler, appError)
132133
if err := c.err(ctx, w, appError); err != nil {
133134
return err
134135
}

file.go

+31-18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package nfs
22

33
import (
44
"io"
5+
"log"
56
"os"
67
"syscall"
78
"time"
@@ -127,8 +128,10 @@ func ToFileAttribute(info os.FileInfo) FileAttribute {
127128
// WritePostOpAttrs writes the `post_op_attr` representation of a files attributes
128129
func WritePostOpAttrs(writer io.Writer, fs billy.Filesystem, path []string) {
129130
attrs, err := fs.Stat(fs.Join(path...))
130-
if err != nil {
131+
if err != nil || attrs == nil {
132+
log.Printf("err writing attrs for %s: %v", fs.Join(path...), err)
131133
_ = xdr.Write(writer, uint32(0))
134+
return
132135
}
133136
_ = xdr.Write(writer, uint32(1))
134137
_ = xdr.Write(writer, ToFileAttribute(attrs))
@@ -148,23 +151,24 @@ type SetFileAttributes struct {
148151
// Apply uses a `Change` implementation to set defined attributes on a
149152
// provided file.
150153
func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, file string) error {
151-
cur := func() *FileAttribute {
152-
curOS, err := fs.Lstat(file)
153-
if err != nil {
154-
return nil
155-
}
156-
curr := ToFileAttribute(curOS)
157-
return &curr
154+
curOS, err := fs.Lstat(file)
155+
if err != nil {
156+
return nil
158157
}
158+
curr := ToFileAttribute(curOS)
159159

160160
if s.SetMode != nil {
161161
mode := os.FileMode(*s.SetMode) & os.ModePerm
162-
if err := changer.Chmod(file, mode); err != nil {
163-
return err
162+
if mode != curr.Mode().Perm() {
163+
if changer == nil {
164+
return &NFSStatusError{NFSStatusNotSupp}
165+
}
166+
if err := changer.Chmod(file, mode); err != nil {
167+
return err
168+
}
164169
}
165170
}
166171
if s.SetUID != nil || s.SetGID != nil {
167-
curr := cur()
168172
euid := curr.UID
169173
if s.SetUID != nil {
170174
euid = *s.SetUID
@@ -173,12 +177,17 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
173177
if s.SetGID != nil {
174178
egid = *s.SetGID
175179
}
176-
if err := changer.Lchown(file, int(euid), int(egid)); err != nil {
177-
return err
180+
if euid != curr.UID || egid != curr.GID {
181+
if changer == nil {
182+
return &NFSStatusError{NFSStatusNotSupp}
183+
}
184+
if err := changer.Lchown(file, int(euid), int(egid)); err != nil {
185+
return err
186+
}
178187
}
179188
}
180189
if s.SetSize != nil {
181-
if cur().Mode()&os.ModeSymlink != 0 {
190+
if curr.Mode()&os.ModeSymlink != 0 {
182191
return &NFSStatusError{NFSStatusNotSupp}
183192
}
184193
fp, err := fs.Open(file)
@@ -194,7 +203,6 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
194203
}
195204

196205
if s.SetAtime != nil || s.SetMtime != nil {
197-
curr := cur()
198206
atime := curr.Atime.Native()
199207
if s.SetAtime != nil {
200208
atime = s.SetAtime
@@ -203,8 +211,13 @@ func (s *SetFileAttributes) Apply(changer billy.Change, fs billy.Filesystem, fil
203211
if s.SetMtime != nil {
204212
mtime = s.SetMtime
205213
}
206-
if err := changer.Chtimes(file, *atime, *mtime); err != nil {
207-
return err
214+
if atime != curr.Atime.Native() || mtime != curr.Mtime.Native() {
215+
if changer == nil {
216+
return &NFSStatusError{NFSStatusNotSupp}
217+
}
218+
if err := changer.Chtimes(file, *atime, *mtime); err != nil {
219+
return err
220+
}
208221
}
209222
}
210223
return nil
@@ -261,7 +274,7 @@ func ReadSetFileAttributes(r io.Reader) (*SetFileAttributes, error) {
261274
if hasSize != 0 {
262275
var size uint64
263276
attrs.SetSize = &size
264-
if err := xdr.Read(r, size); err != nil {
277+
if err := xdr.Read(r, &size); err != nil {
265278
return nil, err
266279
}
267280
}

nfs_oncreate.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,19 @@ func onCreate(ctx context.Context, w *response, userHandle Handler) error {
8383

8484
fp := userHandle.ToHandle(fs, append(path, file.Name()))
8585
changer := userHandle.Change(fs)
86-
if changer != nil {
87-
if err := attrs.Apply(changer, fs, newFilePath); err != nil {
88-
return &NFSStatusErrorWithWccData{NFSStatusIO}
89-
}
86+
if err := attrs.Apply(changer, fs, newFilePath); err != nil {
87+
return &NFSStatusErrorWithWccData{NFSStatusIO}
9088
}
9189

9290
writer := bytes.NewBuffer([]byte{})
9391
if err := xdr.Write(writer, uint32(NFSStatusOk)); err != nil {
9492
return err
9593
}
9694

95+
// "handle follows"
96+
if err := xdr.Write(writer, uint32(1)); err != nil {
97+
return err
98+
}
9799
if err := xdr.Write(writer, fp); err != nil {
98100
return err
99101
}

nfs_onmkdir.go

+11-7
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ func onMkdir(ctx context.Context, w *response, userHandle Handler) error {
4040
return &NFSStatusErrorWithWccData{NFSStatusExist}
4141
}
4242

43-
newFile := append(path, string(obj.Filename))
44-
newFilePath := fs.Join(newFile...)
45-
if s, err := fs.Stat(newFilePath); err == nil {
43+
newFolder := append(path, string(obj.Filename))
44+
newFolderPath := fs.Join(newFolder...)
45+
if s, err := fs.Stat(newFolderPath); err == nil {
4646
if s.IsDir() {
4747
return &NFSStatusErrorWithWccData{NFSStatusExist}
4848
}
@@ -54,14 +54,14 @@ func onMkdir(ctx context.Context, w *response, userHandle Handler) error {
5454
}
5555
}
5656

57-
if err := fs.MkdirAll(newFilePath, attrs.Mode(mkdirDefaultMode)); err != nil {
57+
if err := fs.MkdirAll(newFolderPath, attrs.Mode(mkdirDefaultMode)); err != nil {
5858
return &NFSStatusErrorWithWccData{NFSStatusAccess}
5959
}
6060

61-
fp := userHandle.ToHandle(fs, newFile)
61+
fp := userHandle.ToHandle(fs, newFolder)
6262
changer := userHandle.Change(fs)
6363
if changer != nil {
64-
if err := attrs.Apply(changer, fs, newFilePath); err != nil {
64+
if err := attrs.Apply(changer, fs, newFolderPath); err != nil {
6565
return &NFSStatusErrorWithWccData{NFSStatusIO}
6666
}
6767
}
@@ -71,10 +71,14 @@ func onMkdir(ctx context.Context, w *response, userHandle Handler) error {
7171
return err
7272
}
7373

74+
// "handle follows"
75+
if err := xdr.Write(writer, uint32(1)); err != nil {
76+
return err
77+
}
7478
if err := xdr.Write(writer, fp); err != nil {
7579
return err
7680
}
77-
WritePostOpAttrs(writer, fs, newFile)
81+
WritePostOpAttrs(writer, fs, newFolder)
7882

7983
// dir_wcc (we don't include pre_op_attr)
8084
if err := xdr.Write(writer, uint32(0)); err != nil {

nfs_onsetattr.go

-7
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ func onSetAttr(ctx context.Context, w *response, userHandle Handler) error {
5858
}
5959

6060
changer := userHandle.Change(fs)
61-
if changer == nil {
62-
return &NFSStatusErrorWithWccData{NFSStatusROFS}
63-
}
64-
6561
if err := attrs.Apply(changer, fs, fs.Join(path...)); err != nil {
6662
return err
6763
}
@@ -78,9 +74,6 @@ func onSetAttr(ctx context.Context, w *response, userHandle Handler) error {
7874
if err := xdr.Write(writer, *preAttr); err != nil {
7975
return err
8076
}
81-
if err := xdr.Write(writer, uint32(1)); err != nil {
82-
return err
83-
}
8477
WritePostOpAttrs(writer, fs, path)
8578

8679
return w.Write(writer.Bytes())

nfs_onsymlink.go

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ func onSymlink(ctx context.Context, w *response, userHandle Handler) error {
6565
return err
6666
}
6767

68+
// "handle follows"
69+
if err := xdr.Write(writer, uint32(1)); err != nil {
70+
return err
71+
}
6872
if err := xdr.Write(writer, fp); err != nil {
6973
return err
7074
}

nfs_onwrite.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package nfs
33
import (
44
"bytes"
55
"context"
6+
"io"
7+
"log"
68
"math"
79
"os"
810

@@ -21,15 +23,15 @@ const (
2123

2224
type writeArgs struct {
2325
Handle []byte
24-
Offset uint32
26+
Offset uint64
2527
Count uint32
2628
How uint32
2729
Data []byte
2830
}
2931

3032
func onWrite(ctx context.Context, w *response, userHandle Handler) error {
3133
var req writeArgs
32-
if err := xdr.Read(w.req.Body, req); err != nil {
34+
if err := xdr.Read(w.req.Body, &req); err != nil {
3335
return err
3436
}
3537

@@ -58,22 +60,26 @@ func onWrite(ctx context.Context, w *response, userHandle Handler) error {
5860
preOpCache := ToFileAttribute(info).AsCache()
5961

6062
// now the actual op.
61-
file, err := fs.Open(fs.Join(path...))
63+
file, err := fs.OpenFile(fs.Join(path...), os.O_RDWR, info.Mode().Perm())
6264
if err != nil {
6365
return &NFSStatusErrorWithWccData{NFSStatusAccess}
6466
}
65-
if _, err := file.Seek(int64(req.Offset), 0); err != nil {
66-
return &NFSStatusErrorWithWccData{NFSStatusIO}
67+
if req.Offset > 0 {
68+
if _, err := file.Seek(int64(req.Offset), io.SeekStart); err != nil {
69+
return &NFSStatusErrorWithWccData{NFSStatusIO}
70+
}
6771
}
6872
end := req.Count
6973
if len(req.Data) < int(end) {
7074
end = uint32(len(req.Data))
7175
}
7276
writtenCount, err := file.Write(req.Data[:end])
7377
if err != nil {
78+
log.Printf("Error writing: %v", err)
7479
return &NFSStatusErrorWithWccData{NFSStatusIO}
7580
}
7681
if err := file.Close(); err != nil {
82+
log.Printf("error closing: %v", err)
7783
return &NFSStatusErrorWithWccData{NFSStatusIO}
7884
}
7985

@@ -88,7 +94,7 @@ func onWrite(ctx context.Context, w *response, userHandle Handler) error {
8894
if err := xdr.Write(writer, *preOpCache); err != nil {
8995
return err
9096
}
91-
WritePostOpAttrs(writer, fs, append(path, file.Name()))
97+
WritePostOpAttrs(writer, fs, path)
9298
if err := xdr.Write(writer, uint32(writtenCount)); err != nil {
9399
return err
94100
}

0 commit comments

Comments
 (0)