Added FUSE support #55

Merged
Elara6331 merged 65 commits from yannickulrich/itd:fuse into master 2023-03-25 22:23:52 +00:00
Showing only changes of commit b28c386c4e - Show all commits

View File

@ -126,8 +126,7 @@ func (n *ITNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
files, err := myfs.ReadDir(n.path) files, err := myfs.ReadDir(n.path)
if err != nil { if err != nil {
log.Error("FUSE ReadDir failed").Str("path", n.path).Err(err).Send() log.Error("FUSE ReadDir failed").Str("path", n.path).Err(err).Send()
// TODO we probably should figure out why it failed return nil, syscallErr(err)
Elara6331 marked this conversation as resolved Outdated

How would you recommend doing this? I suppose it could fail for all sorts of reasons such as

  • no such file or directory ENOENT
  • generic input/output error EIO
  • invalid argument EINVAL
  • connection aborted ECONNABORTED
  • connection refused ECONNREFUSED
  • connection reset ECONNRESET
  • is actually a file EISNAM

In other places such as when we open a file, we could have

  • is actually a folder EISDIR
  • file exists EEXIST

Again, I'm sorry but I'm not a Go expert and don't really now how to do this properly.. especially when dealing with FSError

How would you recommend doing this? I suppose it could fail for all sorts of reasons such as * no such file or directory `ENOENT` * generic input/output error `EIO` * invalid argument `EINVAL` * connection aborted `ECONNABORTED` * connection refused `ECONNREFUSED` * connection reset `ECONNRESET` * is actually a file `EISNAM` In other places such as when we open a file, we could have * is actually a folder `EISDIR` * file exists `EEXIST` Again, I'm sorry but I'm not a Go expert and don't really now how to do this properly.. especially when dealing with `FSError`

The err can be several different kinds of errors, and FSError is just one of them. It's actually a type I made. You can see it here: https://gitea.arsenm.dev/Arsen6331/infinitime/src/commit/512d48bc2469/blefs/error.go#L20. It contains an error code you can check to see what went wrong, and you can scroll down to see the meaning of each code.

In this case, I'd use a Go type switch to check which error type actually occurred and then check the code or do whatever else needs to be done. Maybe there could be a function like syscallErr() that takes an error and returns the proper syscall error?

If you don't feel comfortable doing that, I can merge this and then implement it myself and send you the commit so you can see how I did it, or you can just try it yourself, whatever you feel would be better.

The `err` can be several different kinds of errors, and `FSError` is just one of them. It's actually a type I made. You can see it here: https://gitea.arsenm.dev/Arsen6331/infinitime/src/commit/512d48bc2469/blefs/error.go#L20. It contains an error code you can check to see what went wrong, and you can scroll down to see the meaning of each code. In this case, I'd use a Go type switch to check which error type actually occurred and then check the code or do whatever else needs to be done. Maybe there could be a function like `syscallErr()` that takes an `error` and returns the proper syscall error? If you don't feel comfortable doing that, I can merge this and then implement it myself and send you the commit so you can see how I did it, or you can just try it yourself, whatever you feel would be better.

Something like in 4c59561a99? There are a few TODO where I'm not sure what the correct POSIX error would be and improvised. If you have a better idea, feel free to change them though

Something like in 4c59561a99? There are a few `TODO` where I'm not sure what the correct POSIX error would be and improvised. If you have a better idea, feel free to change them though

That looks good, thanks

That looks good, thanks
return nil, syscall.ENOENT
} }
log.Debug("FUSE ReadDir succeeded").Str("path", n.path).Int("objects", len(files)).Send() log.Debug("FUSE ReadDir succeeded").Str("path", n.path).Int("objects", len(files)).Send()
@ -137,7 +136,7 @@ func (n *ITNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
info, err := entry.Info() info, err := entry.Info()
if err != nil { if err != nil {
log.Error("FUSE Info failed").Str("path", n.path).Err(err).Send() log.Error("FUSE Info failed").Str("path", n.path).Err(err).Send()
return nil, syscall.ENOENT return nil, syscallErr(err)
} }
name := info.Name() name := info.Name()
@ -307,7 +306,7 @@ func (fh *bytesFileWriteHandle) Flush(ctx context.Context) (errno syscall.Errno)
fp, err := myfs.Create(fh.path, uint32(len(fh.content))) fp, err := myfs.Create(fh.path, uint32(len(fh.content)))
if err != nil { if err != nil {
log.Error("FUSE Flush failed: create").Str("path", fh.path).Err(err).Send() log.Error("FUSE Flush failed: create").Str("path", fh.path).Err(err).Send()
return syscall.EROFS return syscallErr(err)
} }
go func() { go func() {
@ -322,7 +321,7 @@ func (fh *bytesFileWriteHandle) Flush(ctx context.Context) (errno syscall.Errno)
if err != nil { if err != nil {
log.Error("FUSE Flush failed during write").Str("path", fh.path).Err(err).Send() log.Error("FUSE Flush failed during write").Str("path", fh.path).Err(err).Send()
fp.Close() fp.Close()
return syscall.EIO return syscallErr(err)
} }
if int(nread) != len(fh.content) { if int(nread) != len(fh.content) {
log.Error("FUSE Flush failed during write").Str("path", fh.path).Int("expect", len(fh.content)).Int("got", int(nread)).Send() log.Error("FUSE Flush failed during write").Str("path", fh.path).Int("expect", len(fh.content)).Int("got", int(nread)).Send()
@ -332,7 +331,7 @@ func (fh *bytesFileWriteHandle) Flush(ctx context.Context) (errno syscall.Errno)
err = fp.Close() err = fp.Close()
if err != nil { if err != nil {
log.Error("FUSE Flush failed during close").Str("path", fh.path).Err(err).Send() log.Error("FUSE Flush failed during close").Str("path", fh.path).Err(err).Send()
yannickulrich marked this conversation as resolved
Review

These should be debug logs rather than info logs. Also, the message should be a bit more specific, something like "FUSE getattr". Same for all the similar logs.

These should be debug logs rather than info logs. Also, the message should be a bit more specific, something like "FUSE getattr". Same for all the similar logs.
Review

Done in b5328ec

Done in b5328ec
return syscall.EIO return syscallErr(err)
} }
log.Debug("FUSE Flush done").Str("path", fh.path).Int("size", len(fh.content)).Send() log.Debug("FUSE Flush done").Str("path", fh.path).Int("size", len(fh.content)).Send()
@ -383,9 +382,8 @@ func (f *ITNode) Open(ctx context.Context, openFlags uint32) (fh fs.FileHandle,
log.Debug("FUSE Opening for read").Str("path", f.path).Send() log.Debug("FUSE Opening for read").Str("path", f.path).Send()
fp, err := myfs.Open(f.path) fp, err := myfs.Open(f.path)
if err != nil { if err != nil {
// TODO we probably should figure out why it failed
log.Error("FUSE: Opening failed").Str("path", f.path).Err(err).Send() log.Error("FUSE: Opening failed").Str("path", f.path).Err(err).Send()
return nil, 0, syscall.EROFS return nil, 0, syscallErr(err)
} }
defer fp.Close() defer fp.Close()
@ -403,7 +401,7 @@ func (f *ITNode) Open(ctx context.Context, openFlags uint32) (fh fs.FileHandle,
if err != nil { if err != nil {
log.Error("FUSE Read failed").Str("path", f.path).Err(err).Send() log.Error("FUSE Read failed").Str("path", f.path).Err(err).Send()
fp.Close() fp.Close()
return nil, 0, syscall.EIO return nil, 0, syscallErr(err)
} }
fh = &bytesFileReadHandle{ fh = &bytesFileReadHandle{
@ -425,8 +423,7 @@ func (f *ITNode) Open(ctx context.Context, openFlags uint32) (fh fs.FileHandle,
sub_ctx, cancel := context.WithCancel(ctx) sub_ctx, cancel := context.WithCancel(ctx)
ans, err := value.gen(sub_ctx) ans, err := value.gen(sub_ctx)
if err != nil { if err != nil {
// TODO we probably should figure out why it failed return nil, 0, syscallErr(err)
return nil, 0, syscall.EIO
} }
fh = &sensorFileReadHandle{ fh = &sensorFileReadHandle{
@ -484,8 +481,7 @@ func (f *ITNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.
Str("path", path). Str("path", path).
Err(err). Err(err).
Send() Send()
// TODO we probably should figure out why it failed return nil, syscallErr(err)
return nil, syscall.EROFS
} }
yannickulrich marked this conversation as resolved Outdated

Minor typo, it's "success"

Minor typo, it's "success"

Done in b5328ec

Done in b5328ec
ino := uint64(len(inodemap)) + 11 ino := uint64(len(inodemap)) + 11
@ -525,8 +521,7 @@ func (f *ITNode) Rename(ctx context.Context, name string, newParent fs.InodeEmbe
Err(err). Err(err).
Send() Send()
// TODO we probably should figure out why it failed return syscallErr(err)
return syscall.EIO
} }
log.Debug("FUSE Rename sucess"). log.Debug("FUSE Rename sucess").
Str("src", p1). Str("src", p1).
@ -554,8 +549,7 @@ func (f *ITNode) Unlink(ctx context.Context, name string) syscall.Errno {
Err(err). Err(err).
Send() Send()
// TODO we probably should figure out why it failed return syscallErr(err)
return syscall.EIO
} }
log.Debug("FUSE Unlink success"). log.Debug("FUSE Unlink success").