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