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