aboutsummaryrefslogtreecommitdiff
path: root/weed/filesys
diff options
context:
space:
mode:
authorhilimd <68371223+hilimd@users.noreply.github.com>2021-04-06 13:39:26 +0800
committerGitHub <noreply@github.com>2021-04-06 13:39:26 +0800
commit8693cdacae5b4201ccd259382a02392250b0890e (patch)
treeb565af4380b0f59a61b1d3c9fad8f04cbb802e7c /weed/filesys
parent17d02264f33f501e124060ade7b0b39e687aaa3d (diff)
parenta37eca78cd680858d021cd864766b0847328a8d7 (diff)
downloadseaweedfs-8693cdacae5b4201ccd259382a02392250b0890e.tar.xz
seaweedfs-8693cdacae5b4201ccd259382a02392250b0890e.zip
Merge pull request #75 from chrislusf/master
sync
Diffstat (limited to 'weed/filesys')
-rw-r--r--weed/filesys/dir.go29
-rw-r--r--weed/filesys/dir_link.go8
-rw-r--r--weed/filesys/dir_rename.go4
-rw-r--r--weed/filesys/dir_test.go34
-rw-r--r--weed/filesys/file.go36
-rw-r--r--weed/filesys/filehandle.go21
-rw-r--r--weed/filesys/wfs.go1
7 files changed, 84 insertions, 49 deletions
diff --git a/weed/filesys/dir.go b/weed/filesys/dir.go
index 33e1a0a3a..46457f858 100644
--- a/weed/filesys/dir.go
+++ b/weed/filesys/dir.go
@@ -128,6 +128,10 @@ func (dir *Dir) newDirectory(fullpath util.FullPath, entry *filer_pb.Entry) fs.N
func (dir *Dir) Create(ctx context.Context, req *fuse.CreateRequest,
resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
+ if dir.wfs.option.ReadOnly {
+ return nil, nil, fuse.EPERM
+ }
+
request, err := dir.doCreateEntry(req.Name, req.Mode, req.Uid, req.Gid, req.Flags&fuse.OpenExclusive != 0)
if err != nil {
@@ -148,6 +152,10 @@ func (dir *Dir) Create(ctx context.Context, req *fuse.CreateRequest,
func (dir *Dir) Mknod(ctx context.Context, req *fuse.MknodRequest) (fs.Node, error) {
+ if dir.wfs.option.ReadOnly {
+ return nil, fuse.EPERM
+ }
+
request, err := dir.doCreateEntry(req.Name, req.Mode, req.Uid, req.Gid, false)
if err != nil {
@@ -202,6 +210,10 @@ func (dir *Dir) doCreateEntry(name string, mode os.FileMode, uid, gid uint32, ex
func (dir *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
+ if dir.wfs.option.ReadOnly {
+ return nil, fuse.EPERM
+ }
+
glog.V(4).Infof("mkdir %s: %s", dir.FullPath(), req.Name)
newEntry := &filer_pb.Entry{
@@ -356,6 +368,11 @@ func findFileType(mode uint16) fuse.DirentType {
func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
+ if dir.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
+
if !req.Dir {
return dir.removeOneFile(req)
}
@@ -429,6 +446,10 @@ func (dir *Dir) removeFolder(req *fuse.RemoveRequest) error {
func (dir *Dir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
+ if dir.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("%v dir setattr %+v", dir.FullPath(), req)
if err := dir.maybeLoadEntry(); err != nil {
@@ -457,6 +478,10 @@ func (dir *Dir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fus
func (dir *Dir) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
+ if dir.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("dir Setxattr %s: %s", dir.FullPath(), req.Name)
if err := dir.maybeLoadEntry(); err != nil {
@@ -473,6 +498,10 @@ func (dir *Dir) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
func (dir *Dir) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
+ if dir.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("dir Removexattr %s: %s", dir.FullPath(), req.Name)
if err := dir.maybeLoadEntry(); err != nil {
diff --git a/weed/filesys/dir_link.go b/weed/filesys/dir_link.go
index 606e52fcb..6266e492d 100644
--- a/weed/filesys/dir_link.go
+++ b/weed/filesys/dir_link.go
@@ -24,6 +24,10 @@ const (
func (dir *Dir) Link(ctx context.Context, req *fuse.LinkRequest, old fs.Node) (fs.Node, error) {
+ if dir.wfs.option.ReadOnly {
+ return nil, fuse.EPERM
+ }
+
oldFile, ok := old.(*File)
if !ok {
glog.Errorf("old node is not a file: %+v", old)
@@ -105,6 +109,10 @@ func (dir *Dir) Link(ctx context.Context, req *fuse.LinkRequest, old fs.Node) (f
func (dir *Dir) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) {
+ if dir.wfs.option.ReadOnly {
+ return nil, fuse.EPERM
+ }
+
glog.V(4).Infof("Symlink: %v/%v to %v", dir.FullPath(), req.NewName, req.Target)
request := &filer_pb.CreateEntryRequest{
diff --git a/weed/filesys/dir_rename.go b/weed/filesys/dir_rename.go
index d2acad4b2..28316c3bd 100644
--- a/weed/filesys/dir_rename.go
+++ b/weed/filesys/dir_rename.go
@@ -13,6 +13,10 @@ import (
func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirectory fs.Node) error {
+ if dir.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
newDir := newDirectory.(*Dir)
newPath := util.NewFullPath(newDir.FullPath(), req.NewName)
diff --git a/weed/filesys/dir_test.go b/weed/filesys/dir_test.go
deleted file mode 100644
index 49c76eb5e..000000000
--- a/weed/filesys/dir_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package filesys
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestDirPath(t *testing.T) {
-
- p := &Dir{name: "/some"}
- p = &Dir{name: "path", parent: p}
- p = &Dir{name: "to", parent: p}
- p = &Dir{name: "a", parent: p}
- p = &Dir{name: "file", parent: p}
-
- assert.Equal(t, "/some/path/to/a/file", p.FullPath())
-
- p = &Dir{name: "/some"}
- assert.Equal(t, "/some", p.FullPath())
-
- p = &Dir{name: "/"}
- assert.Equal(t, "/", p.FullPath())
-
- p = &Dir{name: "/"}
- p = &Dir{name: "path", parent: p}
- assert.Equal(t, "/path", p.FullPath())
-
- p = &Dir{name: "/"}
- p = &Dir{name: "path", parent: p}
- p = &Dir{name: "to", parent: p}
- assert.Equal(t, "/path/to", p.FullPath())
-
-}
diff --git a/weed/filesys/file.go b/weed/filesys/file.go
index 5931dd2ff..2433be590 100644
--- a/weed/filesys/file.go
+++ b/weed/filesys/file.go
@@ -56,6 +56,10 @@ func (file *File) Attr(ctx context.Context, attr *fuse.Attr) (err error) {
}
}
+ if entry == nil {
+ return fuse.ENOENT
+ }
+
// attr.Inode = file.fullpath().AsInode()
attr.Valid = time.Second
attr.Mode = os.FileMode(entry.Attributes.FileMode)
@@ -106,6 +110,10 @@ func (file *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.Op
func (file *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
+ if file.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("%v file setattr %+v", file.fullpath(), req)
entry, err := file.maybeLoadEntry(ctx)
@@ -147,7 +155,7 @@ func (file *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *f
}
entry.Chunks = chunks
file.entryViewCache, _ = filer.NonOverlappingVisibleIntervals(file.wfs.LookupFn(), chunks)
- file.reader = nil
+ file.setReader(nil)
}
entry.Attributes.FileSize = req.Size
file.dirtyMetadata = true
@@ -196,6 +204,10 @@ func (file *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *f
func (file *File) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
+ if file.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("file Setxattr %s: %s", file.fullpath(), req.Name)
entry, err := file.maybeLoadEntry(ctx)
@@ -213,6 +225,10 @@ func (file *File) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error
func (file *File) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
+ if file.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
glog.V(4).Infof("file Removexattr %s: %s", file.fullpath(), req.Name)
entry, err := file.maybeLoadEntry(ctx)
@@ -257,6 +273,8 @@ func (file *File) Forget() {
t := util.NewFullPath(file.dir.FullPath(), file.Name)
glog.V(4).Infof("Forget file %s", t)
file.wfs.fsNodeCache.DeleteFsNode(t)
+ file.wfs.ReleaseHandle(t, 0)
+ file.setReader(nil)
}
func (file *File) maybeLoadEntry(ctx context.Context) (entry *filer_pb.Entry, err error) {
@@ -323,19 +341,29 @@ func (file *File) addChunks(chunks []*filer_pb.FileChunk) {
file.entryViewCache = filer.MergeIntoVisibles(file.entryViewCache, chunk)
}
- file.reader = nil
+ file.setReader(nil)
glog.V(4).Infof("%s existing %d chunks adds %d more", file.fullpath(), len(entry.Chunks), len(chunks))
entry.Chunks = append(entry.Chunks, newChunks...)
}
+func (file *File) setReader(reader io.ReaderAt) {
+ r := file.reader
+ if r != nil {
+ if closer, ok := r.(io.Closer); ok {
+ closer.Close()
+ }
+ }
+ file.reader = reader
+}
+
func (file *File) setEntry(entry *filer_pb.Entry) {
file.entryLock.Lock()
defer file.entryLock.Unlock()
file.entry = entry
file.entryViewCache, _ = filer.NonOverlappingVisibleIntervals(file.wfs.LookupFn(), entry.Chunks)
- file.reader = nil
+ file.setReader(nil)
}
func (file *File) clearEntry() {
@@ -343,7 +371,7 @@ func (file *File) clearEntry() {
defer file.entryLock.Unlock()
file.entry = nil
file.entryViewCache = nil
- file.reader = nil
+ file.setReader(nil)
}
func (file *File) saveEntry(entry *filer_pb.Entry) error {
diff --git a/weed/filesys/filehandle.go b/weed/filesys/filehandle.go
index 25eaf7033..4419888c4 100644
--- a/weed/filesys/filehandle.go
+++ b/weed/filesys/filehandle.go
@@ -23,7 +23,7 @@ type FileHandle struct {
dirtyPages *ContinuousDirtyPages
contentType string
handle uint64
- sync.RWMutex
+ sync.Mutex
f *File
RequestId fuse.RequestID // unique ID for request
@@ -59,8 +59,8 @@ var _ = fs.HandleReleaser(&FileHandle{})
func (fh *FileHandle) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
glog.V(4).Infof("%s read fh %d: [%d,%d) size %d resp.Data cap=%d", fh.f.fullpath(), fh.handle, req.Offset, req.Offset+int64(req.Size), req.Size, cap(resp.Data))
- fh.RLock()
- defer fh.RUnlock()
+ fh.Lock()
+ defer fh.Unlock()
if req.Size <= 0 {
return nil
@@ -130,7 +130,7 @@ func (fh *FileHandle) readFromChunks(buff []byte, offset int64) (int64, error) {
if chunkResolveErr != nil {
return 0, fmt.Errorf("fail to resolve chunk manifest: %v", chunkResolveErr)
}
- fh.f.reader = nil
+ fh.f.setReader(nil)
}
reader := fh.f.reader
@@ -138,7 +138,7 @@ func (fh *FileHandle) readFromChunks(buff []byte, offset int64) (int64, error) {
chunkViews := filer.ViewFromVisibleIntervals(fh.f.entryViewCache, 0, math.MaxInt64)
reader = filer.NewChunkReaderAtFromClient(fh.f.wfs.LookupFn(), chunkViews, fh.f.wfs.chunkCache, fileSize)
}
- fh.f.reader = reader
+ fh.f.setReader(reader)
totalRead, err := reader.ReadAt(buff, offset)
@@ -154,6 +154,10 @@ func (fh *FileHandle) readFromChunks(buff []byte, offset int64) (int64, error) {
// Write to the file handle
func (fh *FileHandle) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
+ if fh.f.wfs.option.ReadOnly {
+ return fuse.EPERM
+ }
+
fh.Lock()
defer fh.Unlock()
@@ -207,12 +211,7 @@ func (fh *FileHandle) Release(ctx context.Context, req *fuse.ReleaseRequest) err
fh.f.isOpen--
fh.f.wfs.ReleaseHandle(fh.f.fullpath(), fuse.HandleID(fh.handle))
- if closer, ok := fh.f.reader.(io.Closer); ok {
- if closer != nil {
- closer.Close()
- }
- }
- fh.f.reader = nil
+ fh.f.setReader(nil)
}
return nil
diff --git a/weed/filesys/wfs.go b/weed/filesys/wfs.go
index c6d9080a1..ba5eb4b6b 100644
--- a/weed/filesys/wfs.go
+++ b/weed/filesys/wfs.go
@@ -43,6 +43,7 @@ type Option struct {
DataCenter string
EntryCacheTtl time.Duration
Umask os.FileMode
+ ReadOnly bool
MountUid uint32
MountGid uint32