Files
wls_vfs/proto/lws.proto
ekko.bao d2b98b4020 feat(proto/server)!: 升级至协议 v2(统一错误模型);全面替换 Request/Response 并移除 ret
- Breaking change: 协议不向后兼容,旧客户端需同步升级
- Proto: 新增 FsOp/ErrorCause/FsError/RpcStatus;为所有 FS 接口定义 <Op>Request/<Op>Response;删除历史 ret 字段
- Server: 所有 RPC 返回统一的 RpcStatus;成功 ok=true,失败填充 FsError(operation/paths/sys_msg 等)
  - Open/Read/Write 对齐新字段(fi/data/written);Readdir/Opendir/Releasedir 等返回类型调整
  - Rename 传回 from/to;OpendirRequest 不再输入 fi,服务端生成并回传
- Docs: 新增 docs/protocol_v2.md;README 标注 v2 破坏性升级与用法
- Build: 主要面向 Windows(winapi)。Linux 环境类型检查可能失败

后续:完善 errno 抽取与 context 填充;可选引入流式 read/write 以优化大文件传输。
2025-09-23 21:25:06 +08:00

206 lines
6.6 KiB
Protocol Buffer

// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package lws_vfs;
// Filesystem operation types for diagnostics and observability.
enum FsOp {
FSOP_UNKNOWN = 0;
FSOP_GETATTR = 1;
FSOP_SETXATTR = 2;
FSOP_ACCESS = 3;
FSOP_READDIR = 4;
FSOP_READ = 5;
FSOP_OPEN = 6;
FSOP_WRITE = 7;
FSOP_GETXATTR = 8;
FSOP_TRUNCATE = 9;
FSOP_UTIMENS = 10;
FSOP_CHOWN = 11;
FSOP_RELEASE = 12;
FSOP_MKDIR = 13;
FSOP_RMDIR = 14;
FSOP_FLUSH = 15;
FSOP_OPENDIR = 16;
FSOP_RELEASEDIR = 17;
FSOP_CREATE = 18;
FSOP_UNLINK = 19;
FSOP_RENAME = 20;
FSOP_HELLO = 21;
FSOP_GET_CONFIG = 22;
}
// Optional chained cause for nested errors.
message ErrorCause {
int32 code = 1; // POSIX errno if available
string message = 2; // human-readable message
string type = 3; // error type/category from server implementation
}
// Rich error payload carried by all responses.
message FsError {
int32 code = 1; // POSIX errno (>0)
string message = 2; // application error message
string sys_msg = 3; // strerror(code) or OS message
uint32 grpc_code = 4; // gRPC status code (if applicable)
string grpc_message = 5; // gRPC status message
FsOp operation = 6; // which fs op failed
repeated string paths = 7; // involved paths (e.g. [from, to])
map<string, string> context = 8; // flags/size/offset/uid/gid ...
repeated ErrorCause causes = 9; // nested causes
string server = 10; // server id/hostname
uint64 timestamp_ms = 11; // server time when error occurred
bool retriable = 12; // whether retry may succeed
}
message RpcStatus {
bool ok = 1; // true if the call succeeded
FsError error = 2; // populated when ok == false
}
// Common structs
message file_info {
uint32 flags = 1;
uint32 fh_old = 2;
bool direct_io = 3;
uint64 fh = 10;
uint64 lock_owner = 11;
}
message fstat {
uint64 fst_mode = 1;
uint64 fst_ino = 2;
uint64 fst_dev = 3;
uint64 fst_rdev = 4;
uint64 fst_nlink = 5;
uint64 fst_uid = 6;
uint64 fst_gid = 7;
uint64 fst_size = 8;
uint64 fst_atime = 9;
uint64 fst_mtime = 10;
uint64 fst_ctime = 11;
uint64 fst_blksize = 12;
uint64 fst_blocks = 13;
}
message timespec {
int32 tv_sec = 1;
int64 tv_nsec = 2;
}
message direntry {
string name = 1;
uint32 kind = 2;
}
// Service and RPCs
service LwsVfs {
rpc SayHello(HelloRequest) returns (HelloReply) {}
rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {}
rpc fgetattr(GetattrRequest) returns (GetattrResponse) {}
rpc fsetxattr(SetxattrRequest) returns (EmptyResponse) {}
rpc faccess(AccessRequest) returns (EmptyResponse) {}
rpc freaddir(ReaddirRequest) returns (ReaddirResponse) {}
rpc fread(ReadRequest) returns (ReadResponse) {}
rpc fopen(OpenRequest) returns (OpenResponse) {}
rpc fwrite(WriteRequest) returns (WriteResponse) {}
rpc fgetxattr(GetxattrRequest) returns (GetxattrResponse) {}
rpc ftruncate(TruncateRequest) returns (EmptyResponse) {}
rpc futimens(UtimensRequest) returns (EmptyResponse) {}
rpc fchown(ChownRequest) returns (EmptyResponse) {}
rpc frelease(ReleaseRequest) returns (EmptyResponse) {}
rpc fmkdir(MkdirRequest) returns (EmptyResponse) {}
rpc frmdir(RmdirRequest) returns (EmptyResponse) {}
rpc fflush(FlushRequest) returns (EmptyResponse) {}
rpc fopendir(OpendirRequest) returns (OpendirResponse) {}
rpc freleasedir(ReleasedirRequest) returns (EmptyResponse) {}
rpc fcreate(CreateRequest) returns (CreateResponse) {}
rpc funlink(UnlinkRequest) returns (EmptyResponse) {}
rpc frename(RenameRequest) returns (EmptyResponse) {}
}
// Hello
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; RpcStatus status = 2; }
// Config
message GetConfigRequest {}
message GetConfigResponse { string config = 1; RpcStatus status = 2; }
// getattr
message GetattrRequest { string path = 1; file_info fi = 2; }
message GetattrResponse { fstat stat = 1; RpcStatus status = 2; }
// xattr
message SetxattrRequest { string path = 1; string name = 2; bytes value = 3; int64 size = 4; uint32 flags = 5; }
message GetxattrRequest { string path = 1; string name = 2; int64 size = 3; }
message GetxattrResponse { bytes value = 1; RpcStatus status = 2; }
// access
message AccessRequest { string path = 1; uint32 mask = 2; }
// readdir
message ReaddirRequest { string path = 1; uint32 offset = 2; file_info fi = 3; }
message ReaddirResponse { repeated direntry dirs = 1; RpcStatus status = 2; }
// open
message OpenRequest { string path = 1; file_info fi = 2; }
message OpenResponse { file_info fi = 1; RpcStatus status = 2; }
// read
message ReadRequest { string path = 1; uint64 offset = 2; int64 size = 3; file_info fi = 4; }
message ReadResponse { bytes data = 1; RpcStatus status = 2; }
// write
message WriteRequest { string path = 1; uint64 offset = 2; bytes data = 3; file_info fi = 4; }
message WriteResponse { uint64 written = 1; RpcStatus status = 2; }
// truncate
message TruncateRequest { string path = 1; int64 size = 2; }
// utimens
message UtimensRequest { string path = 1; repeated timespec ts = 2; }
// chown
message ChownRequest { string path = 1; int32 uid = 2; int32 gid = 3; }
// release/flush
message ReleaseRequest { string path = 1; file_info fi = 2; uint32 flush = 3; }
message FlushRequest { string path = 1; file_info fi = 2; }
// mkdir/rmdir
message MkdirRequest { string path = 1; uint32 mode = 2; }
message RmdirRequest { string path = 1; }
// opendir/releasedir
message OpendirRequest { string path = 1; }
message OpendirResponse { file_info fi = 1; RpcStatus status = 2; }
message ReleasedirRequest { string path = 1; file_info fi = 2; }
// create
message CreateRequest { string path = 1; uint32 mode = 2; }
message CreateResponse { file_info fi = 1; RpcStatus status = 2; }
// unlink
message UnlinkRequest { string path = 1; }
// rename
message RenameRequest { string path = 1; string new = 2; }
// Empty response with status only
message EmptyResponse { RpcStatus status = 1; }