@@ -21,6 +21,14 @@ import (
21
21
"github.com/ipfs/kubo/core"
22
22
)
23
23
24
+ const (
25
+ ipfsCIDXattr = "ipfs_cid"
26
+ mfsDirMode = os .ModeDir | 0755
27
+ mfsFileMode = 0644
28
+ blockSize = 512
29
+ dirSize = 8
30
+ )
31
+
24
32
// FUSE filesystem mounted at /mfs.
25
33
type FileSystem struct {
26
34
root Dir
@@ -38,18 +46,23 @@ type Dir struct {
38
46
39
47
// Directory attributes (stat).
40
48
func (dir * Dir ) Attr (ctx context.Context , attr * fuse.Attr ) error {
41
- attr .Mode = os . FileMode ( os . ModeDir | 0755 )
42
- attr .Size = 4096
43
- attr .Blocks = 8
49
+ attr .Mode = mfsDirMode
50
+ attr .Size = dirSize * blockSize
51
+ attr .Blocks = dirSize
44
52
return nil
45
53
}
46
54
47
55
// Access files in a directory.
48
56
func (dir * Dir ) Lookup (ctx context.Context , req * fuse.LookupRequest , resp * fuse.LookupResponse ) (fs.Node , error ) {
49
57
mfsNode , err := dir .mfsDir .Child (req .Name )
50
- if err != nil {
58
+ switch err {
59
+ case os .ErrNotExist :
51
60
return nil , syscall .Errno (syscall .ENOENT )
61
+ case nil :
62
+ default :
63
+ return nil , err
52
64
}
65
+
53
66
switch mfsNode .Type () {
54
67
case mfs .TDir :
55
68
result := Dir {
@@ -75,8 +88,12 @@ func (dir *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
75
88
}
76
89
77
90
for _ , node := range nodes {
91
+ nodeType := fuse .DT_File
92
+ if node .Type == 1 {
93
+ nodeType = fuse .DT_Dir
94
+ }
78
95
res = append (res , fuse.Dirent {
79
- Type : fuse . DT_File ,
96
+ Type : nodeType ,
80
97
Name : node .Name ,
81
98
})
82
99
}
@@ -131,12 +148,23 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fs.N
131
148
}
132
149
targetDir := newDir .(* Dir )
133
150
151
+ // Remove file if exists
152
+ err = targetDir .mfsDir .Unlink (req .NewName )
153
+ if err != nil && err != os .ErrNotExist {
154
+ return err
155
+ }
156
+
134
157
err = targetDir .mfsDir .AddChild (req .NewName , node )
135
158
if err != nil {
136
159
return err
137
160
}
138
161
139
- return dir .mfsDir .Unlink (req .OldName )
162
+ err = dir .mfsDir .Unlink (req .OldName )
163
+ if err != nil {
164
+ return err
165
+ }
166
+
167
+ return dir .mfsDir .Flush ()
140
168
}
141
169
142
170
// Create (touch) an MFS file.
@@ -187,10 +215,16 @@ func (dir *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.
187
215
return & file , & handler , nil
188
216
}
189
217
218
+ // List dir xattr.
219
+ func (dir * Dir ) Listxattr (ctx context.Context , req * fuse.ListxattrRequest , resp * fuse.ListxattrResponse ) error {
220
+ resp .Append (ipfsCIDXattr )
221
+ return nil
222
+ }
223
+
190
224
// Get dir xattr.
191
225
func (dir * Dir ) Getxattr (ctx context.Context , req * fuse.GetxattrRequest , resp * fuse.GetxattrResponse ) error {
192
226
switch req .Name {
193
- case "ipfs_cid" :
227
+ case ipfsCIDXattr :
194
228
node , err := dir .mfsDir .GetNode ()
195
229
if err != nil {
196
230
return err
@@ -209,28 +243,19 @@ type File struct {
209
243
210
244
// File attributes.
211
245
func (file * File ) Attr (ctx context.Context , attr * fuse.Attr ) error {
212
- size , err := file .mfsFile .Size ()
213
- if err != nil {
214
- return err
215
- }
246
+ size , _ := file .mfsFile .Size ()
247
+
216
248
attr .Size = uint64 (size )
217
- if size % 512 == 0 {
218
- attr .Blocks = uint64 (size / 512 )
249
+ if size % blockSize == 0 {
250
+ attr .Blocks = uint64 (size / blockSize )
219
251
} else {
220
- attr .Blocks = uint64 (size / 512 + 1 )
252
+ attr .Blocks = uint64 (size / blockSize + 1 )
221
253
}
222
254
223
- mtime , err := file .mfsFile .ModTime ()
224
- if err != nil {
225
- return err
226
- }
255
+ mtime , _ := file .mfsFile .ModTime ()
227
256
attr .Mtime = mtime
228
257
229
- mode , err := file .mfsFile .Mode ()
230
- if err != nil {
231
- return err
232
- }
233
- attr .Mode = mode
258
+ attr .Mode = mfsFileMode
234
259
return nil
235
260
}
236
261
@@ -263,10 +288,16 @@ func (file *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
263
288
return file .mfsFile .Sync ()
264
289
}
265
290
291
+ // List file xattr.
292
+ func (file * File ) Listxattr (ctx context.Context , req * fuse.ListxattrRequest , resp * fuse.ListxattrResponse ) error {
293
+ resp .Append (ipfsCIDXattr )
294
+ return nil
295
+ }
296
+
266
297
// Get file xattr.
267
298
func (file * File ) Getxattr (ctx context.Context , req * fuse.GetxattrRequest , resp * fuse.GetxattrResponse ) error {
268
299
switch req .Name {
269
- case "ipfs_cid" :
300
+ case ipfsCIDXattr :
270
301
node , err := file .mfsFile .GetNode ()
271
302
if err != nil {
272
303
return err
@@ -351,6 +382,7 @@ func NewFileSystem(ipfs *core.IpfsNode) fs.FS {
351
382
type mfsDir interface {
352
383
fs.Node
353
384
fs.NodeGetxattrer
385
+ fs.NodeListxattrer
354
386
fs.HandleReadDirAller
355
387
fs.NodeRequestLookuper
356
388
fs.NodeMkdirer
@@ -364,6 +396,7 @@ var _ mfsDir = (*Dir)(nil)
364
396
type mfsFile interface {
365
397
fs.Node
366
398
fs.NodeGetxattrer
399
+ fs.NodeListxattrer
367
400
fs.NodeOpener
368
401
fs.NodeFsyncer
369
402
}
0 commit comments