royalcat
bc4b39b1c1
Some checks failed
docker / build-docker (linux/amd64) (push) Successful in 2m36s
docker / build-docker (linux/386) (push) Successful in 2m45s
docker / build-docker (linux/arm/v7) (push) Has been cancelled
docker / build-docker (linux/arm64/v8) (push) Has been cancelled
docker / build-docker (linux/arm64) (push) Has been cancelled
89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package nfs
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
|
|
"github.com/go-git/go-billy/v5"
|
|
"github.com/willscott/go-nfs-client/nfs/xdr"
|
|
)
|
|
|
|
const (
|
|
// FSInfoPropertyLink does the FS support hard links?
|
|
FSInfoPropertyLink = 0x0001
|
|
// FSInfoPropertySymlink does the FS support soft links?
|
|
FSInfoPropertySymlink = 0x0002
|
|
// FSInfoPropertyHomogeneous does the FS need PATHCONF calls for each file
|
|
FSInfoPropertyHomogeneous = 0x0008
|
|
// FSInfoPropertyCanSetTime can the FS support setting access/mod times?
|
|
FSInfoPropertyCanSetTime = 0x0010
|
|
)
|
|
|
|
func onFSInfo(ctx context.Context, w *response, userHandle Handler) error {
|
|
roothandle, err := xdr.ReadOpaque(w.req.Body)
|
|
if err != nil {
|
|
return &NFSStatusError{NFSStatusInval, err}
|
|
}
|
|
fs, path, err := userHandle.FromHandle(ctx, roothandle)
|
|
if err != nil {
|
|
return &NFSStatusError{NFSStatusStale, err}
|
|
}
|
|
|
|
writer := bytes.NewBuffer([]byte{})
|
|
if err := xdr.Write(writer, uint32(NFSStatusOk)); err != nil {
|
|
return &NFSStatusError{NFSStatusServerFault, err}
|
|
}
|
|
if err := WritePostOpAttrs(writer, tryStat(ctx, fs, path)); err != nil {
|
|
return &NFSStatusError{NFSStatusServerFault, err}
|
|
}
|
|
|
|
type fsinfores struct {
|
|
Rtmax uint32
|
|
Rtpref uint32
|
|
Rtmult uint32
|
|
Wtmax uint32
|
|
Wtpref uint32
|
|
Wtmult uint32
|
|
Dtpref uint32
|
|
Maxfilesize uint64
|
|
TimeDelta uint64
|
|
Properties uint32
|
|
}
|
|
|
|
res := fsinfores{
|
|
Rtmax: 1 << 30,
|
|
Rtpref: 1 << 30,
|
|
Rtmult: 4096,
|
|
Wtmax: 1 << 30,
|
|
Wtpref: 1 << 30,
|
|
Wtmult: 4096,
|
|
Dtpref: 8192,
|
|
Maxfilesize: 1 << 62, // wild guess. this seems big.
|
|
TimeDelta: 1, // nanosecond precision.
|
|
Properties: 0,
|
|
}
|
|
|
|
// TODO: these aren't great indications of support, really.
|
|
// if _, ok := fs.(billy.Symlink); ok {
|
|
// res.Properties |= FSInfoPropertyLink
|
|
// res.Properties |= FSInfoPropertySymlink
|
|
// }
|
|
// TODO: if the nfs share spans multiple virtual mounts, may need
|
|
// to support granular PATHINFO responses.
|
|
res.Properties |= FSInfoPropertyHomogeneous
|
|
// TODO: not a perfect indicator
|
|
|
|
if CapabilityCheck(fs, billy.WriteCapability) {
|
|
res.Properties |= FSInfoPropertyCanSetTime
|
|
}
|
|
|
|
// TODO: this whole struct should be specifiable by the userhandler.
|
|
|
|
if err := xdr.Write(writer, res); err != nil {
|
|
return &NFSStatusError{NFSStatusServerFault, err}
|
|
}
|
|
if err := w.Write(writer.Bytes()); err != nil {
|
|
return &NFSStatusError{NFSStatusServerFault, err}
|
|
}
|
|
return nil
|
|
}
|