Skip to content

Commit 6745a42

Browse files
committed
Add Unix and Windows backend implementations for file system operations
- Introduced `backend_unix.go` for Unix-specific file info handling and filesystem statistics. - Added `backend_windows.go` for Windows compatibility with synthetic values for file info and filesystem statistics. - Updated `backend.go` to use mode constants for better portability across platforms and refactored attribute retrieval logic.
1 parent dc194b6 commit 6745a42

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

subsystems/vfs/export/backend.go

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ import (
1414
pb "github.com/cyber-shuttle/linkspan/subsystems/vfs/proto/gen/remotefs"
1515
)
1616

17+
// Mode bits (Unix-style); avoid syscall.S_IF* for Windows portability.
18+
const (
19+
_modeDir = 0o40000
20+
_modeReg = 0o100000
21+
_modeLnk = 0o120000
22+
)
23+
1724
func errToErrno(e error) uint32 {
1825
if e == nil {
1926
return 0
@@ -165,11 +172,11 @@ func (b *Backend) HandleRequest(ctx context.Context, req *pb.FileRequest) *pb.Fi
165172
func statToAttr(info os.FileInfo, ino uint64) *pb.Attr {
166173
mode := uint32(info.Mode())
167174
if info.IsDir() {
168-
mode = syscall.S_IFDIR | (mode & 07777)
175+
mode = _modeDir | (mode & 07777)
169176
} else if info.Mode()&os.ModeSymlink != 0 {
170-
mode = syscall.S_IFLNK | (mode & 07777)
177+
mode = _modeLnk | (mode & 07777)
171178
} else {
172-
mode = syscall.S_IFREG | (mode & 07777)
179+
mode = _modeReg | (mode & 07777)
173180
}
174181
attr := &pb.Attr{
175182
Ino: ino,
@@ -182,10 +189,7 @@ func statToAttr(info os.FileInfo, ino uint64) *pb.Attr {
182189
attr.Atime = uint64(mt)
183190
attr.Mtime = uint64(mt)
184191
attr.Ctime = uint64(mt)
185-
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
186-
attr.Uid = uint32(stat.Uid)
187-
attr.Gid = uint32(stat.Gid)
188-
}
192+
attr.Uid, attr.Gid = uidGidFromFileInfo(info)
189193
return attr
190194
}
191195

@@ -195,7 +199,7 @@ func (b *Backend) handleGetAttr(r *pb.GetAttrRequest, resp *pb.FileResponse) {
195199
if r.Path == "" || r.Path == "/" || r.Path == "." {
196200
// Root: return synthetic dir attr
197201
resp.Result = &pb.FileResponse_GetAttr{GetAttr: &pb.GetAttrResult{
198-
Attr: &pb.Attr{Mode: uint32(syscall.S_IFDIR) | 0755, Ino: 1},
202+
Attr: &pb.Attr{Mode: _modeDir | 0755, Ino: 1},
199203
}}
200204
return
201205
}
@@ -205,7 +209,7 @@ func (b *Backend) handleGetAttr(r *pb.GetAttrRequest, resp *pb.FileResponse) {
205209
if local == "" {
206210
// Root: return synthetic dir attr (do not os.Stat(""))
207211
resp.Result = &pb.FileResponse_GetAttr{GetAttr: &pb.GetAttrResult{
208-
Attr: &pb.Attr{Mode: uint32(syscall.S_IFDIR) | 0755, Ino: 1},
212+
Attr: &pb.Attr{Mode: _modeDir | 0755, Ino: 1},
209213
}}
210214
return
211215
}
@@ -374,9 +378,9 @@ func (b *Backend) handleReaddir(r *pb.ReaddirRequest, resp *pb.FileResponse) {
374378
}
375379
var mode uint32
376380
if info.IsDir() {
377-
mode = syscall.S_IFDIR | 0755
381+
mode = _modeDir | 0755
378382
} else {
379-
mode = syscall.S_IFREG | (uint32(info.Mode()) & 07777)
383+
mode = _modeReg | (uint32(info.Mode()) & 07777)
380384
}
381385
ino := b.inoForPath(p.VirtualName)
382386
entries = append(entries, &pb.DirEntry{Name: p.VirtualName, Mode: mode, Ino: ino})
@@ -395,11 +399,11 @@ func (b *Backend) handleReaddir(r *pb.ReaddirRequest, resp *pb.FileResponse) {
395399
}
396400
mode := uint32(info.Mode())
397401
if info.IsDir() {
398-
mode = syscall.S_IFDIR | (mode & 07777)
402+
mode = _modeDir | (mode & 07777)
399403
} else if info.Mode()&os.ModeSymlink != 0 {
400-
mode = syscall.S_IFLNK | (mode & 07777)
404+
mode = _modeLnk | (mode & 07777)
401405
} else {
402-
mode = syscall.S_IFREG | (mode & 07777)
406+
mode = _modeReg | (mode & 07777)
403407
}
404408
childPath := ent.path + "/" + name
405409
if ent.path == "" {
@@ -582,18 +586,18 @@ func (b *Backend) handleStatfs(r *pb.StatfsRequest, resp *pb.FileResponse) {
582586
return
583587
}
584588
}
585-
var stat syscall.Statfs_t
586-
if err := syscall.Statfs(local, &stat); err != nil {
589+
blocks, bfree, bavail, files, ffree, bsize, err := getStatfs(local)
590+
if err != nil {
587591
resp.Errno = errToErrno(err)
588592
return
589593
}
590594
resp.Result = &pb.FileResponse_Statfs{Statfs: &pb.StatfsResult{
591-
Blocks: stat.Blocks,
592-
Bfree: stat.Bfree,
593-
Bavail: stat.Bavail,
594-
Files: stat.Files,
595-
Ffree: stat.Ffree,
596-
Bsize: uint64(stat.Bsize),
595+
Blocks: blocks,
596+
Bfree: bfree,
597+
Bavail: bavail,
598+
Files: files,
599+
Ffree: ffree,
600+
Bsize: uint64(bsize),
597601
Namelen: 255,
598602
}}
599603
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build unix
2+
3+
package export
4+
5+
import (
6+
"os"
7+
"syscall"
8+
)
9+
10+
func uidGidFromFileInfo(info os.FileInfo) (uid, gid uint32) {
11+
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
12+
return uint32(stat.Uid), uint32(stat.Gid)
13+
}
14+
return 0, 0
15+
}
16+
17+
func getStatfs(path string) (blocks, bfree, bavail, files, ffree uint64, bsize uint32, err error) {
18+
var stat syscall.Statfs_t
19+
if err := syscall.Statfs(path, &stat); err != nil {
20+
return 0, 0, 0, 0, 0, 0, err
21+
}
22+
return stat.Blocks, stat.Bfree, stat.Bavail, stat.Files, stat.Ffree, uint32(stat.Bsize), nil
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build windows
2+
3+
package export
4+
5+
import "os"
6+
7+
func uidGidFromFileInfo(info os.FileInfo) (uid, gid uint32) {
8+
return 0, 0
9+
}
10+
11+
func getStatfs(path string) (blocks, bfree, bavail, files, ffree uint64, bsize uint32, err error) {
12+
// Windows has no direct Statfs equivalent; return synthetic values.
13+
return 0, 0, 0, 0, 0, 4096, nil
14+
}

0 commit comments

Comments
 (0)