@jsonjoy.com/json-pack 1.21.0 → 17.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/JsonPackExtension.d.ts +8 -0
- package/lib/JsonPackExtension.js +8 -0
- package/lib/JsonPackExtension.js.map +1 -1
- package/lib/JsonPackMpint.d.ts +25 -0
- package/lib/JsonPackMpint.js +31 -1
- package/lib/JsonPackMpint.js.map +1 -1
- package/lib/JsonPackValue.d.ts +10 -0
- package/lib/JsonPackValue.js +10 -0
- package/lib/JsonPackValue.js.map +1 -1
- package/lib/avro/AvroDecoder.d.ts +67 -0
- package/lib/avro/AvroDecoder.js +77 -5
- package/lib/avro/AvroDecoder.js.map +1 -1
- package/lib/avro/AvroEncoder.d.ts +71 -0
- package/lib/avro/AvroEncoder.js +90 -12
- package/lib/avro/AvroEncoder.js.map +1 -1
- package/lib/avro/AvroSchemaDecoder.d.ts +53 -0
- package/lib/avro/AvroSchemaDecoder.js +60 -3
- package/lib/avro/AvroSchemaDecoder.js.map +1 -1
- package/lib/avro/AvroSchemaEncoder.d.ts +65 -0
- package/lib/avro/AvroSchemaEncoder.js +84 -5
- package/lib/avro/AvroSchemaEncoder.js.map +1 -1
- package/lib/avro/AvroSchemaValidator.d.ts +10 -0
- package/lib/avro/AvroSchemaValidator.js +18 -1
- package/lib/avro/AvroSchemaValidator.js.map +1 -1
- package/lib/avro/types.d.ts +31 -0
- package/lib/avro/types.js +4 -0
- package/lib/avro/types.js.map +1 -1
- package/lib/bencode/BencodeDecoder.js +9 -9
- package/lib/bencode/BencodeDecoder.js.map +1 -1
- package/lib/bencode/BencodeEncoder.d.ts +5 -0
- package/lib/bencode/BencodeEncoder.js +25 -20
- package/lib/bencode/BencodeEncoder.js.map +1 -1
- package/lib/bson/BsonDecoder.js +48 -33
- package/lib/bson/BsonDecoder.js.map +1 -1
- package/lib/bson/BsonEncoder.js +11 -3
- package/lib/bson/BsonEncoder.js.map +1 -1
- package/lib/cbor/CborDecoder.d.ts +24 -0
- package/lib/cbor/CborDecoder.js +94 -56
- package/lib/cbor/CborDecoder.js.map +1 -1
- package/lib/cbor/CborDecoderBase.d.ts +1 -0
- package/lib/cbor/CborDecoderBase.js +63 -53
- package/lib/cbor/CborDecoderBase.js.map +1 -1
- package/lib/cbor/CborEncoder.d.ts +5 -0
- package/lib/cbor/CborEncoder.js +9 -3
- package/lib/cbor/CborEncoder.js.map +1 -1
- package/lib/cbor/CborEncoderFast.d.ts +7 -0
- package/lib/cbor/CborEncoderFast.js +22 -14
- package/lib/cbor/CborEncoderFast.js.map +1 -1
- package/lib/cbor/CborEncoderStable.d.ts +1 -0
- package/lib/cbor/CborEncoderStable.js +2 -1
- package/lib/cbor/CborEncoderStable.js.map +1 -1
- package/lib/cbor/shared.d.ts +1 -1
- package/lib/codecs/Codecs.d.ts +1 -1
- package/lib/codecs/cbor.js +1 -1
- package/lib/codecs/cbor.js.map +1 -1
- package/lib/codecs/json.js +1 -1
- package/lib/codecs/json.js.map +1 -1
- package/lib/codecs/msgpack.js +1 -1
- package/lib/codecs/msgpack.js.map +1 -1
- package/lib/ejson/EjsonDecoder.d.ts +5 -0
- package/lib/ejson/EjsonDecoder.js +72 -37
- package/lib/ejson/EjsonDecoder.js.map +1 -1
- package/lib/ejson/EjsonEncoder.d.ts +5 -0
- package/lib/ejson/EjsonEncoder.js +149 -114
- package/lib/ejson/EjsonEncoder.js.map +1 -1
- package/lib/ejson/index.js +1 -0
- package/lib/ejson/index.js.map +1 -1
- package/lib/ion/Import.d.ts +1 -1
- package/lib/ion/Import.js.map +1 -1
- package/lib/ion/IonDecoder.d.ts +0 -1
- package/lib/ion/IonDecoder.js +4 -3
- package/lib/ion/IonDecoder.js.map +1 -1
- package/lib/ion/IonDecoderBase.js +29 -18
- package/lib/ion/IonDecoderBase.js.map +1 -1
- package/lib/ion/IonEncoderFast.d.ts +1 -1
- package/lib/ion/IonEncoderFast.js +30 -30
- package/lib/ion/IonEncoderFast.js.map +1 -1
- package/lib/ion/ast.d.ts +4 -1
- package/lib/ion/symbols.d.ts +1 -1
- package/lib/json/JsonDecoder.js +72 -66
- package/lib/json/JsonDecoder.js.map +1 -1
- package/lib/json/JsonDecoderDag.js +14 -0
- package/lib/json/JsonDecoderDag.js.map +1 -1
- package/lib/json/JsonDecoderPartial.d.ts +22 -0
- package/lib/json/JsonDecoderPartial.js +30 -8
- package/lib/json/JsonDecoderPartial.js.map +1 -1
- package/lib/json/JsonEncoder.d.ts +5 -0
- package/lib/json/JsonEncoder.js +59 -51
- package/lib/json/JsonEncoder.js.map +1 -1
- package/lib/json/JsonEncoderDag.d.ts +17 -0
- package/lib/json/JsonEncoderDag.js +27 -10
- package/lib/json/JsonEncoderDag.js.map +1 -1
- package/lib/json/JsonEncoderStable.js +5 -5
- package/lib/json/JsonEncoderStable.js.map +1 -1
- package/lib/json-binary/codec.d.ts +8 -1
- package/lib/json-binary/codec.js +7 -0
- package/lib/json-binary/codec.js.map +1 -1
- package/lib/msgpack/MsgPackDecoder.d.ts +27 -0
- package/lib/msgpack/MsgPackDecoder.js +55 -23
- package/lib/msgpack/MsgPackDecoder.js.map +1 -1
- package/lib/msgpack/MsgPackDecoderFast.d.ts +8 -0
- package/lib/msgpack/MsgPackDecoderFast.js +14 -5
- package/lib/msgpack/MsgPackDecoderFast.js.map +1 -1
- package/lib/msgpack/MsgPackEncoder.d.ts +3 -0
- package/lib/msgpack/MsgPackEncoder.js +7 -4
- package/lib/msgpack/MsgPackEncoder.js.map +1 -1
- package/lib/msgpack/MsgPackEncoderFast.d.ts +26 -4
- package/lib/msgpack/MsgPackEncoderFast.js +31 -0
- package/lib/msgpack/MsgPackEncoderFast.js.map +1 -1
- package/lib/msgpack/MsgPackEncoderStable.d.ts +3 -0
- package/lib/msgpack/MsgPackEncoderStable.js +3 -0
- package/lib/msgpack/MsgPackEncoderStable.js.map +1 -1
- package/lib/msgpack/MsgPackToJsonConverter.d.ts +30 -4
- package/lib/msgpack/MsgPackToJsonConverter.js +32 -5
- package/lib/msgpack/MsgPackToJsonConverter.js.map +1 -1
- package/lib/msgpack/index.d.ts +29 -0
- package/lib/msgpack/index.js +30 -0
- package/lib/msgpack/index.js.map +1 -1
- package/lib/msgpack/shallow-read.js +7 -7
- package/lib/msgpack/shallow-read.js.map +1 -1
- package/lib/msgpack/types.d.ts +1 -0
- package/lib/msgpack/util.d.ts +1 -1
- package/lib/nfs/v3/FullNfsv3Encoder.d.ts +3 -3
- package/lib/nfs/v3/FullNfsv3Encoder.js +3 -3
- package/lib/nfs/v3/FullNfsv3Encoder.js.map +1 -1
- package/lib/nfs/v3/Nfsv3Decoder.js +51 -50
- package/lib/nfs/v3/Nfsv3Decoder.js.map +1 -1
- package/lib/nfs/v3/Nfsv3Encoder.d.ts +2 -2
- package/lib/nfs/v3/Nfsv3Encoder.js +52 -52
- package/lib/nfs/v3/Nfsv3Encoder.js.map +1 -1
- package/lib/nfs/v3/constants.d.ts +34 -0
- package/lib/nfs/v3/constants.js +4 -0
- package/lib/nfs/v3/constants.js.map +1 -1
- package/lib/nfs/v3/locks/NlmDecoder.js +20 -20
- package/lib/nfs/v3/locks/NlmDecoder.js.map +1 -1
- package/lib/nfs/v3/locks/NlmEncoder.d.ts +2 -2
- package/lib/nfs/v3/locks/NlmEncoder.js +20 -20
- package/lib/nfs/v3/locks/NlmEncoder.js.map +1 -1
- package/lib/nfs/v3/locks/constants.d.ts +9 -0
- package/lib/nfs/v3/locks/messages.d.ts +58 -1
- package/lib/nfs/v3/locks/messages.js +54 -0
- package/lib/nfs/v3/locks/messages.js.map +1 -1
- package/lib/nfs/v3/locks/structs.d.ts +15 -0
- package/lib/nfs/v3/locks/structs.js +15 -0
- package/lib/nfs/v3/locks/structs.js.map +1 -1
- package/lib/nfs/v3/messages.d.ts +249 -0
- package/lib/nfs/v3/messages.js +249 -0
- package/lib/nfs/v3/messages.js.map +1 -1
- package/lib/nfs/v3/mount/MountDecoder.js +12 -12
- package/lib/nfs/v3/mount/MountEncoder.d.ts +2 -2
- package/lib/nfs/v3/mount/MountEncoder.js +13 -13
- package/lib/nfs/v3/mount/MountEncoder.js.map +1 -1
- package/lib/nfs/v3/mount/constants.d.ts +9 -0
- package/lib/nfs/v3/mount/messages.d.ts +31 -1
- package/lib/nfs/v3/mount/messages.js +27 -0
- package/lib/nfs/v3/mount/messages.js.map +1 -1
- package/lib/nfs/v3/mount/structs.d.ts +15 -0
- package/lib/nfs/v3/mount/structs.js +15 -0
- package/lib/nfs/v3/mount/structs.js.map +1 -1
- package/lib/nfs/v3/structs.d.ts +78 -0
- package/lib/nfs/v3/structs.js +78 -0
- package/lib/nfs/v3/structs.js.map +1 -1
- package/lib/nfs/v4/Nfsv4Decoder.d.ts +0 -2
- package/lib/nfs/v4/Nfsv4Decoder.js +96 -102
- package/lib/nfs/v4/Nfsv4Decoder.js.map +1 -1
- package/lib/nfs/v4/Nfsv4Encoder.d.ts +2 -2
- package/lib/nfs/v4/Nfsv4Encoder.js +1 -1
- package/lib/nfs/v4/Nfsv4Encoder.js.map +1 -1
- package/lib/nfs/v4/Nfsv4FullEncoder.d.ts +4 -4
- package/lib/nfs/v4/Nfsv4FullEncoder.js +4 -4
- package/lib/nfs/v4/Nfsv4FullEncoder.js.map +1 -1
- package/lib/nfs/v4/attributes.d.ts +62 -0
- package/lib/nfs/v4/attributes.js +209 -147
- package/lib/nfs/v4/attributes.js.map +1 -1
- package/lib/nfs/v4/builder.d.ts +274 -1
- package/lib/nfs/v4/builder.js +283 -10
- package/lib/nfs/v4/builder.js.map +1 -1
- package/lib/nfs/v4/client/NfsFsDir.d.ts +4 -1
- package/lib/nfs/v4/client/NfsFsDir.js +8 -5
- package/lib/nfs/v4/client/NfsFsDir.js.map +1 -1
- package/lib/nfs/v4/client/NfsFsDirent.d.ts +3 -0
- package/lib/nfs/v4/client/NfsFsDirent.js +10 -7
- package/lib/nfs/v4/client/NfsFsDirent.js.map +1 -1
- package/lib/nfs/v4/client/NfsFsFileHandle.d.ts +4 -3
- package/lib/nfs/v4/client/NfsFsFileHandle.js +13 -10
- package/lib/nfs/v4/client/NfsFsFileHandle.js.map +1 -1
- package/lib/nfs/v4/client/NfsFsStats.d.ts +3 -0
- package/lib/nfs/v4/client/NfsFsStats.js +10 -7
- package/lib/nfs/v4/client/NfsFsStats.js.map +1 -1
- package/lib/nfs/v4/client/Nfsv4FsClient.d.ts +2 -3
- package/lib/nfs/v4/client/Nfsv4FsClient.js +92 -92
- package/lib/nfs/v4/client/Nfsv4FsClient.js.map +1 -1
- package/lib/nfs/v4/client/Nfsv4TcpClient.d.ts +6 -6
- package/lib/nfs/v4/client/Nfsv4TcpClient.js +3 -3
- package/lib/nfs/v4/client/Nfsv4TcpClient.js.map +1 -1
- package/lib/nfs/v4/client/types.d.ts +1 -1
- package/lib/nfs/v4/constants.d.ts +78 -1
- package/lib/nfs/v4/format.d.ts +1 -1
- package/lib/nfs/v4/format.js +229 -229
- package/lib/nfs/v4/format.js.map +1 -1
- package/lib/nfs/v4/messages.js +101 -101
- package/lib/nfs/v4/messages.js.map +1 -1
- package/lib/nfs/v4/server/Nfsv4CompoundProcCtx.d.ts +20 -1
- package/lib/nfs/v4/server/Nfsv4CompoundProcCtx.js +29 -8
- package/lib/nfs/v4/server/Nfsv4CompoundProcCtx.js.map +1 -1
- package/lib/nfs/v4/server/Nfsv4Connection.d.ts +6 -3
- package/lib/nfs/v4/server/Nfsv4Connection.js +11 -8
- package/lib/nfs/v4/server/Nfsv4Connection.js.map +1 -1
- package/lib/nfs/v4/server/Nfsv4TcpServer.d.ts +2 -3
- package/lib/nfs/v4/server/Nfsv4TcpServer.js +1 -0
- package/lib/nfs/v4/server/Nfsv4TcpServer.js.map +1 -1
- package/lib/nfs/v4/server/operations/ByteRangeLock.d.ts +69 -1
- package/lib/nfs/v4/server/operations/ByteRangeLock.js +43 -1
- package/lib/nfs/v4/server/operations/ByteRangeLock.js.map +1 -1
- package/lib/nfs/v4/server/operations/ClientRecord.d.ts +98 -1
- package/lib/nfs/v4/server/operations/ClientRecord.js +54 -1
- package/lib/nfs/v4/server/operations/ClientRecord.js.map +1 -1
- package/lib/nfs/v4/server/operations/FilesystemStats.d.ts +22 -1
- package/lib/nfs/v4/server/operations/FilesystemStats.js +16 -1
- package/lib/nfs/v4/server/operations/FilesystemStats.js.map +1 -1
- package/lib/nfs/v4/server/operations/LockOwnerState.d.ts +75 -2
- package/lib/nfs/v4/server/operations/LockOwnerState.js +43 -1
- package/lib/nfs/v4/server/operations/LockOwnerState.js.map +1 -1
- package/lib/nfs/v4/server/operations/LockStateid.d.ts +55 -1
- package/lib/nfs/v4/server/operations/LockStateid.js +37 -1
- package/lib/nfs/v4/server/operations/LockStateid.js.map +1 -1
- package/lib/nfs/v4/server/operations/Nfsv4Operations.d.ts +2 -1
- package/lib/nfs/v4/server/operations/Nfsv4OperationsNotImpl.d.ts +2 -2
- package/lib/nfs/v4/server/operations/OpenFileState.d.ts +90 -2
- package/lib/nfs/v4/server/operations/OpenFileState.js +52 -1
- package/lib/nfs/v4/server/operations/OpenFileState.js.map +1 -1
- package/lib/nfs/v4/server/operations/OpenOwnerState.d.ts +76 -2
- package/lib/nfs/v4/server/operations/OpenOwnerState.js +44 -1
- package/lib/nfs/v4/server/operations/OpenOwnerState.js.map +1 -1
- package/lib/nfs/v4/server/operations/node/Nfsv4OperationsNode.d.ts +73 -3
- package/lib/nfs/v4/server/operations/node/Nfsv4OperationsNode.js +261 -187
- package/lib/nfs/v4/server/operations/node/Nfsv4OperationsNode.js.map +1 -1
- package/lib/nfs/v4/server/operations/node/attrs.d.ts +13 -1
- package/lib/nfs/v4/server/operations/node/attrs.js +75 -62
- package/lib/nfs/v4/server/operations/node/attrs.js.map +1 -1
- package/lib/nfs/v4/server/operations/node/fh.d.ts +67 -2
- package/lib/nfs/v4/server/operations/node/fh.js +83 -21
- package/lib/nfs/v4/server/operations/node/fh.js.map +1 -1
- package/lib/nfs/v4/server/operations/node/util.js +4 -4
- package/lib/nfs/v4/server/operations/node/util.js.map +1 -1
- package/lib/nfs/v4/server/util.d.ts +0 -1
- package/lib/nfs/v4/server/util.js +40 -40
- package/lib/nfs/v4/structs.d.ts +136 -4
- package/lib/nfs/v4/structs.js +129 -0
- package/lib/nfs/v4/structs.js.map +1 -1
- package/lib/resp/RespDecoder.d.ts +9 -0
- package/lib/resp/RespDecoder.js +93 -76
- package/lib/resp/RespDecoder.js.map +1 -1
- package/lib/resp/RespEncoder.d.ts +8 -0
- package/lib/resp/RespEncoder.js +107 -89
- package/lib/resp/RespEncoder.js.map +1 -1
- package/lib/resp/RespEncoderLegacy.d.ts +3 -0
- package/lib/resp/RespEncoderLegacy.js +7 -4
- package/lib/resp/RespEncoderLegacy.js.map +1 -1
- package/lib/resp/RespStreamingDecoder.d.ts +48 -0
- package/lib/resp/RespStreamingDecoder.js +48 -0
- package/lib/resp/RespStreamingDecoder.js.map +1 -1
- package/lib/resp/constants.d.ts +19 -19
- package/lib/rm/RmRecordEncoder.d.ts +15 -1
- package/lib/rm/RmRecordEncoder.js +15 -1
- package/lib/rm/RmRecordEncoder.js.map +1 -1
- package/lib/rpc/RpcMessageDecoder.d.ts +1 -1
- package/lib/rpc/RpcMessageDecoder.js +8 -7
- package/lib/rpc/RpcMessageDecoder.js.map +1 -1
- package/lib/rpc/RpcMessageEncoder.d.ts +2 -2
- package/lib/rpc/RpcMessageEncoder.js +6 -6
- package/lib/rpc/RpcMessageEncoder.js.map +1 -1
- package/lib/rpc/constants.d.ts +76 -28
- package/lib/rpc/constants.js +10 -0
- package/lib/rpc/constants.js.map +1 -1
- package/lib/ssh/SshDecoder.d.ts +46 -0
- package/lib/ssh/SshDecoder.js +52 -2
- package/lib/ssh/SshDecoder.js.map +1 -1
- package/lib/ssh/SshEncoder.d.ts +69 -0
- package/lib/ssh/SshEncoder.js +81 -8
- package/lib/ssh/SshEncoder.js.map +1 -1
- package/lib/ssh/index.d.ts +6 -0
- package/lib/ssh/index.js +6 -0
- package/lib/ssh/index.js.map +1 -1
- package/lib/ubjson/UbjsonDecoder.js +1 -1
- package/lib/ubjson/UbjsonDecoder.js.map +1 -1
- package/lib/ubjson/UbjsonEncoder.js +6 -5
- package/lib/ubjson/UbjsonEncoder.js.map +1 -1
- package/lib/util/CompressionTable.js +4 -4
- package/lib/util/CompressionTable.js.map +1 -1
- package/lib/util/DecompressionTable.js +3 -2
- package/lib/util/DecompressionTable.js.map +1 -1
- package/lib/ws/WsFrameDecoder.d.ts +18 -0
- package/lib/ws/WsFrameDecoder.js +18 -0
- package/lib/ws/WsFrameDecoder.js.map +1 -1
- package/lib/ws/WsFrameEncoder.d.ts +1 -1
- package/lib/ws/WsFrameEncoder.js +3 -3
- package/lib/ws/WsFrameEncoder.js.map +1 -1
- package/lib/ws/constants.js +5 -0
- package/lib/ws/constants.js.map +1 -1
- package/lib/xdr/XdrDecoder.d.ts +62 -0
- package/lib/xdr/XdrDecoder.js +73 -6
- package/lib/xdr/XdrDecoder.js.map +1 -1
- package/lib/xdr/XdrEncoder.d.ts +71 -0
- package/lib/xdr/XdrEncoder.js +88 -13
- package/lib/xdr/XdrEncoder.js.map +1 -1
- package/lib/xdr/XdrSchemaDecoder.d.ts +40 -0
- package/lib/xdr/XdrSchemaDecoder.js +52 -0
- package/lib/xdr/XdrSchemaDecoder.js.map +1 -1
- package/lib/xdr/XdrSchemaEncoder.d.ts +5 -0
- package/lib/xdr/XdrSchemaEncoder.js +9 -0
- package/lib/xdr/XdrSchemaEncoder.js.map +1 -1
- package/lib/xdr/XdrSchemaValidator.d.ts +9 -0
- package/lib/xdr/XdrSchemaValidator.js +42 -11
- package/lib/xdr/XdrSchemaValidator.js.map +1 -1
- package/lib/xdr/XdrUnion.d.ts +5 -0
- package/lib/xdr/XdrUnion.js +5 -0
- package/lib/xdr/XdrUnion.js.map +1 -1
- package/lib/xdr/index.d.ts +14 -0
- package/lib/xdr/index.js +14 -0
- package/lib/xdr/index.js.map +1 -1
- package/lib/xdr/types.d.ts +46 -0
- package/package.json +32 -55
|
@@ -21,23 +21,49 @@ const attributes_1 = require("../../../attributes");
|
|
|
21
21
|
const Writer_1 = require("@jsonjoy.com/buffers/lib/Writer");
|
|
22
22
|
const XdrEncoder_1 = require("../../../../../xdr/XdrEncoder");
|
|
23
23
|
const XdrDecoder_1 = require("../../../../../xdr/XdrDecoder");
|
|
24
|
+
/**
|
|
25
|
+
* NFS v4 Operations implementation for Node.js `fs` filesystem.
|
|
26
|
+
*/
|
|
24
27
|
class Nfsv4OperationsNode {
|
|
25
28
|
constructor(opts) {
|
|
29
|
+
/**
|
|
30
|
+
* Lease time in seconds.
|
|
31
|
+
* Per RFC 7530 §9.5, this is the time a client has to renew its lease
|
|
32
|
+
* before the server may reclaim its state. Default is 90 seconds.
|
|
33
|
+
*/
|
|
26
34
|
this.leaseTime = 90;
|
|
35
|
+
/** Confirmed clients. */
|
|
27
36
|
this.clients = new Map();
|
|
37
|
+
/** Clients pending SETCLIENTID_CONFIRM confirmation. */
|
|
28
38
|
this.pendingClients = new Map();
|
|
39
|
+
/** Next client ID to assign. */
|
|
29
40
|
this.nextClientId = 1n;
|
|
41
|
+
/** Boot stamp, identifies server instance, 16 bits. */
|
|
30
42
|
this.bootStamp = Math.round(Math.random() * 0xffff);
|
|
43
|
+
/** Next stateid sequence number. */
|
|
31
44
|
this.nextStateidSeqid = 1;
|
|
45
|
+
/** Map from stateid (as string key) to open file state. */
|
|
32
46
|
this.openFiles = new Map();
|
|
47
|
+
/** Map from open-owner key to owner state. */
|
|
33
48
|
this.openOwners = new Map();
|
|
49
|
+
/** Map from lock key to byte-range lock. */
|
|
34
50
|
this.locks = new Map();
|
|
51
|
+
/** Map from lock-owner key to lock-owner state. */
|
|
35
52
|
this.lockOwners = new Map();
|
|
53
|
+
/** Map from lock stateid 'other' field to lock stateid state. Per RFC 7530, one stateid per lock-owner per file. */
|
|
36
54
|
this.lockStateids = new Map();
|
|
55
|
+
/**
|
|
56
|
+
* Server-wide monotonic change counter for directory change_info.
|
|
57
|
+
* Incremented on every mutating operation (RENAME, REMOVE, CREATE, etc.).
|
|
58
|
+
* Used to populate change_info4 before/after values for client cache validation.
|
|
59
|
+
*/
|
|
37
60
|
this.changeCounter = 0n;
|
|
61
|
+
/**
|
|
62
|
+
* Default filesystem statistics: 2TB available space, 2M available inodes.
|
|
63
|
+
*/
|
|
38
64
|
this.defaultFsStats = async () => {
|
|
39
|
-
const twoTB = BigInt(2 * 1024 * 1024 * 1024 * 1024);
|
|
40
|
-
const twoM = BigInt(2 * 1000 * 1000);
|
|
65
|
+
const twoTB = BigInt(2 * 1024 * 1024 * 1024 * 1024); // 2TB
|
|
66
|
+
const twoM = BigInt(2 * 1000 * 1000); // 2M inodes
|
|
41
67
|
return new FilesystemStats_1.FilesystemStats(twoTB, twoTB, twoTB * 2n, twoM, twoM, twoM * 2n);
|
|
42
68
|
};
|
|
43
69
|
this.fs = opts.fs;
|
|
@@ -71,6 +97,15 @@ class Nfsv4OperationsNode {
|
|
|
71
97
|
makeOpenOwnerKey(clientid, owner) {
|
|
72
98
|
return `${clientid}:${Buffer.from(owner).toString('hex')}`;
|
|
73
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Validates a seqid from a client request against the owner's current seqid.
|
|
102
|
+
* Per RFC 7530 §9.1.7, the server expects seqid = last_seqid + 1 for new operations,
|
|
103
|
+
* or seqid = last_seqid for replayed requests (idempotent retry).
|
|
104
|
+
*
|
|
105
|
+
* @param requestSeqid - seqid from the client request
|
|
106
|
+
* @param ownerSeqid - current seqid stored for the owner
|
|
107
|
+
* @returns 'valid' if seqid matches expected next value, 'replay' if it matches last value, 'invalid' otherwise
|
|
108
|
+
*/
|
|
74
109
|
validateSeqid(requestSeqid, ownerSeqid) {
|
|
75
110
|
const nextSeqid = ownerSeqid === 0xffffffff ? 1 : ownerSeqid + 1;
|
|
76
111
|
if (requestSeqid === nextSeqid)
|
|
@@ -79,6 +114,12 @@ class Nfsv4OperationsNode {
|
|
|
79
114
|
return 'replay';
|
|
80
115
|
return 'invalid';
|
|
81
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Renews the lease for a client.
|
|
119
|
+
* Per RFC 7530 §9.5, any stateful operation renews the client's lease.
|
|
120
|
+
*
|
|
121
|
+
* @param clientid - The client ID whose lease should be renewed
|
|
122
|
+
*/
|
|
82
123
|
renewClientLease(clientid) {
|
|
83
124
|
const client = this.clients.get(clientid);
|
|
84
125
|
if (client) {
|
|
@@ -145,7 +186,7 @@ class Nfsv4OperationsNode {
|
|
|
145
186
|
return this.lockStateids.get(otherKey);
|
|
146
187
|
}
|
|
147
188
|
hasConflictingLock(path, locktype, offset, length, ownerKey) {
|
|
148
|
-
const isWriteLock = locktype === 2
|
|
189
|
+
const isWriteLock = locktype === 2 /* Nfsv4LockType.WRITE_LT */;
|
|
149
190
|
for (const lock of this.locks.values()) {
|
|
150
191
|
if (lock.path !== path)
|
|
151
192
|
continue;
|
|
@@ -153,11 +194,15 @@ class Nfsv4OperationsNode {
|
|
|
153
194
|
continue;
|
|
154
195
|
if (lock.lockOwnerKey === ownerKey)
|
|
155
196
|
continue;
|
|
156
|
-
if (isWriteLock || lock.locktype === 2)
|
|
197
|
+
if (isWriteLock || lock.locktype === 2 /* Nfsv4LockType.WRITE_LT */)
|
|
157
198
|
return true;
|
|
158
199
|
}
|
|
159
200
|
return false;
|
|
160
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Establishes client ID or updates callback information.
|
|
204
|
+
* Returns a client ID and confirmation verifier for SETCLIENTID_CONFIRM.
|
|
205
|
+
*/
|
|
161
206
|
async SETCLIENTID(request, ctx) {
|
|
162
207
|
const principal = ctx.getPrincipal();
|
|
163
208
|
const verifier = request.client.verifier.data;
|
|
@@ -169,13 +214,17 @@ class Nfsv4OperationsNode {
|
|
|
169
214
|
if (confirmedClientEntry) {
|
|
170
215
|
const existingRecord = confirmedClientEntry[1];
|
|
171
216
|
if (existingRecord.principal !== principal)
|
|
172
|
-
return new msg.Nfsv4SetclientidResponse(10017);
|
|
217
|
+
return new msg.Nfsv4SetclientidResponse(10017 /* Nfsv4Stat.NFS4ERR_CLID_INUSE */);
|
|
173
218
|
this.pendingClients.delete(clientid);
|
|
174
219
|
clientid = confirmedClientEntry[0];
|
|
175
220
|
const verifierMatch = (0, cmpUint8Array_1.cmpUint8Array)(existingRecord.verifier, verifier);
|
|
176
221
|
if (verifierMatch) {
|
|
222
|
+
// The client is re-registering with the same ID string and verifier.
|
|
223
|
+
// Update callback information, return existing client ID and issue
|
|
224
|
+
// new confirm verifier.
|
|
177
225
|
}
|
|
178
226
|
else {
|
|
227
|
+
// The client is re-registering with the same ID string but different verifier.
|
|
179
228
|
clientid = this.nextClientId++;
|
|
180
229
|
}
|
|
181
230
|
}
|
|
@@ -184,19 +233,23 @@ class Nfsv4OperationsNode {
|
|
|
184
233
|
if (pendingClientEntry) {
|
|
185
234
|
const existingRecord = pendingClientEntry[1];
|
|
186
235
|
if (existingRecord.principal !== principal)
|
|
187
|
-
return new msg.Nfsv4SetclientidResponse(10017);
|
|
236
|
+
return new msg.Nfsv4SetclientidResponse(10017 /* Nfsv4Stat.NFS4ERR_CLID_INUSE */);
|
|
188
237
|
const verifierMatch = (0, cmpUint8Array_1.cmpUint8Array)(existingRecord.verifier, verifier);
|
|
189
238
|
if (verifierMatch && existingRecord.cache) {
|
|
239
|
+
// The client is re-registering with the same ID string and verifier.
|
|
240
|
+
// Return cached response.
|
|
190
241
|
return existingRecord.cache;
|
|
191
242
|
}
|
|
192
243
|
}
|
|
244
|
+
// New client ID string. Create new client record.
|
|
193
245
|
clientid = this.nextClientId++;
|
|
194
246
|
}
|
|
195
247
|
const setclientidConfirm = (0, node_crypto_1.randomBytes)(8);
|
|
196
248
|
const verifierStruct = new struct.Nfsv4Verifier(setclientidConfirm);
|
|
197
249
|
const body = new msg.Nfsv4SetclientidResOk(clientid, verifierStruct);
|
|
198
|
-
const response = new msg.Nfsv4SetclientidResponse(0
|
|
250
|
+
const response = new msg.Nfsv4SetclientidResponse(0 /* Nfsv4Stat.NFS4_OK */, body);
|
|
199
251
|
const newRecord = new ClientRecord_1.ClientRecord(principal, verifier, clientIdString, callback, callbackIdent, setclientidConfirm, response);
|
|
252
|
+
// Remove any existing pending records with same ID string.
|
|
200
253
|
for (const [id, entry] of this.pendingClients.entries())
|
|
201
254
|
if ((0, cmpUint8Array_1.cmpUint8Array)(entry.clientIdString, clientIdString))
|
|
202
255
|
this.pendingClients.delete(id);
|
|
@@ -204,6 +257,10 @@ class Nfsv4OperationsNode {
|
|
|
204
257
|
this.pendingClients.set(clientid, newRecord);
|
|
205
258
|
return response;
|
|
206
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Confirms a client ID established by SETCLIENTID.
|
|
262
|
+
* Transitions unconfirmed client record to confirmed state.
|
|
263
|
+
*/
|
|
207
264
|
async SETCLIENTID_CONFIRM(request, ctx) {
|
|
208
265
|
const { clients, pendingClients } = this;
|
|
209
266
|
const clientid = request.clientid;
|
|
@@ -212,14 +269,14 @@ class Nfsv4OperationsNode {
|
|
|
212
269
|
if (!pendingRecord) {
|
|
213
270
|
const confirmedRecord = this.clients.get(clientid);
|
|
214
271
|
if (confirmedRecord && (0, cmpUint8Array_1.cmpUint8Array)(confirmedRecord.setclientidConfirm, setclientidConfirm))
|
|
215
|
-
return new msg.Nfsv4SetclientidConfirmResponse(0);
|
|
216
|
-
return new msg.Nfsv4SetclientidConfirmResponse(10022);
|
|
272
|
+
return new msg.Nfsv4SetclientidConfirmResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
273
|
+
return new msg.Nfsv4SetclientidConfirmResponse(10022 /* Nfsv4Stat.NFS4ERR_STALE_CLIENTID */);
|
|
217
274
|
}
|
|
218
275
|
const principal = ctx.getPrincipal();
|
|
219
276
|
if (pendingRecord.principal !== principal)
|
|
220
|
-
return new msg.Nfsv4SetclientidConfirmResponse(10017);
|
|
277
|
+
return new msg.Nfsv4SetclientidConfirmResponse(10017 /* Nfsv4Stat.NFS4ERR_CLID_INUSE */);
|
|
221
278
|
if (!(0, cmpUint8Array_1.cmpUint8Array)(pendingRecord.setclientidConfirm, setclientidConfirm))
|
|
222
|
-
return new msg.Nfsv4SetclientidConfirmResponse(10022);
|
|
279
|
+
return new msg.Nfsv4SetclientidConfirmResponse(10022 /* Nfsv4Stat.NFS4ERR_STALE_CLIENTID */);
|
|
223
280
|
const oldConfirmed = this.findClientByIdString(this.clients, pendingRecord.clientIdString);
|
|
224
281
|
if (oldConfirmed) {
|
|
225
282
|
const clientid2 = oldConfirmed[0];
|
|
@@ -228,6 +285,7 @@ class Nfsv4OperationsNode {
|
|
|
228
285
|
}
|
|
229
286
|
this.clients.delete(clientid);
|
|
230
287
|
pendingClients.delete(clientid);
|
|
288
|
+
// Remove any existing pending records with same ID string.
|
|
231
289
|
const clientIdString = pendingRecord.clientIdString;
|
|
232
290
|
for (const [id, entry] of pendingClients.entries())
|
|
233
291
|
if ((0, cmpUint8Array_1.cmpUint8Array)(entry.clientIdString, clientIdString))
|
|
@@ -237,49 +295,49 @@ class Nfsv4OperationsNode {
|
|
|
237
295
|
clients.delete(id);
|
|
238
296
|
this.enforceClientLimit();
|
|
239
297
|
clients.set(clientid, pendingRecord);
|
|
240
|
-
return new msg.Nfsv4SetclientidConfirmResponse(0);
|
|
298
|
+
return new msg.Nfsv4SetclientidConfirmResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
241
299
|
}
|
|
242
300
|
async ILLEGAL(request, ctx) {
|
|
243
301
|
ctx.connection.logger.log('ILLEGAL', request);
|
|
244
|
-
return new msg.Nfsv4IllegalResponse(10044);
|
|
302
|
+
return new msg.Nfsv4IllegalResponse(10044 /* Nfsv4Stat.NFS4ERR_OP_ILLEGAL */);
|
|
245
303
|
}
|
|
246
304
|
async PUTROOTFH(request, ctx) {
|
|
247
305
|
ctx.cfh = fh_1.ROOT_FH;
|
|
248
|
-
return new msg.Nfsv4PutrootfhResponse(0);
|
|
306
|
+
return new msg.Nfsv4PutrootfhResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
249
307
|
}
|
|
250
308
|
async PUTPUBFH(request, ctx) {
|
|
251
309
|
ctx.cfh = fh_1.ROOT_FH;
|
|
252
|
-
return new msg.Nfsv4PutpubfhResponse(0);
|
|
310
|
+
return new msg.Nfsv4PutpubfhResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
253
311
|
}
|
|
254
312
|
async PUTFH(request, ctx) {
|
|
255
313
|
const fh = request.object.data;
|
|
256
|
-
if (fh.length > 128)
|
|
257
|
-
throw 10001
|
|
314
|
+
if (fh.length > 128 /* Nfsv4Const.FHSIZE */)
|
|
315
|
+
throw 10001 /* Nfsv4Stat.NFS4ERR_BADHANDLE */;
|
|
258
316
|
const valid = this.fh.validate(fh);
|
|
259
317
|
if (!valid)
|
|
260
|
-
throw 10001
|
|
318
|
+
throw 10001 /* Nfsv4Stat.NFS4ERR_BADHANDLE */;
|
|
261
319
|
ctx.cfh = fh;
|
|
262
|
-
return new msg.Nfsv4PutfhResponse(0);
|
|
320
|
+
return new msg.Nfsv4PutfhResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
263
321
|
}
|
|
264
322
|
async GETFH(request, ctx) {
|
|
265
323
|
const cfh = ctx.cfh;
|
|
266
324
|
if (!cfh)
|
|
267
|
-
throw 10020
|
|
325
|
+
throw 10020 /* Nfsv4Stat.NFS4ERR_NOFILEHANDLE */;
|
|
268
326
|
const fh = new struct.Nfsv4Fh(cfh);
|
|
269
327
|
const body = new msg.Nfsv4GetfhResOk(fh);
|
|
270
|
-
return new msg.Nfsv4GetfhResponse(0
|
|
328
|
+
return new msg.Nfsv4GetfhResponse(0 /* Nfsv4Stat.NFS4_OK */, body);
|
|
271
329
|
}
|
|
272
330
|
async RESTOREFH(request, ctx) {
|
|
273
331
|
if (!ctx.sfh)
|
|
274
|
-
throw 10030
|
|
332
|
+
throw 10030 /* Nfsv4Stat.NFS4ERR_RESTOREFH */;
|
|
275
333
|
ctx.cfh = ctx.sfh;
|
|
276
|
-
return new msg.Nfsv4RestorefhResponse(0);
|
|
334
|
+
return new msg.Nfsv4RestorefhResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
277
335
|
}
|
|
278
336
|
async SAVEFH(request, ctx) {
|
|
279
337
|
if (!ctx.cfh)
|
|
280
|
-
throw 10020
|
|
338
|
+
throw 10020 /* Nfsv4Stat.NFS4ERR_NOFILEHANDLE */;
|
|
281
339
|
ctx.sfh = ctx.cfh;
|
|
282
|
-
return new msg.Nfsv4SavefhResponse(0);
|
|
340
|
+
return new msg.Nfsv4SavefhResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
283
341
|
}
|
|
284
342
|
absolutePath(path) {
|
|
285
343
|
const dir = this.dir;
|
|
@@ -289,9 +347,9 @@ class Nfsv4OperationsNode {
|
|
|
289
347
|
return path;
|
|
290
348
|
const absolutePath = NodePath.join(dir, path);
|
|
291
349
|
if (absolutePath.length < dir.length)
|
|
292
|
-
throw 2
|
|
350
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
293
351
|
if (!absolutePath.startsWith(dir))
|
|
294
|
-
throw 2
|
|
352
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
295
353
|
return absolutePath;
|
|
296
354
|
}
|
|
297
355
|
async LOOKUP(request, ctx) {
|
|
@@ -300,7 +358,7 @@ class Nfsv4OperationsNode {
|
|
|
300
358
|
const currentPathAbsolute = this.absolutePath(currentPath);
|
|
301
359
|
const component = request.objname;
|
|
302
360
|
if (component.length === 0)
|
|
303
|
-
throw 22
|
|
361
|
+
throw 22 /* Nfsv4Stat.NFS4ERR_INVAL */;
|
|
304
362
|
const promises = this.promises;
|
|
305
363
|
let stats;
|
|
306
364
|
try {
|
|
@@ -308,28 +366,28 @@ class Nfsv4OperationsNode {
|
|
|
308
366
|
}
|
|
309
367
|
catch (err) {
|
|
310
368
|
if ((0, util_1.isErrCode)('ENOENT', err))
|
|
311
|
-
throw 2
|
|
312
|
-
throw 5
|
|
369
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
370
|
+
throw 5 /* Nfsv4Stat.NFS4ERR_IO */;
|
|
313
371
|
}
|
|
314
372
|
if (stats.isSymbolicLink())
|
|
315
|
-
throw 10029
|
|
373
|
+
throw 10029 /* Nfsv4Stat.NFS4ERR_SYMLINK */;
|
|
316
374
|
if (!stats.isDirectory())
|
|
317
|
-
throw 20
|
|
375
|
+
throw 20 /* Nfsv4Stat.NFS4ERR_NOTDIR */;
|
|
318
376
|
const targetAbsolutePath = NodePath.join(currentPathAbsolute, component);
|
|
319
377
|
try {
|
|
320
378
|
const targetStats = await promises.stat(targetAbsolutePath);
|
|
321
379
|
if (!targetStats)
|
|
322
|
-
throw 2
|
|
380
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
323
381
|
}
|
|
324
382
|
catch (err) {
|
|
325
383
|
if ((0, util_1.isErrCode)('ENOENT', err))
|
|
326
|
-
throw 2
|
|
384
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
327
385
|
if ((0, util_1.isErrCode)('EACCES', err))
|
|
328
|
-
throw 13
|
|
329
|
-
throw 5
|
|
386
|
+
throw 13 /* Nfsv4Stat.NFS4ERR_ACCESS */;
|
|
387
|
+
throw 5 /* Nfsv4Stat.NFS4ERR_IO */;
|
|
330
388
|
}
|
|
331
389
|
fh.setCfh(ctx, targetAbsolutePath);
|
|
332
|
-
return new msg.Nfsv4LookupResponse(0);
|
|
390
|
+
return new msg.Nfsv4LookupResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
333
391
|
}
|
|
334
392
|
async LOOKUPP(request, ctx) {
|
|
335
393
|
const fh = this.fh;
|
|
@@ -342,16 +400,16 @@ class Nfsv4OperationsNode {
|
|
|
342
400
|
}
|
|
343
401
|
catch (err) {
|
|
344
402
|
if ((0, util_1.isErrCode)('ENOENT', err))
|
|
345
|
-
throw 2
|
|
346
|
-
throw 5
|
|
403
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
404
|
+
throw 5 /* Nfsv4Stat.NFS4ERR_IO */;
|
|
347
405
|
}
|
|
348
406
|
if (!stats.isDirectory())
|
|
349
|
-
throw 20
|
|
407
|
+
throw 20 /* Nfsv4Stat.NFS4ERR_NOTDIR */;
|
|
350
408
|
const parentAbsolutePath = NodePath.dirname(currentPathAbsolute);
|
|
351
409
|
if (parentAbsolutePath.length < this.dir.length)
|
|
352
|
-
throw 2
|
|
410
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
353
411
|
fh.setCfh(ctx, parentAbsolutePath);
|
|
354
|
-
return new msg.Nfsv4LookuppResponse(0);
|
|
412
|
+
return new msg.Nfsv4LookuppResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
355
413
|
}
|
|
356
414
|
async GETATTR(request, ctx) {
|
|
357
415
|
const currentPath = this.fh.currentPath(ctx);
|
|
@@ -378,7 +436,7 @@ class Nfsv4OperationsNode {
|
|
|
378
436
|
}
|
|
379
437
|
}
|
|
380
438
|
const attrs = (0, attrs_1.encodeAttrs)(request.attrRequest, stats, currentPath, ctx.cfh, this.leaseTime, fsStats);
|
|
381
|
-
return new msg.Nfsv4GetattrResponse(0
|
|
439
|
+
return new msg.Nfsv4GetattrResponse(0 /* Nfsv4Stat.NFS4_OK */, new msg.Nfsv4GetattrResOk(attrs));
|
|
382
440
|
}
|
|
383
441
|
async ACCESS(request, ctx) {
|
|
384
442
|
const currentPath = this.fh.currentPath(ctx);
|
|
@@ -396,43 +454,43 @@ class Nfsv4OperationsNode {
|
|
|
396
454
|
const mode = stats.mode;
|
|
397
455
|
let supported = 0;
|
|
398
456
|
let access = 0;
|
|
399
|
-
if (requestedAccess & 1) {
|
|
400
|
-
supported |= 1
|
|
457
|
+
if (requestedAccess & 1 /* Nfsv4Access.ACCESS4_READ */) {
|
|
458
|
+
supported |= 1 /* Nfsv4Access.ACCESS4_READ */;
|
|
401
459
|
if (mode & 0o444)
|
|
402
|
-
access |= 1
|
|
460
|
+
access |= 1 /* Nfsv4Access.ACCESS4_READ */;
|
|
403
461
|
}
|
|
404
|
-
if (requestedAccess & 2) {
|
|
405
|
-
supported |= 2
|
|
462
|
+
if (requestedAccess & 2 /* Nfsv4Access.ACCESS4_LOOKUP */) {
|
|
463
|
+
supported |= 2 /* Nfsv4Access.ACCESS4_LOOKUP */;
|
|
406
464
|
if (isDirectory && mode & 0o111)
|
|
407
|
-
access |= 2
|
|
465
|
+
access |= 2 /* Nfsv4Access.ACCESS4_LOOKUP */;
|
|
408
466
|
}
|
|
409
|
-
if (requestedAccess & 4) {
|
|
410
|
-
supported |= 4
|
|
467
|
+
if (requestedAccess & 4 /* Nfsv4Access.ACCESS4_MODIFY */) {
|
|
468
|
+
supported |= 4 /* Nfsv4Access.ACCESS4_MODIFY */;
|
|
411
469
|
if (mode & 0o222)
|
|
412
|
-
access |= 4
|
|
470
|
+
access |= 4 /* Nfsv4Access.ACCESS4_MODIFY */;
|
|
413
471
|
}
|
|
414
|
-
if (requestedAccess & 8) {
|
|
415
|
-
supported |= 8
|
|
472
|
+
if (requestedAccess & 8 /* Nfsv4Access.ACCESS4_EXTEND */) {
|
|
473
|
+
supported |= 8 /* Nfsv4Access.ACCESS4_EXTEND */;
|
|
416
474
|
if (mode & 0o222)
|
|
417
|
-
access |= 8
|
|
475
|
+
access |= 8 /* Nfsv4Access.ACCESS4_EXTEND */;
|
|
418
476
|
}
|
|
419
|
-
if (requestedAccess & 16) {
|
|
477
|
+
if (requestedAccess & 16 /* Nfsv4Access.ACCESS4_DELETE */) {
|
|
420
478
|
if (!isDirectory) {
|
|
421
479
|
supported |= 0;
|
|
422
480
|
}
|
|
423
481
|
else {
|
|
424
|
-
supported |= 16
|
|
482
|
+
supported |= 16 /* Nfsv4Access.ACCESS4_DELETE */;
|
|
425
483
|
if (mode & 0o222)
|
|
426
|
-
access |= 16
|
|
484
|
+
access |= 16 /* Nfsv4Access.ACCESS4_DELETE */;
|
|
427
485
|
}
|
|
428
486
|
}
|
|
429
|
-
if (requestedAccess & 32) {
|
|
430
|
-
supported |= 32
|
|
487
|
+
if (requestedAccess & 32 /* Nfsv4Access.ACCESS4_EXECUTE */) {
|
|
488
|
+
supported |= 32 /* Nfsv4Access.ACCESS4_EXECUTE */;
|
|
431
489
|
if (!isDirectory && mode & 0o111)
|
|
432
|
-
access |= 32
|
|
490
|
+
access |= 32 /* Nfsv4Access.ACCESS4_EXECUTE */;
|
|
433
491
|
}
|
|
434
492
|
const body = new msg.Nfsv4AccessResOk(supported, access);
|
|
435
|
-
return new msg.Nfsv4AccessResponse(0
|
|
493
|
+
return new msg.Nfsv4AccessResponse(0 /* Nfsv4Stat.NFS4_OK */, body);
|
|
436
494
|
}
|
|
437
495
|
async READDIR(request, ctx) {
|
|
438
496
|
const fh = this.fh;
|
|
@@ -447,7 +505,7 @@ class Nfsv4OperationsNode {
|
|
|
447
505
|
throw (0, util_1.normalizeNodeFsError)(error, ctx.connection.logger);
|
|
448
506
|
}
|
|
449
507
|
if (!stats.isDirectory())
|
|
450
|
-
throw 20
|
|
508
|
+
throw 20 /* Nfsv4Stat.NFS4ERR_NOTDIR */;
|
|
451
509
|
const cookie = request.cookie;
|
|
452
510
|
const requestedCookieverf = request.cookieverf.data;
|
|
453
511
|
const maxcount = request.maxcount;
|
|
@@ -465,7 +523,7 @@ class Nfsv4OperationsNode {
|
|
|
465
523
|
const view = new DataView(cookieverf.buffer);
|
|
466
524
|
view.setBigUint64(0, changeTime, false);
|
|
467
525
|
if (!(0, cmpUint8Array_1.cmpUint8Array)(requestedCookieverf, cookieverf))
|
|
468
|
-
throw 10027
|
|
526
|
+
throw 10027 /* Nfsv4Stat.NFS4ERR_NOT_SAME */;
|
|
469
527
|
}
|
|
470
528
|
let dirents;
|
|
471
529
|
try {
|
|
@@ -496,7 +554,7 @@ class Nfsv4OperationsNode {
|
|
|
496
554
|
try {
|
|
497
555
|
entryStats = await promises.lstat(entryPath);
|
|
498
556
|
}
|
|
499
|
-
catch (
|
|
557
|
+
catch (_error) {
|
|
500
558
|
continue;
|
|
501
559
|
}
|
|
502
560
|
const entryFh = fh.encode(entryPath);
|
|
@@ -514,7 +572,7 @@ class Nfsv4OperationsNode {
|
|
|
514
572
|
}
|
|
515
573
|
const cookieverf2 = new struct.Nfsv4Verifier(cookieverf);
|
|
516
574
|
const body = new msg.Nfsv4ReaddirResOk(cookieverf2, entries, eof);
|
|
517
|
-
return new msg.Nfsv4ReaddirResponse(0
|
|
575
|
+
return new msg.Nfsv4ReaddirResponse(0 /* Nfsv4Stat.NFS4_OK */, body);
|
|
518
576
|
}
|
|
519
577
|
async OPEN(request, ctx) {
|
|
520
578
|
const currentPath = this.fh.currentPath(ctx);
|
|
@@ -537,15 +595,15 @@ class Nfsv4OperationsNode {
|
|
|
537
595
|
previousSeqid = 0;
|
|
538
596
|
}
|
|
539
597
|
else {
|
|
540
|
-
return new msg.Nfsv4OpenResponse(10026);
|
|
598
|
+
return new msg.Nfsv4OpenResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
541
599
|
}
|
|
542
600
|
}
|
|
543
601
|
else if (seqidValidation === 'replay') {
|
|
544
602
|
replayCandidate = true;
|
|
545
603
|
}
|
|
546
604
|
}
|
|
547
|
-
if (request.claim.claimType !== 0) {
|
|
548
|
-
return new msg.Nfsv4OpenResponse(10004);
|
|
605
|
+
if (request.claim.claimType !== 0 /* Nfsv4OpenClaimType.CLAIM_NULL */) {
|
|
606
|
+
return new msg.Nfsv4OpenResponse(10004 /* Nfsv4Stat.NFS4ERR_NOTSUPP */);
|
|
549
607
|
}
|
|
550
608
|
const claimNull = request.claim.claim;
|
|
551
609
|
const filename = claimNull.file;
|
|
@@ -555,16 +613,16 @@ class Nfsv4OperationsNode {
|
|
|
555
613
|
if (ownerState.lastRequestKey === requestKey && ownerState.lastResponse) {
|
|
556
614
|
return ownerState.lastResponse;
|
|
557
615
|
}
|
|
558
|
-
return new msg.Nfsv4OpenResponse(10026);
|
|
616
|
+
return new msg.Nfsv4OpenResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
559
617
|
}
|
|
560
618
|
ownerState.seqid = request.seqid;
|
|
561
619
|
const opentype = request.openhow.opentype;
|
|
562
|
-
const isCreate = opentype === 1
|
|
620
|
+
const isCreate = opentype === 1 /* Nfsv4OpenFlags.OPEN4_CREATE */;
|
|
563
621
|
let fileExists = false;
|
|
564
622
|
try {
|
|
565
623
|
const stats = await this.promises.lstat(filePath);
|
|
566
624
|
if (!stats.isFile()) {
|
|
567
|
-
const response = new msg.Nfsv4OpenResponse(21);
|
|
625
|
+
const response = new msg.Nfsv4OpenResponse(21 /* Nfsv4Stat.NFS4ERR_ISDIR */);
|
|
568
626
|
ownerState.lastResponse = response;
|
|
569
627
|
ownerState.lastRequestKey = requestKey;
|
|
570
628
|
return response;
|
|
@@ -574,7 +632,7 @@ class Nfsv4OperationsNode {
|
|
|
574
632
|
catch (err) {
|
|
575
633
|
if ((0, util_1.isErrCode)('ENOENT', err)) {
|
|
576
634
|
if (!isCreate) {
|
|
577
|
-
const response = new msg.Nfsv4OpenResponse(2);
|
|
635
|
+
const response = new msg.Nfsv4OpenResponse(2 /* Nfsv4Stat.NFS4ERR_NOENT */);
|
|
578
636
|
ownerState.lastResponse = response;
|
|
579
637
|
ownerState.lastRequestKey = requestKey;
|
|
580
638
|
return response;
|
|
@@ -590,18 +648,18 @@ class Nfsv4OperationsNode {
|
|
|
590
648
|
}
|
|
591
649
|
if (fileExists && !this.canAccessFile(filePath, request.shareAccess, request.shareDeny)) {
|
|
592
650
|
ownerState.seqid = previousSeqid;
|
|
593
|
-
const response = new msg.Nfsv4OpenResponse(10015);
|
|
651
|
+
const response = new msg.Nfsv4OpenResponse(10015 /* Nfsv4Stat.NFS4ERR_SHARE_DENIED */);
|
|
594
652
|
ownerState.lastResponse = response;
|
|
595
653
|
ownerState.lastRequestKey = requestKey;
|
|
596
654
|
return response;
|
|
597
655
|
}
|
|
598
656
|
let flags = 0;
|
|
599
|
-
const isWrite = (request.shareAccess & 2) !== 0;
|
|
600
|
-
const isRead = (request.shareAccess & 1) !== 0;
|
|
657
|
+
const isWrite = (request.shareAccess & 2 /* Nfsv4OpenAccess.OPEN4_SHARE_ACCESS_WRITE */) !== 0;
|
|
658
|
+
const isRead = (request.shareAccess & 1 /* Nfsv4OpenAccess.OPEN4_SHARE_ACCESS_READ */) !== 0;
|
|
601
659
|
if (isCreate) {
|
|
602
660
|
flags = this.fs.constants.O_CREAT;
|
|
603
661
|
const createHow = request.openhow.how;
|
|
604
|
-
if (createHow && createHow.mode === 2) {
|
|
662
|
+
if (createHow && createHow.mode === 2 /* Nfsv4CreateMode.EXCLUSIVE4 */) {
|
|
605
663
|
flags |= this.fs.constants.O_EXCL;
|
|
606
664
|
}
|
|
607
665
|
}
|
|
@@ -627,9 +685,9 @@ class Nfsv4OperationsNode {
|
|
|
627
685
|
const after = ++this.changeCounter;
|
|
628
686
|
const cinfo = new struct.Nfsv4ChangeInfo(true, before, after);
|
|
629
687
|
const attrset = new struct.Nfsv4Bitmap([]);
|
|
630
|
-
const delegation = new struct.Nfsv4OpenDelegation(0);
|
|
688
|
+
const delegation = new struct.Nfsv4OpenDelegation(0 /* Nfsv4DelegType.OPEN_DELEGATE_NONE */);
|
|
631
689
|
const resok = new msg.Nfsv4OpenResOk(stateid, cinfo, 0, attrset, delegation);
|
|
632
|
-
const response = new msg.Nfsv4OpenResponse(0
|
|
690
|
+
const response = new msg.Nfsv4OpenResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
633
691
|
ownerState.lastResponse = response;
|
|
634
692
|
ownerState.lastRequestKey = requestKey;
|
|
635
693
|
return response;
|
|
@@ -643,23 +701,23 @@ class Nfsv4OperationsNode {
|
|
|
643
701
|
}
|
|
644
702
|
}
|
|
645
703
|
async OPENATTR(request, ctx) {
|
|
646
|
-
return new msg.Nfsv4OpenattrResponse(10004);
|
|
704
|
+
return new msg.Nfsv4OpenattrResponse(10004 /* Nfsv4Stat.NFS4ERR_NOTSUPP */);
|
|
647
705
|
}
|
|
648
706
|
async OPEN_CONFIRM(request, ctx) {
|
|
649
707
|
const stateidKey = this.makeStateidKey(request.openStateid);
|
|
650
708
|
const openFile = this.openFiles.get(stateidKey);
|
|
651
709
|
if (!openFile)
|
|
652
|
-
throw 10025
|
|
710
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
653
711
|
const ownerState = this.openOwners.get(openFile.openOwnerKey);
|
|
654
712
|
if (!ownerState)
|
|
655
|
-
throw 10025
|
|
713
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
656
714
|
const seqidValidation = this.validateSeqid(request.seqid, ownerState.seqid);
|
|
657
715
|
if (seqidValidation === 'invalid')
|
|
658
|
-
throw 10026
|
|
716
|
+
throw 10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */;
|
|
659
717
|
if (seqidValidation === 'replay') {
|
|
660
718
|
const newStateid = new struct.Nfsv4Stateid(openFile.stateid.seqid, openFile.stateid.other);
|
|
661
719
|
const resok = new msg.Nfsv4OpenConfirmResOk(newStateid);
|
|
662
|
-
return new msg.Nfsv4OpenConfirmResponse(0
|
|
720
|
+
return new msg.Nfsv4OpenConfirmResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
663
721
|
}
|
|
664
722
|
ownerState.seqid = request.seqid;
|
|
665
723
|
openFile.confirmed = true;
|
|
@@ -673,29 +731,29 @@ class Nfsv4OperationsNode {
|
|
|
673
731
|
ownerState.opens.delete(oldKey);
|
|
674
732
|
ownerState.opens.add(newKey);
|
|
675
733
|
const resok = new msg.Nfsv4OpenConfirmResOk(newStateid);
|
|
676
|
-
return new msg.Nfsv4OpenConfirmResponse(0
|
|
734
|
+
return new msg.Nfsv4OpenConfirmResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
677
735
|
}
|
|
678
736
|
async OPEN_DOWNGRADE(request, ctx) {
|
|
679
737
|
const stateidKey = this.makeStateidKey(request.openStateid);
|
|
680
738
|
const openFile = this.openFiles.get(stateidKey);
|
|
681
739
|
if (!openFile)
|
|
682
|
-
throw 10025
|
|
740
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
683
741
|
const ownerState = this.openOwners.get(openFile.openOwnerKey);
|
|
684
742
|
if (!ownerState)
|
|
685
|
-
throw 10025
|
|
743
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
686
744
|
const seqidValidation = this.validateSeqid(request.seqid, ownerState.seqid);
|
|
687
745
|
if (seqidValidation === 'invalid')
|
|
688
|
-
throw 10026
|
|
746
|
+
throw 10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */;
|
|
689
747
|
if (seqidValidation === 'replay') {
|
|
690
748
|
const newStateid = new struct.Nfsv4Stateid(openFile.stateid.seqid, openFile.stateid.other);
|
|
691
749
|
const resok = new msg.Nfsv4OpenDowngradeResOk(newStateid);
|
|
692
|
-
return new msg.Nfsv4OpenDowngradeResponse(0
|
|
750
|
+
return new msg.Nfsv4OpenDowngradeResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
693
751
|
}
|
|
694
752
|
ownerState.seqid = request.seqid;
|
|
695
753
|
if ((request.shareAccess & ~openFile.shareAccess) !== 0)
|
|
696
|
-
throw 22
|
|
754
|
+
throw 22 /* Nfsv4Stat.NFS4ERR_INVAL */;
|
|
697
755
|
if ((request.shareDeny & ~openFile.shareDeny) !== 0)
|
|
698
|
-
throw 22
|
|
756
|
+
throw 22 /* Nfsv4Stat.NFS4ERR_INVAL */;
|
|
699
757
|
const newSeqid = this.nextStateidSeqid++;
|
|
700
758
|
const newStateid = new struct.Nfsv4Stateid(newSeqid, openFile.stateid.other);
|
|
701
759
|
const oldKey = stateidKey;
|
|
@@ -706,27 +764,27 @@ class Nfsv4OperationsNode {
|
|
|
706
764
|
ownerState.opens.delete(oldKey);
|
|
707
765
|
ownerState.opens.add(newKey);
|
|
708
766
|
const resok = new msg.Nfsv4OpenDowngradeResOk(newStateid);
|
|
709
|
-
return new msg.Nfsv4OpenDowngradeResponse(0
|
|
767
|
+
return new msg.Nfsv4OpenDowngradeResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
710
768
|
}
|
|
711
769
|
async CLOSE(request, ctx) {
|
|
712
770
|
const stateidKey = this.makeStateidKey(request.openStateid);
|
|
713
771
|
const openFile = this.openFiles.get(stateidKey);
|
|
714
772
|
if (!openFile) {
|
|
715
|
-
return new msg.Nfsv4CloseResponse(0
|
|
773
|
+
return new msg.Nfsv4CloseResponse(0 /* Nfsv4Stat.NFS4_OK */, new msg.Nfsv4CloseResOk(request.openStateid));
|
|
716
774
|
}
|
|
717
775
|
const ownerState = this.openOwners.get(openFile.openOwnerKey);
|
|
718
776
|
if (!ownerState) {
|
|
719
|
-
return new msg.Nfsv4CloseResponse(10025);
|
|
777
|
+
return new msg.Nfsv4CloseResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
720
778
|
}
|
|
721
779
|
this.renewClientLease(ownerState.clientid);
|
|
722
780
|
const seqidValidation = this.validateSeqid(request.seqid, ownerState.seqid);
|
|
723
781
|
if (seqidValidation === 'invalid') {
|
|
724
|
-
return new msg.Nfsv4CloseResponse(10026);
|
|
782
|
+
return new msg.Nfsv4CloseResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
725
783
|
}
|
|
726
784
|
if (seqidValidation === 'replay') {
|
|
727
785
|
const newStateid = new struct.Nfsv4Stateid(openFile.stateid.seqid, openFile.stateid.other);
|
|
728
786
|
const resok = new msg.Nfsv4CloseResOk(newStateid);
|
|
729
|
-
return new msg.Nfsv4CloseResponse(0
|
|
787
|
+
return new msg.Nfsv4CloseResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
730
788
|
}
|
|
731
789
|
ownerState.seqid = request.seqid;
|
|
732
790
|
try {
|
|
@@ -737,7 +795,7 @@ class Nfsv4OperationsNode {
|
|
|
737
795
|
}
|
|
738
796
|
catch (err) {
|
|
739
797
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
740
|
-
if (status !== 2) {
|
|
798
|
+
if (status !== 2 /* Nfsv4Stat.NFS4ERR_NOENT */) {
|
|
741
799
|
return new msg.Nfsv4CloseResponse(status);
|
|
742
800
|
}
|
|
743
801
|
}
|
|
@@ -749,7 +807,7 @@ class Nfsv4OperationsNode {
|
|
|
749
807
|
const newSeqid = this.nextStateidSeqid++;
|
|
750
808
|
const newStateid = new struct.Nfsv4Stateid(newSeqid, openFile.stateid.other);
|
|
751
809
|
const resok = new msg.Nfsv4CloseResOk(newStateid);
|
|
752
|
-
return new msg.Nfsv4CloseResponse(0
|
|
810
|
+
return new msg.Nfsv4CloseResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
753
811
|
}
|
|
754
812
|
async SECINFO(request, ctx) {
|
|
755
813
|
const currentPath = this.fh.currentPath(ctx);
|
|
@@ -760,14 +818,14 @@ class Nfsv4OperationsNode {
|
|
|
760
818
|
}
|
|
761
819
|
catch (err) {
|
|
762
820
|
if ((0, util_1.isErrCode)(err, 'ENOENT')) {
|
|
763
|
-
return new msg.Nfsv4SecinfoResponse(2);
|
|
821
|
+
return new msg.Nfsv4SecinfoResponse(2 /* Nfsv4Stat.NFS4ERR_NOENT */);
|
|
764
822
|
}
|
|
765
823
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
766
824
|
return new msg.Nfsv4SecinfoResponse(status);
|
|
767
825
|
}
|
|
768
826
|
const flavors = [new struct.Nfsv4SecInfoFlavor(1)];
|
|
769
827
|
const resok = new msg.Nfsv4SecinfoResOk(flavors);
|
|
770
|
-
return new msg.Nfsv4SecinfoResponse(0
|
|
828
|
+
return new msg.Nfsv4SecinfoResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
771
829
|
}
|
|
772
830
|
async LOCK(request, ctx) {
|
|
773
831
|
const currentPath = this.fh.currentPath(ctx);
|
|
@@ -783,31 +841,31 @@ class Nfsv4OperationsNode {
|
|
|
783
841
|
}
|
|
784
842
|
}
|
|
785
843
|
if (!existingLockOwnerKey) {
|
|
786
|
-
return new msg.Nfsv4LockResponse(10025);
|
|
844
|
+
return new msg.Nfsv4LockResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
787
845
|
}
|
|
788
846
|
const lockOwnerState = this.lockOwners.get(existingLockOwnerKey);
|
|
789
847
|
if (!lockOwnerState) {
|
|
790
|
-
return new msg.Nfsv4LockResponse(10025);
|
|
848
|
+
return new msg.Nfsv4LockResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
791
849
|
}
|
|
792
850
|
this.renewClientLease(lockOwnerState.clientid);
|
|
793
851
|
const seqidValidation = this.validateSeqid(existingOwner.lockSeqid, lockOwnerState.seqid);
|
|
794
852
|
const requestKey = this.makeLockRequestKey(existingLockOwnerKey, currentPath, locktype, offset, length, existingOwner.lockSeqid);
|
|
795
853
|
if (seqidValidation === 'invalid') {
|
|
796
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
854
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
797
855
|
}
|
|
798
856
|
if (seqidValidation === 'replay') {
|
|
799
857
|
if (lockOwnerState.lastRequestKey !== requestKey) {
|
|
800
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
858
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
801
859
|
}
|
|
802
860
|
if (lockOwnerState.lastResponse)
|
|
803
861
|
return lockOwnerState.lastResponse;
|
|
804
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
862
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
805
863
|
}
|
|
806
864
|
lockOwnerState.seqid = existingOwner.lockSeqid;
|
|
807
865
|
if (this.hasConflictingLock(currentPath, locktype, offset, length, existingLockOwnerKey)) {
|
|
808
866
|
const conflictOwner = new struct.Nfsv4LockOwner(BigInt(0), new Uint8Array());
|
|
809
867
|
const denied = new msg.Nfsv4LockResDenied(offset, length, locktype, conflictOwner);
|
|
810
|
-
return new msg.Nfsv4LockResponse(10010
|
|
868
|
+
return new msg.Nfsv4LockResponse(10010 /* Nfsv4Stat.NFS4ERR_DENIED */, undefined, denied);
|
|
811
869
|
}
|
|
812
870
|
const lockStateid = this.getOrCreateLockStateid(existingLockOwnerKey, currentPath);
|
|
813
871
|
const stateid = lockStateid.incrementAndGetStateid();
|
|
@@ -816,7 +874,7 @@ class Nfsv4OperationsNode {
|
|
|
816
874
|
this.locks.set(lockKey, lock);
|
|
817
875
|
lockOwnerState.locks.add(lockKey);
|
|
818
876
|
const resok = new msg.Nfsv4LockResOk(stateid);
|
|
819
|
-
const response = new msg.Nfsv4LockResponse(0
|
|
877
|
+
const response = new msg.Nfsv4LockResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
820
878
|
lockOwnerState.lastResponse = response;
|
|
821
879
|
lockOwnerState.lastRequestKey = requestKey;
|
|
822
880
|
return response;
|
|
@@ -827,26 +885,26 @@ class Nfsv4OperationsNode {
|
|
|
827
885
|
const openStateidKey = this.makeStateidKey(openToLock.openStateid);
|
|
828
886
|
const openFile = this.openFiles.get(openStateidKey);
|
|
829
887
|
if (!openFile) {
|
|
830
|
-
return new msg.Nfsv4LockResponse(10025);
|
|
888
|
+
return new msg.Nfsv4LockResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
831
889
|
}
|
|
832
890
|
const openOwnerKey = openFile.openOwnerKey;
|
|
833
891
|
const openOwnerState = this.openOwners.get(openOwnerKey);
|
|
834
892
|
if (!openOwnerState) {
|
|
835
|
-
return new msg.Nfsv4LockResponse(10025);
|
|
893
|
+
return new msg.Nfsv4LockResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
836
894
|
}
|
|
837
895
|
this.renewClientLease(lockOwnerData.clientid);
|
|
838
896
|
const seqidValidation = this.validateSeqid(openToLock.openSeqid, openOwnerState.seqid);
|
|
839
897
|
if (seqidValidation === 'invalid') {
|
|
840
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
898
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
841
899
|
}
|
|
842
900
|
if (seqidValidation === 'replay') {
|
|
843
|
-
for (const [
|
|
901
|
+
for (const [_key, lock] of this.locks.entries()) {
|
|
844
902
|
if (lock.lockOwnerKey === this.makeLockOwnerKey(lockOwnerData.clientid, lockOwnerData.owner) &&
|
|
845
903
|
lock.path === currentPath &&
|
|
846
904
|
lock.offset === offset &&
|
|
847
905
|
lock.length === length) {
|
|
848
906
|
const resok = new msg.Nfsv4LockResOk(lock.stateid);
|
|
849
|
-
return new msg.Nfsv4LockResponse(0
|
|
907
|
+
return new msg.Nfsv4LockResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
850
908
|
}
|
|
851
909
|
}
|
|
852
910
|
}
|
|
@@ -856,12 +914,12 @@ class Nfsv4OperationsNode {
|
|
|
856
914
|
if (this.hasConflictingLock(currentPath, locktype, offset, length, lockOwnerKey)) {
|
|
857
915
|
const conflictOwner = new struct.Nfsv4LockOwner(BigInt(0), new Uint8Array());
|
|
858
916
|
const denied = new msg.Nfsv4LockResDenied(offset, length, locktype, conflictOwner);
|
|
859
|
-
return new msg.Nfsv4LockResponse(10010
|
|
917
|
+
return new msg.Nfsv4LockResponse(10010 /* Nfsv4Stat.NFS4ERR_DENIED */, undefined, denied);
|
|
860
918
|
}
|
|
861
919
|
let lockOwnerState = this.lockOwners.get(lockOwnerKey);
|
|
862
920
|
if (!lockOwnerState) {
|
|
863
921
|
if (openToLock.lockSeqid !== 0) {
|
|
864
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
922
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
865
923
|
}
|
|
866
924
|
lockOwnerState = new LockOwnerState_1.LockOwnerState(lockOwnerData.clientid, lockOwnerData.owner, 0);
|
|
867
925
|
this.lockOwners.set(lockOwnerKey, lockOwnerState);
|
|
@@ -869,13 +927,13 @@ class Nfsv4OperationsNode {
|
|
|
869
927
|
else {
|
|
870
928
|
const lockSeqidValidation = this.validateSeqid(openToLock.lockSeqid, lockOwnerState.seqid);
|
|
871
929
|
if (lockSeqidValidation === 'invalid') {
|
|
872
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
930
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
873
931
|
}
|
|
874
932
|
if (lockSeqidValidation === 'replay') {
|
|
875
933
|
if (lockOwnerState.lastRequestKey === lockRequestKey && lockOwnerState.lastResponse) {
|
|
876
934
|
return lockOwnerState.lastResponse;
|
|
877
935
|
}
|
|
878
|
-
return new msg.Nfsv4LockResponse(10026);
|
|
936
|
+
return new msg.Nfsv4LockResponse(10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */);
|
|
879
937
|
}
|
|
880
938
|
}
|
|
881
939
|
lockOwnerState.seqid = openToLock.lockSeqid;
|
|
@@ -886,7 +944,7 @@ class Nfsv4OperationsNode {
|
|
|
886
944
|
this.locks.set(lockKey, lock);
|
|
887
945
|
lockOwnerState.locks.add(lockKey);
|
|
888
946
|
const resok = new msg.Nfsv4LockResOk(stateid);
|
|
889
|
-
const response = new msg.Nfsv4LockResponse(0
|
|
947
|
+
const response = new msg.Nfsv4LockResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
890
948
|
lockOwnerState.lastResponse = response;
|
|
891
949
|
lockOwnerState.lastRequestKey = lockRequestKey;
|
|
892
950
|
return response;
|
|
@@ -898,33 +956,33 @@ class Nfsv4OperationsNode {
|
|
|
898
956
|
if (this.hasConflictingLock(currentPath, locktype, offset, length, ownerKey)) {
|
|
899
957
|
const conflictOwner = new struct.Nfsv4LockOwner(BigInt(0), new Uint8Array());
|
|
900
958
|
const denied = new msg.Nfsv4LocktResDenied(offset, length, locktype, conflictOwner);
|
|
901
|
-
return new msg.Nfsv4LocktResponse(10010
|
|
959
|
+
return new msg.Nfsv4LocktResponse(10010 /* Nfsv4Stat.NFS4ERR_DENIED */, denied);
|
|
902
960
|
}
|
|
903
|
-
return new msg.Nfsv4LocktResponse(0);
|
|
961
|
+
return new msg.Nfsv4LocktResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
904
962
|
}
|
|
905
963
|
async LOCKU(request, ctx) {
|
|
906
964
|
const { lockStateid, offset, length, seqid } = request;
|
|
907
965
|
const lockStateidState = this.findLockStateidByOther(lockStateid.other);
|
|
908
966
|
if (!lockStateidState)
|
|
909
|
-
throw 10025
|
|
967
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
910
968
|
const ownerKey = lockStateidState.lockOwnerKey;
|
|
911
969
|
const lockOwnerState = this.lockOwners.get(ownerKey);
|
|
912
970
|
if (!lockOwnerState)
|
|
913
|
-
throw 10025
|
|
971
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
914
972
|
this.renewClientLease(lockOwnerState.clientid);
|
|
915
973
|
const currentPath = this.fh.currentPath(ctx);
|
|
916
974
|
if (lockStateidState.path !== currentPath)
|
|
917
|
-
throw 10025
|
|
975
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
918
976
|
const requestKey = this.makeLockuRequestKey(ownerKey, lockStateid, offset, length, seqid);
|
|
919
977
|
const seqidValidation = this.validateSeqid(seqid, lockOwnerState.seqid);
|
|
920
978
|
if (seqidValidation === 'invalid') {
|
|
921
|
-
throw 10026
|
|
979
|
+
throw 10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */;
|
|
922
980
|
}
|
|
923
981
|
if (seqidValidation === 'replay') {
|
|
924
982
|
if (lockOwnerState.lastRequestKey === requestKey && lockOwnerState.lastResponse) {
|
|
925
983
|
return lockOwnerState.lastResponse;
|
|
926
984
|
}
|
|
927
|
-
throw 10026
|
|
985
|
+
throw 10026 /* Nfsv4Stat.NFS4ERR_BAD_SEQID */;
|
|
928
986
|
}
|
|
929
987
|
lockOwnerState.seqid = seqid;
|
|
930
988
|
const lockKey = this.makeLockKey(lockStateid, offset, length);
|
|
@@ -935,7 +993,7 @@ class Nfsv4OperationsNode {
|
|
|
935
993
|
}
|
|
936
994
|
const stateid = lockStateidState.incrementAndGetStateid();
|
|
937
995
|
const resok = new msg.Nfsv4LockuResOk(stateid);
|
|
938
|
-
const response = new msg.Nfsv4LockuResponse(0
|
|
996
|
+
const response = new msg.Nfsv4LockuResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
939
997
|
lockOwnerState.lastResponse = response;
|
|
940
998
|
lockOwnerState.lastRequestKey = requestKey;
|
|
941
999
|
return response;
|
|
@@ -945,26 +1003,27 @@ class Nfsv4OperationsNode {
|
|
|
945
1003
|
const ownerKey = this.makeLockOwnerKey(lockOwner.clientid, lockOwner.owner);
|
|
946
1004
|
const lockOwnerState = this.lockOwners.get(ownerKey);
|
|
947
1005
|
if (!lockOwnerState)
|
|
948
|
-
throw 10025
|
|
1006
|
+
throw 10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */;
|
|
949
1007
|
for (const lockKey of lockOwnerState.locks)
|
|
950
1008
|
this.locks.delete(lockKey);
|
|
951
1009
|
this.lockOwners.delete(ownerKey);
|
|
952
|
-
return new msg.Nfsv4ReleaseLockOwnerResponse(0);
|
|
1010
|
+
return new msg.Nfsv4ReleaseLockOwnerResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
953
1011
|
}
|
|
954
1012
|
async RENEW(request, ctx) {
|
|
955
1013
|
const clientid = request.clientid;
|
|
956
1014
|
const client = this.clients.get(clientid);
|
|
957
1015
|
if (!client)
|
|
958
|
-
throw 10022
|
|
959
|
-
return new msg.Nfsv4RenewResponse(0);
|
|
1016
|
+
throw 10022 /* Nfsv4Stat.NFS4ERR_STALE_CLIENTID */;
|
|
1017
|
+
return new msg.Nfsv4RenewResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
960
1018
|
}
|
|
961
1019
|
async READ(request, ctx) {
|
|
962
1020
|
const stateidKey = this.makeStateidKey(request.stateid);
|
|
963
1021
|
const openFile = this.openFiles.get(stateidKey);
|
|
964
1022
|
if (!openFile)
|
|
965
|
-
return new msg.Nfsv4ReadResponse(10025);
|
|
1023
|
+
return new msg.Nfsv4ReadResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
966
1024
|
const fdHandle = openFile.fd;
|
|
967
|
-
|
|
1025
|
+
// If we have an fd-like handle, use its .read; otherwise open the path
|
|
1026
|
+
let fd;
|
|
968
1027
|
let openedHere = false;
|
|
969
1028
|
try {
|
|
970
1029
|
if (fdHandle && typeof fdHandle.read === 'function') {
|
|
@@ -979,7 +1038,7 @@ class Nfsv4OperationsNode {
|
|
|
979
1038
|
const eof = bytesRead < request.count;
|
|
980
1039
|
const data = buf.slice(0, bytesRead);
|
|
981
1040
|
const resok = new msg.Nfsv4ReadResOk(eof, data);
|
|
982
|
-
return new msg.Nfsv4ReadResponse(0
|
|
1041
|
+
return new msg.Nfsv4ReadResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
983
1042
|
}
|
|
984
1043
|
catch (err) {
|
|
985
1044
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -990,7 +1049,8 @@ class Nfsv4OperationsNode {
|
|
|
990
1049
|
if (openedHere && fd && typeof fd.close === 'function')
|
|
991
1050
|
await fd.close();
|
|
992
1051
|
}
|
|
993
|
-
catch (
|
|
1052
|
+
catch (_e) {
|
|
1053
|
+
/* ignore close errors */
|
|
994
1054
|
}
|
|
995
1055
|
}
|
|
996
1056
|
}
|
|
@@ -1000,7 +1060,7 @@ class Nfsv4OperationsNode {
|
|
|
1000
1060
|
try {
|
|
1001
1061
|
const target = await this.promises.readlink(currentPathAbsolute);
|
|
1002
1062
|
const resok = new msg.Nfsv4ReadlinkResOk(target);
|
|
1003
|
-
return new msg.Nfsv4ReadlinkResponse(0
|
|
1063
|
+
return new msg.Nfsv4ReadlinkResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1004
1064
|
}
|
|
1005
1065
|
catch (err) {
|
|
1006
1066
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1023,7 +1083,7 @@ class Nfsv4OperationsNode {
|
|
|
1023
1083
|
const after = ++this.changeCounter;
|
|
1024
1084
|
const cinfo = new struct.Nfsv4ChangeInfo(true, before, after);
|
|
1025
1085
|
const resok = new msg.Nfsv4RemoveResOk(cinfo);
|
|
1026
|
-
return new msg.Nfsv4RemoveResponse(0
|
|
1086
|
+
return new msg.Nfsv4RemoveResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1027
1087
|
}
|
|
1028
1088
|
catch (err) {
|
|
1029
1089
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1038,11 +1098,11 @@ class Nfsv4OperationsNode {
|
|
|
1038
1098
|
const oldFull = NodePath.join(savedPathAbsolute, request.oldname);
|
|
1039
1099
|
const newFull = NodePath.join(currentPathAbsolute, request.newname);
|
|
1040
1100
|
if (oldFull.length < this.dir.length || newFull.length < this.dir.length)
|
|
1041
|
-
throw 2
|
|
1101
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
1042
1102
|
if (!oldFull.startsWith(this.dir))
|
|
1043
|
-
return new msg.Nfsv4RenameResponse(2);
|
|
1103
|
+
return new msg.Nfsv4RenameResponse(2 /* Nfsv4Stat.NFS4ERR_NOENT */);
|
|
1044
1104
|
if (!newFull.startsWith(this.dir))
|
|
1045
|
-
return new msg.Nfsv4RenameResponse(2);
|
|
1105
|
+
return new msg.Nfsv4RenameResponse(2 /* Nfsv4Stat.NFS4ERR_NOENT */);
|
|
1046
1106
|
let oldPath;
|
|
1047
1107
|
let newPath;
|
|
1048
1108
|
try {
|
|
@@ -1050,7 +1110,7 @@ class Nfsv4OperationsNode {
|
|
|
1050
1110
|
newPath = this.absolutePath(newFull);
|
|
1051
1111
|
}
|
|
1052
1112
|
catch (e) {
|
|
1053
|
-
const status = typeof e === 'number' ? e : 2
|
|
1113
|
+
const status = typeof e === 'number' ? e : 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
1054
1114
|
return new msg.Nfsv4RenameResponse(status);
|
|
1055
1115
|
}
|
|
1056
1116
|
try {
|
|
@@ -1061,11 +1121,11 @@ class Nfsv4OperationsNode {
|
|
|
1061
1121
|
const sourceCinfo = new struct.Nfsv4ChangeInfo(true, before, after);
|
|
1062
1122
|
const targetCinfo = new struct.Nfsv4ChangeInfo(true, before, after);
|
|
1063
1123
|
const resok = new msg.Nfsv4RenameResOk(sourceCinfo, targetCinfo);
|
|
1064
|
-
return new msg.Nfsv4RenameResponse(0
|
|
1124
|
+
return new msg.Nfsv4RenameResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1065
1125
|
}
|
|
1066
1126
|
catch (err) {
|
|
1067
1127
|
if ((0, util_1.isErrCode)('EXDEV', err))
|
|
1068
|
-
return new msg.Nfsv4RenameResponse(18);
|
|
1128
|
+
return new msg.Nfsv4RenameResponse(18 /* Nfsv4Stat.NFS4ERR_XDEV */);
|
|
1069
1129
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
1070
1130
|
return new msg.Nfsv4RenameResponse(status);
|
|
1071
1131
|
}
|
|
@@ -1074,9 +1134,9 @@ class Nfsv4OperationsNode {
|
|
|
1074
1134
|
const stateidKey = this.makeStateidKey(request.stateid);
|
|
1075
1135
|
const openFile = this.openFiles.get(stateidKey);
|
|
1076
1136
|
if (!openFile)
|
|
1077
|
-
return new msg.Nfsv4WriteResponse(10025);
|
|
1137
|
+
return new msg.Nfsv4WriteResponse(10025 /* Nfsv4Stat.NFS4ERR_BAD_STATEID */);
|
|
1078
1138
|
const fdHandle = openFile.fd;
|
|
1079
|
-
let fd
|
|
1139
|
+
let fd;
|
|
1080
1140
|
let openedHere = false;
|
|
1081
1141
|
try {
|
|
1082
1142
|
if (fdHandle && typeof fdHandle.write === 'function') {
|
|
@@ -1088,8 +1148,10 @@ class Nfsv4OperationsNode {
|
|
|
1088
1148
|
}
|
|
1089
1149
|
const buffer = Buffer.from(request.data);
|
|
1090
1150
|
const { bytesWritten } = await fd.write(buffer, 0, buffer.length, Number(request.offset));
|
|
1091
|
-
|
|
1092
|
-
|
|
1151
|
+
// Handle stable flag
|
|
1152
|
+
const committed = request.stable === 0 /* Nfsv4StableHow.UNSTABLE4 */ ? 0 /* Nfsv4StableHow.UNSTABLE4 */ : 2 /* Nfsv4StableHow.FILE_SYNC4 */;
|
|
1153
|
+
if (request.stable === 2 /* Nfsv4StableHow.FILE_SYNC4 */ || request.stable === 1 /* Nfsv4StableHow.DATA_SYNC4 */) {
|
|
1154
|
+
// fd.datasync or fd.sync
|
|
1093
1155
|
if (typeof fd.datasync === 'function')
|
|
1094
1156
|
await fd.datasync();
|
|
1095
1157
|
else if (typeof fd.sync === 'function')
|
|
@@ -1097,7 +1159,7 @@ class Nfsv4OperationsNode {
|
|
|
1097
1159
|
}
|
|
1098
1160
|
const verifier = new struct.Nfsv4Verifier((0, node_crypto_1.randomBytes)(8));
|
|
1099
1161
|
const resok = new msg.Nfsv4WriteResOk(bytesWritten, committed, verifier);
|
|
1100
|
-
return new msg.Nfsv4WriteResponse(0
|
|
1162
|
+
return new msg.Nfsv4WriteResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1101
1163
|
}
|
|
1102
1164
|
catch (err) {
|
|
1103
1165
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1108,20 +1170,22 @@ class Nfsv4OperationsNode {
|
|
|
1108
1170
|
if (openedHere && fd && typeof fd.close === 'function')
|
|
1109
1171
|
await fd.close();
|
|
1110
1172
|
}
|
|
1111
|
-
catch (
|
|
1173
|
+
catch (_e) {
|
|
1174
|
+
/* ignore close errors */
|
|
1112
1175
|
}
|
|
1113
1176
|
}
|
|
1114
1177
|
}
|
|
1115
1178
|
async DELEGPURGE(request, ctx) {
|
|
1116
|
-
return new msg.Nfsv4DelegpurgeResponse(10004);
|
|
1179
|
+
return new msg.Nfsv4DelegpurgeResponse(10004 /* Nfsv4Stat.NFS4ERR_NOTSUPP */);
|
|
1117
1180
|
}
|
|
1118
1181
|
async DELEGRETURN(request, ctx) {
|
|
1119
|
-
return new msg.Nfsv4DelegreturnResponse(10004);
|
|
1182
|
+
return new msg.Nfsv4DelegreturnResponse(10004 /* Nfsv4Stat.NFS4ERR_NOTSUPP */);
|
|
1120
1183
|
}
|
|
1121
1184
|
async COMMIT(request, ctx) {
|
|
1122
1185
|
const currentPath = this.fh.currentPath(ctx);
|
|
1123
1186
|
const currentPathAbsolute = this.absolutePath(currentPath);
|
|
1124
|
-
|
|
1187
|
+
// If there is an open file corresponding to this path, prefer that fd
|
|
1188
|
+
let fd;
|
|
1125
1189
|
for (const openFile of this.openFiles.values()) {
|
|
1126
1190
|
if (openFile.path === currentPathAbsolute) {
|
|
1127
1191
|
fd = openFile.fd;
|
|
@@ -1136,6 +1200,7 @@ class Nfsv4OperationsNode {
|
|
|
1136
1200
|
await fd.sync();
|
|
1137
1201
|
}
|
|
1138
1202
|
else {
|
|
1203
|
+
// fallback: open and fdatasync
|
|
1139
1204
|
const handle = await this.promises.open(currentPathAbsolute, this.fs.constants.O_RDONLY);
|
|
1140
1205
|
try {
|
|
1141
1206
|
if (typeof handle.datasync === 'function')
|
|
@@ -1147,11 +1212,13 @@ class Nfsv4OperationsNode {
|
|
|
1147
1212
|
try {
|
|
1148
1213
|
await handle.close();
|
|
1149
1214
|
}
|
|
1150
|
-
catch (
|
|
1215
|
+
catch (_e) {
|
|
1216
|
+
/* ignore */
|
|
1151
1217
|
}
|
|
1152
1218
|
}
|
|
1153
1219
|
}
|
|
1154
|
-
|
|
1220
|
+
// Return OK; no specific commit verifier currently persisted
|
|
1221
|
+
return new msg.Nfsv4CommitResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
1155
1222
|
}
|
|
1156
1223
|
catch (err) {
|
|
1157
1224
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1164,27 +1231,28 @@ class Nfsv4OperationsNode {
|
|
|
1164
1231
|
const name = request.objname;
|
|
1165
1232
|
const createPath = NodePath.join(currentPathAbsolute, name);
|
|
1166
1233
|
if (createPath.length < this.dir.length)
|
|
1167
|
-
throw 2
|
|
1234
|
+
throw 2 /* Nfsv4Stat.NFS4ERR_NOENT */;
|
|
1168
1235
|
try {
|
|
1169
1236
|
const objType = request.objtype.type;
|
|
1170
|
-
if (objType === 2) {
|
|
1237
|
+
if (objType === 2 /* Nfsv4FType.NF4DIR */) {
|
|
1171
1238
|
let mode = 0o777;
|
|
1172
1239
|
try {
|
|
1173
1240
|
if (request.createattrs && request.createattrs.attrmask) {
|
|
1174
1241
|
const dec = new XdrDecoder_1.XdrDecoder();
|
|
1175
1242
|
dec.reader.reset(request.createattrs.attrVals);
|
|
1176
1243
|
const maskSet = (0, attributes_1.parseBitmask)(request.createattrs.attrmask.mask);
|
|
1177
|
-
if (maskSet.has(33)) {
|
|
1244
|
+
if (maskSet.has(33 /* Nfsv4Attr.FATTR4_MODE */)) {
|
|
1178
1245
|
const m = dec.readUnsignedInt();
|
|
1179
1246
|
mode = m & 0o7777;
|
|
1180
1247
|
}
|
|
1181
1248
|
}
|
|
1182
1249
|
}
|
|
1183
|
-
catch (
|
|
1250
|
+
catch (_e) {
|
|
1251
|
+
// ignore parsing errors, fall back to default mode
|
|
1184
1252
|
}
|
|
1185
1253
|
await this.promises.mkdir(createPath, mode);
|
|
1186
1254
|
}
|
|
1187
|
-
else if (objType === 5) {
|
|
1255
|
+
else if (objType === 5 /* Nfsv4FType.NF4LNK */) {
|
|
1188
1256
|
const linkTarget = request.objtype.objtype.linkdata;
|
|
1189
1257
|
await this.promises.symlink(linkTarget, createPath);
|
|
1190
1258
|
}
|
|
@@ -1195,13 +1263,14 @@ class Nfsv4OperationsNode {
|
|
|
1195
1263
|
const dec = new XdrDecoder_1.XdrDecoder();
|
|
1196
1264
|
dec.reader.reset(request.createattrs.attrVals);
|
|
1197
1265
|
const maskSet = (0, attributes_1.parseBitmask)(request.createattrs.attrmask.mask);
|
|
1198
|
-
if (maskSet.has(33)) {
|
|
1266
|
+
if (maskSet.has(33 /* Nfsv4Attr.FATTR4_MODE */)) {
|
|
1199
1267
|
const m = dec.readUnsignedInt();
|
|
1200
1268
|
mode = m & 0o7777;
|
|
1201
1269
|
}
|
|
1202
1270
|
}
|
|
1203
1271
|
}
|
|
1204
|
-
catch (
|
|
1272
|
+
catch (_e) {
|
|
1273
|
+
// ignore parsing errors, fall back to default mode
|
|
1205
1274
|
}
|
|
1206
1275
|
const fd = await this.promises.open(createPath, this.fs.constants.O_CREAT | this.fs.constants.O_EXCL | this.fs.constants.O_RDWR, mode);
|
|
1207
1276
|
try {
|
|
@@ -1209,7 +1278,7 @@ class Nfsv4OperationsNode {
|
|
|
1209
1278
|
}
|
|
1210
1279
|
catch { }
|
|
1211
1280
|
}
|
|
1212
|
-
const
|
|
1281
|
+
const _stats = await this.promises.stat(createPath);
|
|
1213
1282
|
const fh = this.fh.encode(createPath);
|
|
1214
1283
|
ctx.cfh = fh;
|
|
1215
1284
|
const before = this.changeCounter;
|
|
@@ -1217,7 +1286,7 @@ class Nfsv4OperationsNode {
|
|
|
1217
1286
|
const cinfo = new struct.Nfsv4ChangeInfo(true, before, after);
|
|
1218
1287
|
const attrset = new struct.Nfsv4Bitmap([]);
|
|
1219
1288
|
const resok = new msg.Nfsv4CreateResOk(cinfo, attrset);
|
|
1220
|
-
return new msg.Nfsv4CreateResponse(0
|
|
1289
|
+
return new msg.Nfsv4CreateResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1221
1290
|
}
|
|
1222
1291
|
catch (err) {
|
|
1223
1292
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1234,7 +1303,7 @@ class Nfsv4OperationsNode {
|
|
|
1234
1303
|
const before = this.changeCounter;
|
|
1235
1304
|
const after = ++this.changeCounter;
|
|
1236
1305
|
const resok = new msg.Nfsv4LinkResOk(new struct.Nfsv4ChangeInfo(true, before, after));
|
|
1237
|
-
return new msg.Nfsv4LinkResponse(0
|
|
1306
|
+
return new msg.Nfsv4LinkResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1238
1307
|
}
|
|
1239
1308
|
catch (err) {
|
|
1240
1309
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1247,10 +1316,13 @@ class Nfsv4OperationsNode {
|
|
|
1247
1316
|
try {
|
|
1248
1317
|
const stats = await this.promises.lstat(currentPathAbsolute);
|
|
1249
1318
|
const fsStats = await this.fsStats();
|
|
1319
|
+
// request.objAttributes is a Nfsv4Fattr: use its attrmask when asking
|
|
1320
|
+
// encodeAttrs to serialize the server's current attributes and compare
|
|
1321
|
+
// raw attrVals bytes.
|
|
1250
1322
|
const attrs = (0, attrs_1.encodeAttrs)(request.objAttributes.attrmask, stats, currentPathAbsolute, ctx.cfh, this.leaseTime, fsStats);
|
|
1251
1323
|
if ((0, cmpUint8Array_1.cmpUint8Array)(attrs.attrVals, request.objAttributes.attrVals))
|
|
1252
|
-
return new msg.Nfsv4NverifyResponse(10027);
|
|
1253
|
-
return new msg.Nfsv4NverifyResponse(0);
|
|
1324
|
+
return new msg.Nfsv4NverifyResponse(10027 /* Nfsv4Stat.NFS4ERR_NOT_SAME */);
|
|
1325
|
+
return new msg.Nfsv4NverifyResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
1254
1326
|
}
|
|
1255
1327
|
catch (err) {
|
|
1256
1328
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1277,33 +1349,33 @@ class Nfsv4OperationsNode {
|
|
|
1277
1349
|
continue;
|
|
1278
1350
|
const attrNum = i * 32 + bit;
|
|
1279
1351
|
switch (attrNum) {
|
|
1280
|
-
case 33
|
|
1352
|
+
case 33 /* Nfsv4Attr.FATTR4_MODE */: {
|
|
1281
1353
|
const mode = dec.readUnsignedInt();
|
|
1282
1354
|
await this.promises.chmod(currentPathAbsolute, mode & 0o7777);
|
|
1283
1355
|
break;
|
|
1284
1356
|
}
|
|
1285
|
-
case 36
|
|
1357
|
+
case 36 /* Nfsv4Attr.FATTR4_OWNER */: {
|
|
1286
1358
|
const owner = dec.readString();
|
|
1287
1359
|
const parsedUid = parseInt(owner, 10);
|
|
1288
|
-
if (!isNaN(parsedUid)) {
|
|
1360
|
+
if (!Number.isNaN(parsedUid)) {
|
|
1289
1361
|
uid = parsedUid;
|
|
1290
1362
|
}
|
|
1291
1363
|
break;
|
|
1292
1364
|
}
|
|
1293
|
-
case 37
|
|
1365
|
+
case 37 /* Nfsv4Attr.FATTR4_OWNER_GROUP */: {
|
|
1294
1366
|
const group = dec.readString();
|
|
1295
1367
|
const parsedGid = parseInt(group, 10);
|
|
1296
|
-
if (!isNaN(parsedGid)) {
|
|
1368
|
+
if (!Number.isNaN(parsedGid)) {
|
|
1297
1369
|
gid = parsedGid;
|
|
1298
1370
|
}
|
|
1299
1371
|
break;
|
|
1300
1372
|
}
|
|
1301
|
-
case 4
|
|
1373
|
+
case 4 /* Nfsv4Attr.FATTR4_SIZE */: {
|
|
1302
1374
|
const size = dec.readUnsignedHyper();
|
|
1303
1375
|
await this.promises.truncate(currentPathAbsolute, Number(size));
|
|
1304
1376
|
break;
|
|
1305
1377
|
}
|
|
1306
|
-
case 48
|
|
1378
|
+
case 48 /* Nfsv4Attr.FATTR4_TIME_ACCESS_SET */: {
|
|
1307
1379
|
const setIt = dec.readUnsignedInt();
|
|
1308
1380
|
if (setIt === 1) {
|
|
1309
1381
|
const seconds = Number(dec.readHyper());
|
|
@@ -1312,7 +1384,7 @@ class Nfsv4OperationsNode {
|
|
|
1312
1384
|
}
|
|
1313
1385
|
break;
|
|
1314
1386
|
}
|
|
1315
|
-
case 54
|
|
1387
|
+
case 54 /* Nfsv4Attr.FATTR4_TIME_MODIFY_SET */: {
|
|
1316
1388
|
const setIt = dec.readUnsignedInt();
|
|
1317
1389
|
if (setIt === 1) {
|
|
1318
1390
|
const seconds = Number(dec.readHyper());
|
|
@@ -1321,35 +1393,36 @@ class Nfsv4OperationsNode {
|
|
|
1321
1393
|
}
|
|
1322
1394
|
break;
|
|
1323
1395
|
}
|
|
1324
|
-
case 19
|
|
1396
|
+
case 19 /* Nfsv4Attr.FATTR4_FILEHANDLE */: {
|
|
1397
|
+
// read and ignore
|
|
1325
1398
|
dec.readVarlenArray(() => dec.readUnsignedInt());
|
|
1326
1399
|
break;
|
|
1327
1400
|
}
|
|
1328
|
-
case 0
|
|
1401
|
+
case 0 /* Nfsv4Attr.FATTR4_SUPPORTED_ATTRS */: {
|
|
1329
1402
|
const len = dec.readUnsignedInt();
|
|
1330
1403
|
for (let j = 0; j < len; j++)
|
|
1331
1404
|
dec.readUnsignedInt();
|
|
1332
1405
|
break;
|
|
1333
1406
|
}
|
|
1334
|
-
case 1
|
|
1407
|
+
case 1 /* Nfsv4Attr.FATTR4_TYPE */: {
|
|
1335
1408
|
dec.readUnsignedInt();
|
|
1336
1409
|
break;
|
|
1337
1410
|
}
|
|
1338
|
-
case 20
|
|
1339
|
-
case 45
|
|
1340
|
-
case 3
|
|
1411
|
+
case 20 /* Nfsv4Attr.FATTR4_FILEID */:
|
|
1412
|
+
case 45 /* Nfsv4Attr.FATTR4_SPACE_USED */:
|
|
1413
|
+
case 3 /* Nfsv4Attr.FATTR4_CHANGE */: {
|
|
1341
1414
|
dec.readUnsignedHyper();
|
|
1342
1415
|
break;
|
|
1343
1416
|
}
|
|
1344
|
-
case 47
|
|
1345
|
-
case 53
|
|
1346
|
-
case 52
|
|
1417
|
+
case 47 /* Nfsv4Attr.FATTR4_TIME_ACCESS */:
|
|
1418
|
+
case 53 /* Nfsv4Attr.FATTR4_TIME_MODIFY */:
|
|
1419
|
+
case 52 /* Nfsv4Attr.FATTR4_TIME_METADATA */: {
|
|
1347
1420
|
dec.readHyper();
|
|
1348
1421
|
dec.readUnsignedInt();
|
|
1349
1422
|
break;
|
|
1350
1423
|
}
|
|
1351
1424
|
default: {
|
|
1352
|
-
return new msg.Nfsv4SetattrResponse(10032);
|
|
1425
|
+
return new msg.Nfsv4SetattrResponse(10032 /* Nfsv4Stat.NFS4ERR_ATTRNOTSUPP */);
|
|
1353
1426
|
}
|
|
1354
1427
|
}
|
|
1355
1428
|
}
|
|
@@ -1369,10 +1442,11 @@ class Nfsv4OperationsNode {
|
|
|
1369
1442
|
const stats = await this.promises.lstat(currentPathAbsolute);
|
|
1370
1443
|
const fh = this.fh.encode(currentPath);
|
|
1371
1444
|
const fsStats = await this.fsStats();
|
|
1372
|
-
|
|
1373
|
-
const
|
|
1445
|
+
// Return updated mode and size attributes
|
|
1446
|
+
const returnMask = new struct.Nfsv4Bitmap((0, attributes_1.attrNumsToBitmap)([33 /* Nfsv4Attr.FATTR4_MODE */, 4 /* Nfsv4Attr.FATTR4_SIZE */]));
|
|
1447
|
+
const _fattr = (0, attrs_1.encodeAttrs)(returnMask, stats, currentPath, fh, this.leaseTime, fsStats);
|
|
1374
1448
|
const resok = new msg.Nfsv4SetattrResOk(returnMask);
|
|
1375
|
-
return new msg.Nfsv4SetattrResponse(0
|
|
1449
|
+
return new msg.Nfsv4SetattrResponse(0 /* Nfsv4Stat.NFS4_OK */, resok);
|
|
1376
1450
|
}
|
|
1377
1451
|
catch (err) {
|
|
1378
1452
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|
|
@@ -1387,8 +1461,8 @@ class Nfsv4OperationsNode {
|
|
|
1387
1461
|
const fsStats = await this.fsStats();
|
|
1388
1462
|
const attrs = (0, attrs_1.encodeAttrs)(request.objAttributes.attrmask, stats, currentPath, ctx.cfh, this.leaseTime, fsStats);
|
|
1389
1463
|
if ((0, cmpUint8Array_1.cmpUint8Array)(attrs.attrVals, request.objAttributes.attrVals))
|
|
1390
|
-
return new msg.Nfsv4VerifyResponse(0);
|
|
1391
|
-
return new msg.Nfsv4VerifyResponse(10027);
|
|
1464
|
+
return new msg.Nfsv4VerifyResponse(0 /* Nfsv4Stat.NFS4_OK */);
|
|
1465
|
+
return new msg.Nfsv4VerifyResponse(10027 /* Nfsv4Stat.NFS4ERR_NOT_SAME */);
|
|
1392
1466
|
}
|
|
1393
1467
|
catch (err) {
|
|
1394
1468
|
const status = (0, util_1.normalizeNodeFsError)(err, ctx.connection.logger);
|