github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/fuse/fuse_dir.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:47</date> 10 //</624342671002963968> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 // 29 30 package fuse 31 32 import ( 33 "os" 34 "path/filepath" 35 "sync" 36 37 "bazil.org/fuse" 38 "bazil.org/fuse/fs" 39 "github.com/ethereum/go-ethereum/swarm/log" 40 "golang.org/x/net/context" 41 ) 42 43 var ( 44 _ fs.Node = (*SwarmDir)(nil) 45 _ fs.NodeRequestLookuper = (*SwarmDir)(nil) 46 _ fs.HandleReadDirAller = (*SwarmDir)(nil) 47 _ fs.NodeCreater = (*SwarmDir)(nil) 48 _ fs.NodeRemover = (*SwarmDir)(nil) 49 _ fs.NodeMkdirer = (*SwarmDir)(nil) 50 ) 51 52 type SwarmDir struct { 53 inode uint64 54 name string 55 path string 56 directories []*SwarmDir 57 files []*SwarmFile 58 59 mountInfo *MountInfo 60 lock *sync.RWMutex 61 } 62 63 func NewSwarmDir(fullpath string, minfo *MountInfo) *SwarmDir { 64 log.Debug("swarmfs", "NewSwarmDir", fullpath) 65 newdir := &SwarmDir{ 66 inode: NewInode(), 67 name: filepath.Base(fullpath), 68 path: fullpath, 69 directories: []*SwarmDir{}, 70 files: []*SwarmFile{}, 71 mountInfo: minfo, 72 lock: &sync.RWMutex{}, 73 } 74 return newdir 75 } 76 77 func (sd *SwarmDir) Attr(ctx context.Context, a *fuse.Attr) error { 78 sd.lock.RLock() 79 defer sd.lock.RUnlock() 80 a.Inode = sd.inode 81 a.Mode = os.ModeDir | 0700 82 a.Uid = uint32(os.Getuid()) 83 a.Gid = uint32(os.Getegid()) 84 return nil 85 } 86 87 func (sd *SwarmDir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) { 88 log.Debug("swarmfs", "Lookup", req.Name) 89 for _, n := range sd.files { 90 if n.name == req.Name { 91 return n, nil 92 } 93 } 94 for _, n := range sd.directories { 95 if n.name == req.Name { 96 return n, nil 97 } 98 } 99 return nil, fuse.ENOENT 100 } 101 102 func (sd *SwarmDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { 103 log.Debug("swarmfs ReadDirAll") 104 var children []fuse.Dirent 105 for _, file := range sd.files { 106 children = append(children, fuse.Dirent{Inode: file.inode, Type: fuse.DT_File, Name: file.name}) 107 } 108 for _, dir := range sd.directories { 109 children = append(children, fuse.Dirent{Inode: dir.inode, Type: fuse.DT_Dir, Name: dir.name}) 110 } 111 return children, nil 112 } 113 114 func (sd *SwarmDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { 115 log.Debug("swarmfs Create", "path", sd.path, "req.Name", req.Name) 116 117 newFile := NewSwarmFile(sd.path, req.Name, sd.mountInfo) 118 newFile.fileSize = 0 // 119 120 sd.lock.Lock() 121 defer sd.lock.Unlock() 122 sd.files = append(sd.files, newFile) 123 124 return newFile, newFile, nil 125 } 126 127 func (sd *SwarmDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { 128 log.Debug("swarmfs Remove", "path", sd.path, "req.Name", req.Name) 129 130 if req.Dir && sd.directories != nil { 131 newDirs := []*SwarmDir{} 132 for _, dir := range sd.directories { 133 if dir.name == req.Name { 134 removeDirectoryFromSwarm(dir) 135 } else { 136 newDirs = append(newDirs, dir) 137 } 138 } 139 if len(sd.directories) > len(newDirs) { 140 sd.lock.Lock() 141 defer sd.lock.Unlock() 142 sd.directories = newDirs 143 } 144 return nil 145 } else if !req.Dir && sd.files != nil { 146 newFiles := []*SwarmFile{} 147 for _, f := range sd.files { 148 if f.name == req.Name { 149 removeFileFromSwarm(f) 150 } else { 151 newFiles = append(newFiles, f) 152 } 153 } 154 if len(sd.files) > len(newFiles) { 155 sd.lock.Lock() 156 defer sd.lock.Unlock() 157 sd.files = newFiles 158 } 159 return nil 160 } 161 return fuse.ENOENT 162 } 163 164 func (sd *SwarmDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { 165 log.Debug("swarmfs Mkdir", "path", sd.path, "req.Name", req.Name) 166 newDir := NewSwarmDir(filepath.Join(sd.path, req.Name), sd.mountInfo) 167 sd.lock.Lock() 168 defer sd.lock.Unlock() 169 sd.directories = append(sd.directories, newDir) 170 171 return newDir, nil 172 } 173