mount: implement mknod to make NFS file creation work - fixes #2115

It turns out that NFS calls mknod in FUSE even though we have create
defined. This was causing EIO errors when creating files.

This patch fixes it by implementing mknod. The way it is implemented
means that to write to an NFS file system you'll need --vfs-cache-mode
writes.
This commit is contained in:
Nick Craig-Wood 2020-10-29 15:12:36 +00:00
parent 0e7fc7613f
commit bfcd4113c3

View File

@ -4,6 +4,7 @@ package mount
import ( import (
"context" "context"
"io"
"os" "os"
"time" "time"
@ -214,3 +215,33 @@ func (d *Dir) Link(ctx context.Context, req *fuse.LinkRequest, old fusefs.Node)
defer log.Trace(d, "req=%v, old=%v", req, old)("new=%v, err=%v", &newNode, &err) defer log.Trace(d, "req=%v, old=%v", req, old)("new=%v, err=%v", &newNode, &err)
return nil, fuse.ENOSYS return nil, fuse.ENOSYS
} }
// Check interface satisfied
var _ fusefs.NodeMknoder = (*Dir)(nil)
// Mknod is called to create a file. Since we define create this will
// be called in preference, however NFS likes to call it for some
// reason. We don't actually create a file here just the Node.
func (d *Dir) Mknod(ctx context.Context, req *fuse.MknodRequest) (node fusefs.Node, err error) {
defer log.Trace(d, "name=%v, mode=%d, rdev=%d", req.Name, req.Mode, req.Rdev)("node=%v, err=%v", &node, &err)
if req.Rdev != 0 {
fs.Errorf(d, "Can't create device node %q", req.Name)
return nil, fuse.EIO
}
var cReq = fuse.CreateRequest{
Name: req.Name,
Flags: fuse.OpenFlags(os.O_CREATE | os.O_WRONLY),
Mode: req.Mode,
Umask: req.Umask,
}
var cResp fuse.CreateResponse
node, handle, err := d.Create(ctx, &cReq, &cResp)
if err != nil {
return nil, err
}
err = handle.(io.Closer).Close()
if err != nil {
return nil, err
}
return node, nil
}