github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/fuse/fuse_dir.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  //
    26  
    27  package fuse
    28  
    29  import (
    30  	"os"
    31  	"path/filepath"
    32  	"sync"
    33  
    34  	"bazil.org/fuse"
    35  	"bazil.org/fuse/fs"
    36  	"github.com/ethereum/go-ethereum/swarm/log"
    37  	"golang.org/x/net/context"
    38  )
    39  
    40  var (
    41  	_ fs.Node                = (*SwarmDir)(nil)
    42  	_ fs.NodeRequestLookuper = (*SwarmDir)(nil)
    43  	_ fs.HandleReadDirAller  = (*SwarmDir)(nil)
    44  	_ fs.NodeCreater         = (*SwarmDir)(nil)
    45  	_ fs.NodeRemover         = (*SwarmDir)(nil)
    46  	_ fs.NodeMkdirer         = (*SwarmDir)(nil)
    47  )
    48  
    49  type SwarmDir struct {
    50  	inode       uint64
    51  	name        string
    52  	path        string
    53  	directories []*SwarmDir
    54  	files       []*SwarmFile
    55  
    56  	mountInfo *MountInfo
    57  	lock      *sync.RWMutex
    58  }
    59  
    60  func NewSwarmDir(fullpath string, minfo *MountInfo) *SwarmDir {
    61  	log.Debug("swarmfs", "NewSwarmDir", fullpath)
    62  	newdir := &SwarmDir{
    63  		inode:       NewInode(),
    64  		name:        filepath.Base(fullpath),
    65  		path:        fullpath,
    66  		directories: []*SwarmDir{},
    67  		files:       []*SwarmFile{},
    68  		mountInfo:   minfo,
    69  		lock:        &sync.RWMutex{},
    70  	}
    71  	return newdir
    72  }
    73  
    74  func (sd *SwarmDir) Attr(ctx context.Context, a *fuse.Attr) error {
    75  	sd.lock.RLock()
    76  	defer sd.lock.RUnlock()
    77  	a.Inode = sd.inode
    78  	a.Mode = os.ModeDir | 0700
    79  	a.Uid = uint32(os.Getuid())
    80  	a.Gid = uint32(os.Getegid())
    81  	return nil
    82  }
    83  
    84  func (sd *SwarmDir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) {
    85  	log.Debug("swarmfs", "Lookup", req.Name)
    86  	for _, n := range sd.files {
    87  		if n.name == req.Name {
    88  			return n, nil
    89  		}
    90  	}
    91  	for _, n := range sd.directories {
    92  		if n.name == req.Name {
    93  			return n, nil
    94  		}
    95  	}
    96  	return nil, fuse.ENOENT
    97  }
    98  
    99  func (sd *SwarmDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
   100  	log.Debug("swarmfs ReadDirAll")
   101  	var children []fuse.Dirent
   102  	for _, file := range sd.files {
   103  		children = append(children, fuse.Dirent{Inode: file.inode, Type: fuse.DT_File, Name: file.name})
   104  	}
   105  	for _, dir := range sd.directories {
   106  		children = append(children, fuse.Dirent{Inode: dir.inode, Type: fuse.DT_Dir, Name: dir.name})
   107  	}
   108  	return children, nil
   109  }
   110  
   111  func (sd *SwarmDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
   112  	log.Debug("swarmfs Create", "path", sd.path, "req.Name", req.Name)
   113  
   114  	newFile := NewSwarmFile(sd.path, req.Name, sd.mountInfo)
   115  newFile.fileSize = 0 //
   116  
   117  	sd.lock.Lock()
   118  	defer sd.lock.Unlock()
   119  	sd.files = append(sd.files, newFile)
   120  
   121  	return newFile, newFile, nil
   122  }
   123  
   124  func (sd *SwarmDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
   125  	log.Debug("swarmfs Remove", "path", sd.path, "req.Name", req.Name)
   126  
   127  	if req.Dir && sd.directories != nil {
   128  		newDirs := []*SwarmDir{}
   129  		for _, dir := range sd.directories {
   130  			if dir.name == req.Name {
   131  				removeDirectoryFromSwarm(dir)
   132  			} else {
   133  				newDirs = append(newDirs, dir)
   134  			}
   135  		}
   136  		if len(sd.directories) > len(newDirs) {
   137  			sd.lock.Lock()
   138  			defer sd.lock.Unlock()
   139  			sd.directories = newDirs
   140  		}
   141  		return nil
   142  	} else if !req.Dir && sd.files != nil {
   143  		newFiles := []*SwarmFile{}
   144  		for _, f := range sd.files {
   145  			if f.name == req.Name {
   146  				removeFileFromSwarm(f)
   147  			} else {
   148  				newFiles = append(newFiles, f)
   149  			}
   150  		}
   151  		if len(sd.files) > len(newFiles) {
   152  			sd.lock.Lock()
   153  			defer sd.lock.Unlock()
   154  			sd.files = newFiles
   155  		}
   156  		return nil
   157  	}
   158  	return fuse.ENOENT
   159  }
   160  
   161  func (sd *SwarmDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
   162  	log.Debug("swarmfs Mkdir", "path", sd.path, "req.Name", req.Name)
   163  	newDir := NewSwarmDir(filepath.Join(sd.path, req.Name), sd.mountInfo)
   164  	sd.lock.Lock()
   165  	defer sd.lock.Unlock()
   166  	sd.directories = append(sd.directories, newDir)
   167  
   168  	return newDir, nil
   169  }