Added FUSE support #55
							
								
								
									
										10
									
								
								fuse.go
									
									
									
									
									
								
							
							
						
						@@ -12,7 +12,15 @@ import (
 | 
			
		||||
func startFUSE(ctx context.Context, dev *infinitime.Device) error {
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
					
					yannickulrich marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				 | 
			||||
	// This is where we'll mount the FS
 | 
			
		||||
	os.Mkdir(k.String("fuse.mountpoint"), 0755)
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
					
					yannickulrich marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
				
					
						Elara6331
						commented  
			
		Use  Use `os.MkdirAll` here instead so that it creates parent directories, and handle the error (just return it). 
			
			
		
				
					
						yannickulrich
						commented  
			
		This is actually a bit more complicated than that. If the mountpoint already exists, fuse will crash. We also can't delete the mountpoint beforehand ( This is actually a bit more complicated than that. If the mountpoint already exists, fuse will crash. We also can't delete the mountpoint beforehand (`rm: cannot remove '/tmp/itd/mnt': Transport endpoint is not connected`). The best way to solve this should be calling the [unmount function](https://pkg.go.dev/github.com/hanwen/go-fuse/v2@v2.2.0/fuse#Server.Unmount). How would you suggest going about doing this? 
			
			
		
				
					
						Elara6331
						commented  
			
		Yeah, this one is going to be a bit more complicated. The FUSE library does have a different unmount function that you could call before trying to mount the fs, but it's not exported, so we'll need to do a small hack to get access to it anyway. In the  
 | 
			||||
	root := fusefs.BuildRootNode(dev)
 | 
			
		||||
	root, err := fusefs.BuildRootNode(dev)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("Building root node failed").
 | 
			
		||||
			Err(err).
 | 
			
		||||
			Send()
 | 
			
		||||
			return err
 | 
			
		||||
		return err
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
					
					yannickulrich marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
				
					
						Elara6331
						commented  
			
		
 `err` is returned twice here 
			
			
		
				
					
						yannickulrich
						commented  
			
		Oh, sorry, fixed now Oh, sorry, fixed now 
			
			
		 | 
			||||
	}
 | 
			
		||||
 | 
			
		||||
	server, err := fs.Mount(k.String("fuse.mountpoint"), root, &fs.Options{
 | 
			
		||||
		MountOptions: fuse.MountOptions{
 | 
			
		||||
			// Set to true to see how the file system works.
 | 
			
		||||
 
 | 
			
		||||
@@ -39,11 +39,16 @@ type ITNode struct {
 | 
			
		||||
var myfs *blefs.FS = nil
 | 
			
		||||
var inodemap map[string]uint64 = nil
 | 
			
		||||
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
					
					yannickulrich marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
				
					
						Elara6331
						commented  
			
		This error needs to be handled, you can just return it in this case and update the code that calls this function to do the actual handling This error needs to be handled, you can just return it in this case and update the code that calls this function to do the actual handling 
			
			
		
				
					
						yannickulrich
						commented  
			
		Done in  Done in a54ca7a 
			
			
		 | 
			||||
func BuildRootNode(dev *infinitime.Device) *ITNode {
 | 
			
		||||
func BuildRootNode(dev *infinitime.Device) (*ITNode, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	inodemap = make(map[string]uint64)
 | 
			
		||||
	myfs, _ = dev.FS()
 | 
			
		||||
	myfs, err = dev.FS()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("FUSE failed to get filesystem").Err(err).Send()
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &ITNode{kind: 0}
 | 
			
		||||
	return &ITNode{kind: 0}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var properties = make([]ITProperty, 6)
 | 
			
		||||
@@ -118,12 +123,21 @@ func (n *ITNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
 | 
			
		||||
 | 
			
		||||
	case 2:
 | 
			
		||||
		// on device
 | 
			
		||||
		files, _ := myfs.ReadDir(n.path)
 | 
			
		||||
		files, err := myfs.ReadDir(n.path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Error("ReadDir failed").Str("path", n.path).Err(err).Send()
 | 
			
		||||
			return nil, syscall.ENOENT
 | 
			
		||||
| 
					
	
	
	
	
	
	
	
	 
					
					Elara6331 marked this conversation as resolved
					
						
						
							Outdated
						
					
				 
				
				
					
						yannickulrich
						commented  
			
		How would you recommend doing this? I suppose it could fail for all sorts of reasons such as 
 In other places such as when we open a file, we could have 
 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  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` 
			
			
		
				
					
						Elara6331
						commented  
			
		The  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  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. 
			
			
		
				
					
						yannickulrich
						commented  
			
		Something like in 4c59561a99? There are a few  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 
			
			
		
				
					
						Elara6331
						commented  
			
		That looks good, thanks That looks good, thanks 
			
			
		 | 
			||||
		}
 | 
			
		||||
 | 
			
		||||
		log.Info("readdir").Str("path", n.path).Int("objects", len(files)).Send()
 | 
			
		||||
		r := make([]fuse.DirEntry, len(files))
 | 
			
		||||
		n.lst = make([]DirEntry, len(files))
 | 
			
		||||
		for ind, entry := range files {
 | 
			
		||||
			info, _ := entry.Info()
 | 
			
		||||
			info, err := entry.Info()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error("Info failed").Str("path", n.path).Err(err).Send()
 | 
			
		||||
				return nil, syscall.ENOENT
 | 
			
		||||
			}
 | 
			
		||||
			name := info.Name()
 | 
			
		||||
 | 
			
		||||
			file := DirEntry{
 | 
			
		||||
 
 | 
			
		||||
This function should be called
startFUSEinstead to adhere to Go naming conventionsThanks, I'm relatively new to Go, sorry for these issues
Done in
673383f