aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrislu <chris.lu@gmail.com>2022-02-13 03:09:24 -0800
committerchrislu <chris.lu@gmail.com>2022-02-13 03:09:24 -0800
commit6a42cb6b0bf1b96fce06af06e418845ca288ac0f (patch)
tree5062b18aa24fb30b2f9d96d24a56b680d7121543
parent813b868b9ad8d22e05acc3f2003a9c196cdd83b5 (diff)
downloadseaweedfs-6a42cb6b0bf1b96fce06af06e418845ca288ac0f.tar.xz
seaweedfs-6a42cb6b0bf1b96fce06af06e418845ca288ac0f.zip
supports mknod, unlink
-rw-r--r--weed/mount/inode_to_path.go13
-rw-r--r--weed/mount/weedfs_attr.go23
-rw-r--r--weed/mount/weedfs_dir_mkrm.go1
-rw-r--r--weed/mount/weedfs_file_mkrm.go108
4 files changed, 145 insertions, 0 deletions
diff --git a/weed/mount/inode_to_path.go b/weed/mount/inode_to_path.go
index e3fabb422..21e6c867c 100644
--- a/weed/mount/inode_to_path.go
+++ b/weed/mount/inode_to_path.go
@@ -69,3 +69,16 @@ func (i *InodeToPath) HasInode(inode uint64) bool {
_, found := i.inode2path[inode]
return found
}
+
+func (i *InodeToPath) RemovePath(path util.FullPath) {
+ if path == "/" {
+ return
+ }
+ i.Lock()
+ defer i.Unlock()
+ inode, found := i.path2inode[path]
+ if found {
+ delete(i.path2inode, path)
+ delete(i.inode2path, inode)
+ }
+}
diff --git a/weed/mount/weedfs_attr.go b/weed/mount/weedfs_attr.go
index 8dbf65fe8..a907493ad 100644
--- a/weed/mount/weedfs_attr.go
+++ b/weed/mount/weedfs_attr.go
@@ -147,3 +147,26 @@ func toSystemType(mode os.FileMode) uint32 {
return syscall.S_IFREG
}
}
+
+func toFileType(mode uint32) os.FileMode {
+ switch mode & (syscall.S_IFMT & 0xffff) {
+ case syscall.S_IFDIR:
+ return os.ModeDir
+ case syscall.S_IFLNK:
+ return os.ModeSymlink
+ case syscall.S_IFIFO:
+ return os.ModeNamedPipe
+ case syscall.S_IFSOCK:
+ return os.ModeSocket
+ case syscall.S_IFBLK:
+ return os.ModeDevice
+ case syscall.S_IFCHR:
+ return os.ModeCharDevice
+ default:
+ return 0
+ }
+}
+
+func toFileMode(mode uint32) os.FileMode {
+ return toFileType(mode) | os.FileMode(mode&07777)
+}
diff --git a/weed/mount/weedfs_dir_mkrm.go b/weed/mount/weedfs_dir_mkrm.go
index 69bafaa7e..63fe34f91 100644
--- a/weed/mount/weedfs_dir_mkrm.go
+++ b/weed/mount/weedfs_dir_mkrm.go
@@ -97,6 +97,7 @@ func (wfs *WFS) Rmdir(cancel <-chan struct{}, header *fuse.InHeader, name string
}
wfs.metaCache.DeleteEntry(context.Background(), entryFullPath)
+ wfs.inodeToPath.RemovePath(entryFullPath)
return fuse.OK
diff --git a/weed/mount/weedfs_file_mkrm.go b/weed/mount/weedfs_file_mkrm.go
new file mode 100644
index 000000000..b5ade894e
--- /dev/null
+++ b/weed/mount/weedfs_file_mkrm.go
@@ -0,0 +1,108 @@
+package mount
+
+import (
+ "context"
+ "fmt"
+ "github.com/chrislusf/seaweedfs/weed/filer"
+ "github.com/chrislusf/seaweedfs/weed/glog"
+ "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+ "github.com/hanwen/go-fuse/v2/fuse"
+ "time"
+)
+
+func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out *fuse.EntryOut) (code fuse.Status) {
+
+ if s := checkName(name); s != fuse.OK {
+ return s
+ }
+
+ newEntry := &filer_pb.Entry{
+ Name: name,
+ IsDirectory: false,
+ Attributes: &filer_pb.FuseAttributes{
+ Mtime: time.Now().Unix(),
+ Crtime: time.Now().Unix(),
+ FileMode: uint32(toFileMode(in.Mode) &^ wfs.option.Umask),
+ Uid: in.Uid,
+ Gid: in.Gid,
+ Collection: wfs.option.Collection,
+ Replication: wfs.option.Replication,
+ TtlSec: wfs.option.TtlSec,
+ },
+ }
+
+ dirFullPath := wfs.inodeToPath.GetPath(in.NodeId)
+
+ entryFullPath := dirFullPath.Child(name)
+
+ err := wfs.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
+
+ wfs.mapPbIdFromLocalToFiler(newEntry)
+ defer wfs.mapPbIdFromFilerToLocal(newEntry)
+
+ request := &filer_pb.CreateEntryRequest{
+ Directory: string(dirFullPath),
+ Entry: newEntry,
+ Signatures: []int32{wfs.signature},
+ }
+
+ glog.V(1).Infof("mknod: %v", request)
+ if err := filer_pb.CreateEntry(client, request); err != nil {
+ glog.V(0).Infof("mknod %s: %v", entryFullPath, err)
+ return err
+ }
+
+ if err := wfs.metaCache.InsertEntry(context.Background(), filer.FromPbEntry(request.Directory, request.Entry)); err != nil {
+ return fmt.Errorf("local mknod %s: %v", entryFullPath, err)
+ }
+
+ return nil
+ })
+
+ glog.V(0).Infof("mknod %s: %v", entryFullPath, err)
+
+ if err != nil {
+ return fuse.EIO
+ }
+
+ inode := wfs.inodeToPath.GetInode(entryFullPath)
+
+ wfs.outputPbEntry(out, inode, newEntry)
+
+ return fuse.OK
+
+}
+
+func (wfs *WFS) Unlink(cancel <-chan struct{}, header *fuse.InHeader, name string) (code fuse.Status) {
+
+ dirFullPath := wfs.inodeToPath.GetPath(header.NodeId)
+ entryFullPath := dirFullPath.Child(name)
+
+ entry, status := wfs.maybeLoadEntry(entryFullPath)
+ if status != fuse.OK {
+ return status
+ }
+
+ // first, ensure the filer store can correctly delete
+ glog.V(3).Infof("remove file: %v", entryFullPath)
+ isDeleteData := entry != nil && entry.HardLinkCounter <= 1
+ err := filer_pb.Remove(wfs, string(dirFullPath), name, isDeleteData, false, false, false, []int32{wfs.signature})
+ if err != nil {
+ glog.V(0).Infof("remove %s: %v", entryFullPath, err)
+ return fuse.ENOENT
+ }
+
+ // then, delete meta cache
+ if err = wfs.metaCache.DeleteEntry(context.Background(), entryFullPath); err != nil {
+ glog.V(3).Infof("local DeleteEntry %s: %v", entryFullPath, err)
+ return fuse.EIO
+ }
+
+ wfs.metaCache.DeleteEntry(context.Background(), entryFullPath)
+ wfs.inodeToPath.RemovePath(entryFullPath)
+
+ // TODO handle open files, hardlink
+
+ return fuse.OK
+
+}