github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/swarm/fuse/fuse_dir.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // +build linux darwin freebsd 18 19 package fuse 20 21 import ( 22 "os" 23 "path/filepath" 24 "sync" 25 26 "bazil.org/fuse" 27 "bazil.org/fuse/fs" 28 "github.com/FusionFoundation/efsn/swarm/log" 29 "golang.org/x/net/context" 30 ) 31 32 var ( 33 _ fs.Node = (*SwarmDir)(nil) 34 _ fs.NodeRequestLookuper = (*SwarmDir)(nil) 35 _ fs.HandleReadDirAller = (*SwarmDir)(nil) 36 _ fs.NodeCreater = (*SwarmDir)(nil) 37 _ fs.NodeRemover = (*SwarmDir)(nil) 38 _ fs.NodeMkdirer = (*SwarmDir)(nil) 39 ) 40 41 type SwarmDir struct { 42 inode uint64 43 name string 44 path string 45 directories []*SwarmDir 46 files []*SwarmFile 47 48 mountInfo *MountInfo 49 lock *sync.RWMutex 50 } 51 52 func NewSwarmDir(fullpath string, minfo *MountInfo) *SwarmDir { 53 log.Debug("swarmfs", "NewSwarmDir", fullpath) 54 newdir := &SwarmDir{ 55 inode: NewInode(), 56 name: filepath.Base(fullpath), 57 path: fullpath, 58 directories: []*SwarmDir{}, 59 files: []*SwarmFile{}, 60 mountInfo: minfo, 61 lock: &sync.RWMutex{}, 62 } 63 return newdir 64 } 65 66 func (sd *SwarmDir) Attr(ctx context.Context, a *fuse.Attr) error { 67 sd.lock.RLock() 68 defer sd.lock.RUnlock() 69 a.Inode = sd.inode 70 a.Mode = os.ModeDir | 0700 71 a.Uid = uint32(os.Getuid()) 72 a.Gid = uint32(os.Getegid()) 73 return nil 74 } 75 76 func (sd *SwarmDir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) { 77 log.Debug("swarmfs", "Lookup", req.Name) 78 for _, n := range sd.files { 79 if n.name == req.Name { 80 return n, nil 81 } 82 } 83 for _, n := range sd.directories { 84 if n.name == req.Name { 85 return n, nil 86 } 87 } 88 return nil, fuse.ENOENT 89 } 90 91 func (sd *SwarmDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { 92 log.Debug("swarmfs ReadDirAll") 93 var children []fuse.Dirent 94 for _, file := range sd.files { 95 children = append(children, fuse.Dirent{Inode: file.inode, Type: fuse.DT_File, Name: file.name}) 96 } 97 for _, dir := range sd.directories { 98 children = append(children, fuse.Dirent{Inode: dir.inode, Type: fuse.DT_Dir, Name: dir.name}) 99 } 100 return children, nil 101 } 102 103 func (sd *SwarmDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { 104 log.Debug("swarmfs Create", "path", sd.path, "req.Name", req.Name) 105 106 newFile := NewSwarmFile(sd.path, req.Name, sd.mountInfo) 107 newFile.fileSize = 0 // 0 means, file is not in swarm yet and it is just created 108 109 sd.lock.Lock() 110 defer sd.lock.Unlock() 111 sd.files = append(sd.files, newFile) 112 113 return newFile, newFile, nil 114 } 115 116 func (sd *SwarmDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { 117 log.Debug("swarmfs Remove", "path", sd.path, "req.Name", req.Name) 118 119 if req.Dir && sd.directories != nil { 120 newDirs := []*SwarmDir{} 121 for _, dir := range sd.directories { 122 if dir.name == req.Name { 123 removeDirectoryFromSwarm(dir) 124 } else { 125 newDirs = append(newDirs, dir) 126 } 127 } 128 if len(sd.directories) > len(newDirs) { 129 sd.lock.Lock() 130 defer sd.lock.Unlock() 131 sd.directories = newDirs 132 } 133 return nil 134 } else if !req.Dir && sd.files != nil { 135 newFiles := []*SwarmFile{} 136 for _, f := range sd.files { 137 if f.name == req.Name { 138 removeFileFromSwarm(f) 139 } else { 140 newFiles = append(newFiles, f) 141 } 142 } 143 if len(sd.files) > len(newFiles) { 144 sd.lock.Lock() 145 defer sd.lock.Unlock() 146 sd.files = newFiles 147 } 148 return nil 149 } 150 return fuse.ENOENT 151 } 152 153 func (sd *SwarmDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { 154 log.Debug("swarmfs Mkdir", "path", sd.path, "req.Name", req.Name) 155 newDir := NewSwarmDir(filepath.Join(sd.path, req.Name), sd.mountInfo) 156 sd.lock.Lock() 157 defer sd.lock.Unlock() 158 sd.directories = append(sd.directories, newDir) 159 160 return newDir, nil 161 }