9
9
10
10
"github.com/djdv/go-filesystem-utils/internal/filesystem"
11
11
p9fs "github.com/djdv/go-filesystem-utils/internal/filesystem/9p"
12
- "github.com/djdv/go-filesystem-utils/internal/filesystem/cgofuse"
13
- "github.com/djdv/go-filesystem-utils/internal/filesystem/ipfs"
14
12
"github.com/djdv/go-filesystem-utils/internal/generic"
15
13
"github.com/djdv/p9/p9"
16
14
)
@@ -34,61 +32,23 @@ type (
34
32
Host HT `json:"host"`
35
33
Guest GT `json:"guest"`
36
34
}
35
+ mountPointHosts map [filesystem.Host ]p9fs.MakeGuestFunc
36
+ mountPointGuests map [filesystem.ID ]p9fs.MakeMountPointFunc
37
37
)
38
38
39
- func newGuestFunc [HC mountPointHost [T ], T any ](path ninePath , autoUnlink bool ) p9fs.MakeGuestFunc {
40
- return func (parent p9.File , guest filesystem.ID , mode p9.FileMode , uid p9.UID , gid p9.GID ) (p9.QID , p9.File , error ) {
41
- permissions , err := mountsDirCreatePreamble (mode )
42
- if err != nil {
43
- return p9.QID {}, nil , err
44
- }
45
- var makeMountPointFn p9fs.MakeMountPointFunc
46
- // TODO: share IPFS instances
47
- // when server API is the same
48
- // (needs some wrapper too so
49
- // Close works properly.)
50
- switch guest {
51
- case ipfs .IPFSID :
52
- makeMountPointFn = newMountPointFunc [HC , * ipfs.IPFSGuest ](path )
53
- case ipfs .PinFSID :
54
- makeMountPointFn = newMountPointFunc [HC , * ipfs.PinFSGuest ](path )
55
- case ipfs .IPNSID :
56
- makeMountPointFn = newMountPointFunc [HC , * ipfs.IPNSGuest ](path )
57
- case ipfs .KeyFSID :
58
- makeMountPointFn = newMountPointFunc [HC , * ipfs.KeyFSGuest ](path )
59
- default :
60
- err := fmt .Errorf (`unexpected guest "%v"` , guest )
61
- return p9.QID {}, nil , err
62
- }
63
- return p9fs .NewGuestFile (
64
- makeMountPointFn ,
65
- p9fs.UnlinkEmptyChildren [p9fs.GuestOption ](autoUnlink ),
66
- p9fs.UnlinkWhenEmpty [p9fs.GuestOption ](autoUnlink ),
67
- p9fs .WithParent [p9fs.GuestOption ](parent , string (guest )),
68
- p9fs.WithPath [p9fs.GuestOption ](path ),
69
- p9fs.WithUID [p9fs.GuestOption ](uid ),
70
- p9fs.WithGID [p9fs.GuestOption ](gid ),
71
- p9fs.WithPermissions [p9fs.GuestOption ](permissions ),
72
- )
73
- }
74
- }
75
-
76
39
func newMounter (parent p9.File , path ninePath ,
77
40
uid p9.UID , gid p9.GID , permissions p9.FileMode ,
78
41
) (mountSubsystem , error ) {
79
42
const autoUnlink = true
80
- var (
81
- makeHostFn = newHostFunc (path , autoUnlink )
82
- _ , mountFS , err = p9fs .NewMounter (
83
- makeHostFn ,
84
- p9fs .WithParent [p9fs.MounterOption ](parent , mountsFileName ),
85
- p9fs.WithPath [p9fs.MounterOption ](path ),
86
- p9fs.WithUID [p9fs.MounterOption ](uid ),
87
- p9fs.WithGID [p9fs.MounterOption ](gid ),
88
- p9fs.WithPermissions [p9fs.MounterOption ](permissions ),
89
- p9fs.UnlinkEmptyChildren [p9fs.MounterOption ](autoUnlink ),
90
- p9fs.WithoutRename [p9fs.MounterOption ](true ),
91
- )
43
+ _ , mountFS , err := p9fs .NewMounter (
44
+ newMakeHostFunc (path , autoUnlink ),
45
+ p9fs .WithParent [p9fs.MounterOption ](parent , mountsFileName ),
46
+ p9fs.WithPath [p9fs.MounterOption ](path ),
47
+ p9fs.WithUID [p9fs.MounterOption ](uid ),
48
+ p9fs.WithGID [p9fs.MounterOption ](gid ),
49
+ p9fs.WithPermissions [p9fs.MounterOption ](permissions ),
50
+ p9fs.UnlinkEmptyChildren [p9fs.MounterOption ](autoUnlink ),
51
+ p9fs.WithoutRename [p9fs.MounterOption ](true ),
92
52
)
93
53
if err != nil {
94
54
return mountSubsystem {}, err
@@ -99,17 +59,15 @@ func newMounter(parent p9.File, path ninePath,
99
59
}, nil
100
60
}
101
61
102
- func newHostFunc (path ninePath , autoUnlink bool ) p9fs.MakeHostFunc {
62
+ func newMakeHostFunc (path ninePath , autoUnlink bool ) p9fs.MakeHostFunc {
63
+ hosts := makeMountPointHosts (path , autoUnlink )
103
64
return func (parent p9.File , host filesystem.Host , mode p9.FileMode , uid p9.UID , gid p9.GID ) (p9.QID , p9.File , error ) {
104
65
permissions , err := mountsDirCreatePreamble (mode )
105
66
if err != nil {
106
67
return p9.QID {}, nil , err
107
68
}
108
- var makeGuestFn p9fs.MakeGuestFunc
109
- switch host {
110
- case cgofuse .HostID :
111
- makeGuestFn = newGuestFunc [* cgofuse.Host ](path , autoUnlink )
112
- default :
69
+ makeGuestFn , ok := hosts [host ]
70
+ if ! ok {
113
71
err := fmt .Errorf (`unexpected host "%v"` , host )
114
72
return p9.QID {}, nil , err
115
73
}
@@ -127,6 +85,66 @@ func newHostFunc(path ninePath, autoUnlink bool) p9fs.MakeHostFunc {
127
85
}
128
86
}
129
87
88
+ func makeMountPointHosts (path ninePath , autoUnlink bool ) mountPointHosts {
89
+ type makeHostsFunc func (ninePath , bool ) (filesystem.Host , p9fs.MakeGuestFunc )
90
+ var (
91
+ hostMakers = []makeHostsFunc {
92
+ makeFUSEHost ,
93
+ }
94
+ hosts = make (mountPointHosts , len (hostMakers ))
95
+ )
96
+ for _ , hostMaker := range hostMakers {
97
+ host , guestMaker := hostMaker (path , autoUnlink )
98
+ if guestMaker == nil {
99
+ continue // System (likely) disabled by build constraints.
100
+ }
101
+ // No clobbering, accidental or otherwise.
102
+ if _ , exists := hosts [host ]; exists {
103
+ err := fmt .Errorf (
104
+ "%s file constructor already registered" ,
105
+ host ,
106
+ )
107
+ panic (err )
108
+ }
109
+ hosts [host ] = guestMaker
110
+ }
111
+ return hosts
112
+ }
113
+
114
+ func newMakeGuestFunc (guests mountPointGuests , path ninePath , autoUnlink bool ) p9fs.MakeGuestFunc {
115
+ return func (parent p9.File , guest filesystem.ID , mode p9.FileMode , uid p9.UID , gid p9.GID ) (p9.QID , p9.File , error ) {
116
+ permissions , err := mountsDirCreatePreamble (mode )
117
+ if err != nil {
118
+ return p9.QID {}, nil , err
119
+ }
120
+ makeMountPointFn , ok := guests [guest ]
121
+ if ! ok {
122
+ err := fmt .Errorf (`unexpected guest "%v"` , guest )
123
+ return p9.QID {}, nil , err
124
+ }
125
+ return p9fs .NewGuestFile (
126
+ makeMountPointFn ,
127
+ p9fs.UnlinkEmptyChildren [p9fs.GuestOption ](autoUnlink ),
128
+ p9fs.UnlinkWhenEmpty [p9fs.GuestOption ](autoUnlink ),
129
+ p9fs .WithParent [p9fs.GuestOption ](parent , string (guest )),
130
+ p9fs.WithPath [p9fs.GuestOption ](path ),
131
+ p9fs.WithUID [p9fs.GuestOption ](uid ),
132
+ p9fs.WithGID [p9fs.GuestOption ](gid ),
133
+ p9fs.WithPermissions [p9fs.GuestOption ](permissions ),
134
+ )
135
+ }
136
+ }
137
+
138
+ func makeMountPointGuests [
139
+ T any ,
140
+ HC mountPointHost [T ],
141
+ ](path ninePath ,
142
+ ) mountPointGuests {
143
+ guests := make (mountPointGuests )
144
+ makeIPFSGuests [HC ](guests , path )
145
+ return guests
146
+ }
147
+
130
148
func mountsDirCreatePreamble (mode p9.FileMode ) (p9.FileMode , error ) {
131
149
if ! mode .IsDir () {
132
150
return 0 , generic .ConstError ("expected to be called from mkdir" )
@@ -136,8 +154,9 @@ func mountsDirCreatePreamble(mode p9.FileMode) (p9.FileMode, error) {
136
154
137
155
func newMountPointFunc [
138
156
HC mountPointHost [HT ],
157
+ GT any ,
139
158
GC mountPointGuest [GT ],
140
- HT , GT any ,
159
+ HT any ,
141
160
](path ninePath ,
142
161
) p9fs.MakeMountPointFunc {
143
162
return func (parent p9.File , name string , mode p9.FileMode , uid p9.UID , gid p9.GID ) (p9.QID , p9.File , error ) {
0 commit comments