diff --git a/kernel/api/block.go b/kernel/api/block.go
index 247ba97b4..032ed30c7 100644
--- a/kernel/api/block.go
+++ b/kernel/api/block.go
@@ -17,13 +17,14 @@
package api
import (
+ "errors"
"fmt"
"net/http"
"github.com/88250/gulu"
"github.com/88250/lute/html"
"github.com/gin-gonic/gin"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -73,7 +74,7 @@ func checkBlockExist(c *gin.Context) {
id := arg["id"].(string)
b, err := model.GetBlock(id)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
ret.Code = 2
ret.Data = id
return
@@ -221,7 +222,7 @@ func getBlockInfo(c *gin.Context) {
id := arg["id"].(string)
block, err := model.GetBlock(id)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
ret.Code = 2
ret.Data = id
return
@@ -247,7 +248,7 @@ func getBlockInfo(c *gin.Context) {
}
root, err := model.GetBlock(block.RootID)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
ret.Code = 2
ret.Data = id
return
diff --git a/kernel/api/file.go b/kernel/api/file.go
index 44204c8e0..7a7a245ee 100644
--- a/kernel/api/file.go
+++ b/kernel/api/file.go
@@ -28,7 +28,7 @@ import (
"github.com/88250/gulu"
"github.com/gin-gonic/gin"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -92,7 +92,7 @@ func putFile(c *gin.Context) {
if err = os.MkdirAll(dir, 0755); nil != err {
util.LogErrorf("put a file [%s] make dir [%s] failed: %s", filePath, dir, err)
} else {
- if filesys.IsLocked(filePath) {
+ if filelock.IsLocked(filePath) {
msg := fmt.Sprintf("file [%s] is locked", filePath)
util.LogErrorf(msg)
err = errors.New(msg)
diff --git a/kernel/api/filetree.go b/kernel/api/filetree.go
index da29033e7..e292f5d2f 100644
--- a/kernel/api/filetree.go
+++ b/kernel/api/filetree.go
@@ -17,6 +17,7 @@
package api
import (
+ "errors"
"fmt"
"net/http"
"path"
@@ -26,7 +27,7 @@ import (
"github.com/88250/gulu"
"github.com/gin-gonic/gin"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -592,7 +593,7 @@ func getDoc(c *gin.Context) {
}
blockCount, content, parentID, parent2ID, rootID, typ, eof, boxID, docPath, err := model.GetDoc(id, index, keyword, mode, size)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
ret.Code = 2
ret.Data = id
return
diff --git a/kernel/api/transaction.go b/kernel/api/transaction.go
index 3f469498b..e2068cc3a 100644
--- a/kernel/api/transaction.go
+++ b/kernel/api/transaction.go
@@ -17,13 +17,14 @@
package api
import (
+ "errors"
"fmt"
"net/http"
"time"
"github.com/88250/gulu"
"github.com/gin-gonic/gin"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -64,7 +65,7 @@ func performTransactions(c *gin.Context) {
err = model.PerformTransactions(&transactions)
}
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
ret.Code = 1
return
}
diff --git a/kernel/filesys/filelock.go b/kernel/filesys/filelock.go
deleted file mode 100644
index 4c15883f0..000000000
--- a/kernel/filesys/filelock.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// SiYuan - Build Your Eternal Digital Garden
-// Copyright (c) 2020-present, b3log.org
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-//go:build !android && !ios
-
-package filesys
-
-import (
- "errors"
- "io"
- "os"
- "strings"
- "sync"
- "time"
-
- "github.com/88250/flock"
- "github.com/88250/gulu"
- "github.com/siyuan-note/siyuan/kernel/util"
-)
-
-var ErrUnableLockFile = errors.New("unable to lock file")
-
-var (
- fileLocks = sync.Map{}
- expiration = 5 * time.Minute
- fileReadWriteLock = sync.Mutex{}
-)
-
-type LockItem struct {
- fl *flock.Flock
- expired int64
-}
-
-func init() {
- go func() {
- // 锁定超时自动解锁
- for range time.Tick(10 * time.Second) {
- fileReadWriteLock.Lock()
-
- now := time.Now().UnixNano()
- var expiredKeys []string
- fileLocks.Range(func(k, v interface{}) bool {
- lockItem := v.(*LockItem)
- if now > lockItem.expired {
- expiredKeys = append(expiredKeys, k.(string))
- }
- return true
- })
-
- for _, k := range expiredKeys {
- if err := unlockFile0(k); nil != err {
- util.LogErrorf("unlock file [%s] failed: %s", k, err)
- continue
- }
-
- //util.LogInfof("released file lock [%s]", k)
- }
-
- fileReadWriteLock.Unlock()
- }
- }()
-}
-
-func ReleaseFileLocks(localAbsPath string) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- fileLocks.Range(func(k, v interface{}) bool {
- if strings.HasPrefix(k.(string), localAbsPath) {
- if err := unlockFile0(k.(string)); nil != err {
- util.LogErrorf("unlock file [%s] failed: %s", k, err)
- }
- }
- return true
- })
-}
-
-func ReleaseAllFileLocks() {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- fileLocks.Range(func(k, v interface{}) bool {
- if err := unlockFile0(k.(string)); nil != err {
- util.LogErrorf("unlock file [%s] failed: %s", k, err)
- }
- return true
- })
-}
-
-func NoLockFileRead(filePath string) (data []byte, err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- v, ok := fileLocks.Load(filePath)
- if !ok {
- return os.ReadFile(filePath)
- }
- lockItem := v.(*LockItem)
- handle := lockItem.fl.Fh()
- if _, err = handle.Seek(0, io.SeekStart); nil != err {
- return
- }
- return io.ReadAll(handle)
-}
-
-func LockFileRead(filePath string) (data []byte, err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- if !gulu.File.IsExist(filePath) {
- err = os.ErrNotExist
- return
- }
-
- lock, lockErr := lockFile0(filePath)
- if nil != lockErr {
- err = lockErr
- return
- }
-
- handle := lock.Fh()
- if _, err = handle.Seek(0, io.SeekStart); nil != err {
- return
- }
- return io.ReadAll(handle)
-}
-
-func NoLockFileWrite(filePath string, data []byte) (err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- v, ok := fileLocks.Load(filePath)
- if !ok {
- return os.WriteFile(filePath, data, 0644)
- }
-
- lockItem := v.(*LockItem)
- handle := lockItem.fl.Fh()
- err = gulu.File.WriteFileSaferByHandle(handle, data)
- return
-}
-
-func LockFileWrite(filePath string, data []byte) (err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
-
- lock, lockErr := lockFile0(filePath)
- if nil != lockErr {
- err = lockErr
- return
- }
-
- handle := lock.Fh()
- err = gulu.File.WriteFileSaferByHandle(handle, data)
- return
-}
-
-func IsLocked(filePath string) bool {
- v, _ := fileLocks.Load(filePath)
- if nil == v {
- return false
- }
- return true
-}
-
-func UnlockFile(filePath string) (err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
- return unlockFile0(filePath)
-}
-
-func unlockFile0(filePath string) (err error) {
- v, _ := fileLocks.Load(filePath)
- if nil == v {
- return
- }
- lockItem := v.(*LockItem)
- err = lockItem.fl.Unlock()
- fileLocks.Delete(filePath)
- return
-}
-
-func LockFile(filePath string) (err error) {
- fileReadWriteLock.Lock()
- defer fileReadWriteLock.Unlock()
- _, err = lockFile0(filePath)
- return
-}
-
-func lockFile0(filePath string) (lock *flock.Flock, err error) {
- lockItemVal, _ := fileLocks.Load(filePath)
- var lockItem *LockItem
- if nil == lockItemVal {
- lock = flock.New(filePath)
- var locked bool
- var lockErr error
- for i := 0; i < 7; i++ {
- locked, lockErr = lock.TryLock()
- if nil != lockErr || !locked {
- time.Sleep(100 * time.Millisecond)
- continue
- }
- break
- }
-
- if nil != lockErr {
- util.LogErrorf("lock file [%s] failed: %s", filePath, lockErr)
- err = ErrUnableLockFile
- return
- }
-
- if !locked {
- util.LogErrorf("unable to lock file [%s]", filePath)
- err = ErrUnableLockFile
- return
- }
- lockItem = &LockItem{fl: lock}
- } else {
- lockItem = lockItemVal.(*LockItem)
- lock = lockItem.fl
- }
- lockItem.expired = time.Now().Add(expiration).UnixNano()
- fileLocks.Store(filePath, lockItem)
- return
-}
diff --git a/kernel/filesys/filelock_mobile.go b/kernel/filesys/filelock_mobile.go
deleted file mode 100644
index c0489e9c5..000000000
--- a/kernel/filesys/filelock_mobile.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// SiYuan - Build Your Eternal Digital Garden
-// Copyright (c) 2020-present, b3log.org
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-//go:build android || ios
-// +build android ios
-
-package filesys
-
-import (
- "errors"
- "os"
- "sync"
-
- "github.com/88250/gulu"
-)
-
-var ErrUnableLockFile = errors.New("unable to lock file")
-
-func ReleaseFileLocks(boxLocalPath string) {}
-
-func ReleaseAllFileLocks() {}
-
-func NoLockFileRead(filePath string) (data []byte, err error) {
- return os.ReadFile(filePath)
-}
-
-func LockFileRead(filePath string) (data []byte, err error) {
- return os.ReadFile(filePath)
-}
-
-func NoLockFileWrite(filePath string, data []byte) (err error) {
- return gulu.File.WriteFileSafer(filePath, data, 0644)
-}
-
-func LockFileWrite(filePath string, data []byte) (err error) {
- return gulu.File.WriteFileSafer(filePath, data, 0644)
-}
-
-func LockFile(filePath string) (err error) {
- return
-}
-
-func UnlockFile(filePath string) (err error) {
- return
-}
-
-var fileLocks = sync.Map{}
-
-func IsLocked(filePath string) bool {
- return false
-}
-
-func LockFileReadWrite() {
-}
-
-func UnlockFileReadWriteLock() {
-}
diff --git a/kernel/filesys/tree.go b/kernel/filesys/tree.go
index 91f1e51b3..15f8cfef4 100644
--- a/kernel/filesys/tree.go
+++ b/kernel/filesys/tree.go
@@ -29,6 +29,7 @@ import (
"github.com/88250/lute"
"github.com/88250/lute/parse"
"github.com/88250/protyle"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -36,7 +37,7 @@ import (
func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
filePath := filepath.Join(util.DataDir, boxID, p)
- data, err := LockFileRead(filePath)
+ data, err := filelock.LockFileRead(filePath)
if nil != err {
return
}
@@ -70,7 +71,7 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
}
parentPath += ".sy"
parentPath = filepath.Join(util.DataDir, boxID, parentPath)
- data, err := LockFileRead(parentPath)
+ data, err := filelock.LockFileRead(parentPath)
if nil != err {
hPathBuilder.WriteString("Untitled/")
continue
@@ -113,7 +114,7 @@ func WriteTree(tree *parse.Tree) (err error) {
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
return
}
- if err = LockFileWrite(filePath, output); nil != err {
+ if err = filelock.LockFileWrite(filePath, output); nil != err {
msg := fmt.Sprintf("write data [%s] failed: %s", filePath, err)
util.LogErrorf(msg)
return errors.New(msg)
@@ -144,12 +145,12 @@ func recoverParseJSON2Tree(boxID, p, filePath string, luteEngine *lute.Lute) (re
return
}
- data, err := NoLockFileRead(tmp)
+ data, err := filelock.NoLockFileRead(tmp)
if nil != err {
util.LogErrorf("recover tree read from tmp [%s] failed: %s", tmp, err)
return
}
- if err = NoLockFileWrite(filePath, data); nil != err {
+ if err = filelock.NoLockFileWrite(filePath, data); nil != err {
util.LogErrorf("recover tree write [%s] from tmp [%s] failed: %s", filePath, tmp, err)
return
}
@@ -191,7 +192,7 @@ func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (re
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
return
}
- if err = LockFileWrite(filePath, output); nil != err {
+ if err = filelock.LockFileWrite(filePath, output); nil != err {
msg := fmt.Sprintf("write data [%s] failed: %s", filePath, err)
util.LogErrorf(msg)
}
diff --git a/kernel/filesys/workspace.go b/kernel/filesys/workspace.go
index b5b6e4215..be311e006 100644
--- a/kernel/filesys/workspace.go
+++ b/kernel/filesys/workspace.go
@@ -22,6 +22,7 @@ import (
"sync"
"github.com/88250/gulu"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -47,7 +48,7 @@ func IncWorkspaceDataVer(inc bool, systemID string) {
conf := &DataConf{Updated: now, Device: systemID}
if !gulu.File.IsExist(confPath) {
data, _ = gulu.JSON.MarshalIndentJSON(conf, "", " ")
- if err = LockFileWrite(confPath, data); nil != err {
+ if err = filelock.LockFileWrite(confPath, data); nil != err {
util.LogErrorf("save data conf [%s] failed: %s", confPath, err)
}
@@ -58,7 +59,7 @@ func IncWorkspaceDataVer(inc bool, systemID string) {
return
}
- data, err = LockFileRead(confPath)
+ data, err = filelock.LockFileRead(confPath)
if nil != err {
data, err = recoverFrom(confPath)
if nil != err {
@@ -83,7 +84,7 @@ func IncWorkspaceDataVer(inc bool, systemID string) {
}
data, _ = gulu.JSON.MarshalIndentJSON(conf, "", " ")
- if err = LockFileWrite(confPath, data); nil != err {
+ if err = filelock.LockFileWrite(confPath, data); nil != err {
util.LogErrorf("save data conf [%s] failed: %s", confPath, err)
return
}
@@ -96,7 +97,7 @@ func recoverFrom(confPath string) (data []byte, err error) {
return
}
- data, err = NoLockFileRead(tmp)
+ data, err = filelock.NoLockFileRead(tmp)
if nil != err {
util.LogErrorf("read temp data conf [%s] failed: %s", tmp, err)
return
diff --git a/kernel/go.mod b/kernel/go.mod
index 25261a3c4..b8b1cff60 100644
--- a/kernel/go.mod
+++ b/kernel/go.mod
@@ -40,8 +40,9 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/qiniu/go-sdk/v7 v7.13.0
github.com/radovskyb/watcher v1.0.7
- github.com/siyuan-note/dejavu v0.0.0-20220615074544-177b5b3df8bb
+ github.com/siyuan-note/dejavu v0.0.0-20220615164826-201b6516adf3
github.com/siyuan-note/encryption v0.0.0-20220612074546-f1dd94fe8676
+ github.com/siyuan-note/filelock v0.0.0-20220615164210-064676f342aa
github.com/vmihailenco/msgpack/v5 v5.3.5
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
@@ -93,11 +94,13 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
+ go.uber.org/atomic v1.9.0 // indirect
+ go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
- golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect
+ golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 // indirect
golang.org/x/tools v0.1.8 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.28.0 // indirect
diff --git a/kernel/go.sum b/kernel/go.sum
index 141e742bf..05325641d 100644
--- a/kernel/go.sum
+++ b/kernel/go.sum
@@ -419,10 +419,12 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/siyuan-note/dejavu v0.0.0-20220615074544-177b5b3df8bb h1:GZyX6WxQzW4LCPmJ1jcAZDPpIEAjFFwucbwCgR60kfU=
-github.com/siyuan-note/dejavu v0.0.0-20220615074544-177b5b3df8bb/go.mod h1:Oa/Y6fvTUCg8h9/t6GNWXiu8T7aQri/ZvyDRygnlikI=
+github.com/siyuan-note/dejavu v0.0.0-20220615164826-201b6516adf3 h1:pWPKLb4bpv5Cj8jErsuVKAvXqmudz+0XVfVWZjVxGJc=
+github.com/siyuan-note/dejavu v0.0.0-20220615164826-201b6516adf3/go.mod h1:0XMLF+6gtwqr3ZJTk3nZmNbmQ4xNdaoP9RXKDR2ggkw=
github.com/siyuan-note/encryption v0.0.0-20220612074546-f1dd94fe8676 h1:QB9TjJQFhXhZ6dAtPpY02DlzHAQm1C+WqZq6OadG8mI=
github.com/siyuan-note/encryption v0.0.0-20220612074546-f1dd94fe8676/go.mod h1:H8fyqqAbp9XreANjeSbc72zEdFfKTXYN34tc1TjZwtw=
+github.com/siyuan-note/filelock v0.0.0-20220615164210-064676f342aa h1:6bXZdsdA5EU1NUChdFV4EwH8nvYUis0H1TxwgadLM38=
+github.com/siyuan-note/filelock v0.0.0-20220615164210-064676f342aa/go.mod h1:c4vwvWRrnfa75OXiO21K/76BFRJ4cFITKNoVs5lFdwc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
@@ -472,7 +474,11 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
+go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -649,8 +655,8 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s=
-golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA=
+golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20180302201248-b7ef84aaf62a/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/kernel/model/assets.go b/kernel/model/assets.go
index 15479fcda..4423b4848 100644
--- a/kernel/model/assets.go
+++ b/kernel/model/assets.go
@@ -35,7 +35,7 @@ import (
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/gabriel-vasile/mimetype"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/search"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
@@ -671,7 +671,7 @@ func copyDocAssetsToDataAssets(boxID, parentDocPath string) {
}
func copyAssetsToDataAssets(rootPath string) {
- filesys.ReleaseFileLocks(rootPath)
+ filelock.ReleaseFileLocks(rootPath)
var assetsDirPaths []string
filepath.Walk(rootPath, func(path string, info fs.FileInfo, err error) error {
diff --git a/kernel/model/backup.go b/kernel/model/backup.go
index d11fb8688..22705cbed 100644
--- a/kernel/model/backup.go
+++ b/kernel/model/backup.go
@@ -33,7 +33,7 @@ import (
"github.com/88250/gulu"
"github.com/dustin/go-humanize"
"github.com/siyuan-note/encryption"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -145,7 +145,10 @@ func RecoverLocalBackup() (err error) {
writingDataLock.Lock()
defer writingDataLock.Unlock()
- filesys.ReleaseAllFileLocks()
+ err = filelock.ReleaseAllFileLocks()
+ if nil != err {
+ return
+ }
sql.WaitForWritingDatabase()
CloseWatchAssets()
@@ -256,7 +259,10 @@ func CreateLocalBackup() (err error) {
defer writingDataLock.Unlock()
WaitForWritingFiles()
sql.WaitForWritingDatabase()
- filesys.ReleaseAllFileLocks()
+ err = filelock.ReleaseAllFileLocks()
+ if nil != err {
+ return
+ }
util.LogInfof("creating backup...")
start := time.Now()
@@ -294,7 +300,7 @@ func CreateLocalBackup() (err error) {
util.LogErrorf("marshal backup conf.json failed: %s", err)
} else {
confPath := filepath.Join(newBackupDir, "conf.json")
- if err = os.WriteFile(confPath, data, 0644); nil != err {
+ if err = gulu.File.WriteFileSafer(confPath, data, 0644); nil != err {
util.LogErrorf("write backup conf.json [%s] failed: %s", confPath, err)
}
}
@@ -432,13 +438,7 @@ func encryptDataDir(passwd string) (encryptedDataDir string, err error) {
return io.EOF
}
- f, err0 := os.Create(p)
- if nil != err0 {
- util.LogErrorf("create file [%s] failed: %s", p, err0)
- err = err0
- return io.EOF
- }
- data, err0 := os.ReadFile(path)
+ data, err0 := filelock.NoLockFileRead(path)
if nil != err0 {
util.LogErrorf("read file [%s] failed: %s", path, err0)
err = err0
@@ -450,16 +450,12 @@ func encryptDataDir(passwd string) (encryptedDataDir string, err error) {
err = errors.New("encrypt file failed")
return io.EOF
}
- if _, err0 = f.Write(data); nil != err0 {
+
+ if err0 = gulu.File.WriteFileSafer(p, data, 0644); nil != err0 {
util.LogErrorf("write file [%s] failed: %s", p, err0)
err = err0
return io.EOF
}
- if err0 = f.Close(); nil != err0 {
- util.LogErrorf("close file [%s] failed: %s", p, err0)
- err = err0
- return io.EOF
- }
fi, err0 := os.Stat(path)
if nil != err0 {
@@ -584,7 +580,7 @@ func decryptDataDir(passwd string) (decryptedDataDir string, err error) {
err = errors.New(Conf.Language(40))
return io.EOF
}
- if err0 = os.WriteFile(plainP, data, 0644); nil != err0 {
+ if err0 = gulu.File.WriteFileSafer(plainP, data, 0644); nil != err0 {
util.LogErrorf("write file [%s] failed: %s", plainP, err0)
err = err0
return io.EOF
diff --git a/kernel/model/box.go b/kernel/model/box.go
index 735fd474d..c4c7a94bd 100644
--- a/kernel/model/box.go
+++ b/kernel/model/box.go
@@ -32,8 +32,8 @@ import (
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/facette/natsort"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/conf"
- "github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -85,14 +85,14 @@ func ListNotebooks() (ret []*Box, err error) {
boxConfPath := filepath.Join(util.DataDir, dir.Name(), ".siyuan", "conf.json")
if !gulu.File.IsExist(boxConfPath) {
if isUserGuide(dir.Name()) {
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
os.RemoveAll(filepath.Join(util.DataDir, dir.Name()))
util.LogWarnf("not found user guid box conf [%s], removed it", boxConfPath)
continue
}
util.LogWarnf("not found box conf [%s], recreate it", boxConfPath)
} else {
- data, readErr := filesys.NoLockFileRead(boxConfPath)
+ data, readErr := filelock.NoLockFileRead(boxConfPath)
if nil != readErr {
util.LogErrorf("read box conf [%s] failed: %s", boxConfPath, readErr)
continue
@@ -152,7 +152,7 @@ func (box *Box) GetConf() (ret *conf.BoxConf) {
return
}
- data, err := filesys.LockFileRead(confPath)
+ data, err := filelock.LockFileRead(confPath)
if nil != err {
util.LogErrorf("read box conf [%s] failed: %s", confPath, err)
return
@@ -173,7 +173,7 @@ func (box *Box) SaveConf(conf *conf.BoxConf) {
return
}
- oldData, err := filesys.NoLockFileRead(confPath)
+ oldData, err := filelock.NoLockFileRead(confPath)
if nil != err {
box.saveConf0(newData)
return
@@ -191,7 +191,7 @@ func (box *Box) saveConf0(data []byte) {
if err := os.MkdirAll(filepath.Join(util.DataDir, box.ID, ".siyuan"), 0755); nil != err {
util.LogErrorf("save box conf [%s] failed: %s", confPath, err)
}
- if err := filesys.LockFileWrite(confPath, data); nil != err {
+ if err := filelock.LockFileWrite(confPath, data); nil != err {
util.LogErrorf("save box conf [%s] failed: %s", confPath, err)
}
}
@@ -279,7 +279,7 @@ func (box *Box) Move(oldPath, newPath string) error {
boxLocalPath := filepath.Join(util.DataDir, box.ID)
fromPath := filepath.Join(boxLocalPath, oldPath)
toPath := filepath.Join(boxLocalPath, newPath)
- filesys.ReleaseFileLocks(fromPath)
+ filelock.ReleaseFileLocks(fromPath)
if err := os.Rename(fromPath, toPath); nil != err {
msg := fmt.Sprintf(Conf.Language(5), box.Name, fromPath, err)
util.LogErrorf("move [path=%s] in box [%s] failed: %s", fromPath, box.Name, err)
@@ -299,7 +299,7 @@ func (box *Box) Move(oldPath, newPath string) error {
func (box *Box) Remove(path string) error {
boxLocalPath := filepath.Join(util.DataDir, box.ID)
filePath := filepath.Join(boxLocalPath, path)
- filesys.ReleaseFileLocks(filePath)
+ filelock.ReleaseFileLocks(filePath)
if err := os.RemoveAll(filePath); nil != err {
msg := fmt.Sprintf(Conf.Language(7), box.Name, path, err)
util.LogErrorf("remove [path=%s] in box [%s] failed: %s", path, box.ID, err)
@@ -317,7 +317,7 @@ func (box *Box) Unindex() {
sql.RemoveBoxHash(tx, box.ID)
sql.DeleteByBoxTx(tx, box.ID)
sql.CommitTx(tx)
- filesys.ReleaseFileLocks(filepath.Join(util.DataDir, box.ID))
+ filelock.ReleaseFileLocks(filepath.Join(util.DataDir, box.ID))
treenode.RemoveBlockTreesByBoxID(box.ID)
}
@@ -528,5 +528,5 @@ func LockFileByBlockID(id string) (locked bool, filePath string) {
if !gulu.File.IsExist(p) {
return true, ""
}
- return nil == filesys.LockFile(p), p
+ return nil == filelock.LockFile(p), p
}
diff --git a/kernel/model/conf.go b/kernel/model/conf.go
index 83550b5a7..c2cf8352f 100644
--- a/kernel/model/conf.go
+++ b/kernel/model/conf.go
@@ -34,8 +34,8 @@ import (
"github.com/88250/lute"
humanize "github.com/dustin/go-humanize"
"github.com/getsentry/sentry-go"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/conf"
- "github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -386,7 +386,7 @@ func (conf *AppConf) Save() {
newData, _ := gulu.JSON.MarshalIndentJSON(Conf, "", " ")
confPath := filepath.Join(util.ConfDir, "conf.json")
- oldData, err := filesys.NoLockFileRead(confPath)
+ oldData, err := filelock.NoLockFileRead(confPath)
if nil != err {
conf.save0(newData)
return
@@ -401,7 +401,7 @@ func (conf *AppConf) Save() {
func (conf *AppConf) save0(data []byte) {
confPath := filepath.Join(util.ConfDir, "conf.json")
- if err := filesys.LockFileWrite(confPath, data); nil != err {
+ if err := filelock.LockFileWrite(confPath, data); nil != err {
util.LogFatalf("write conf [%s] failed: %s", confPath, err)
}
}
diff --git a/kernel/model/export.go b/kernel/model/export.go
index 178744472..fca9dc3f6 100644
--- a/kernel/model/export.go
+++ b/kernel/model/export.go
@@ -40,7 +40,7 @@ import (
"github.com/88250/pdfcpu/pkg/pdfcpu"
"github.com/emirpasic/gods/sets/hashset"
"github.com/emirpasic/gods/stacks/linkedliststack"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -112,7 +112,10 @@ func exportData(exportFolder string) (err error) {
return
}
- filesys.ReleaseAllFileLocks()
+ err = filelock.ReleaseAllFileLocks()
+ if nil != err {
+ return
+ }
data := filepath.Join(util.WorkspaceDir, "data")
if err = stableCopy(data, exportFolder); nil != err {
@@ -659,7 +662,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
// 按文件夹结构复制选择的树
for _, tree := range trees {
readPath := filepath.Join(util.DataDir, tree.Box, tree.Path)
- data, readErr := filesys.NoLockFileRead(readPath)
+ data, readErr := filelock.NoLockFileRead(readPath)
if nil != readErr {
util.LogErrorf("read file [%s] failed: %s", readPath, readErr)
continue
@@ -681,7 +684,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
// 引用树放在导出文件夹根路径下
for treeID, tree := range refTrees {
readPath := filepath.Join(util.DataDir, tree.Box, tree.Path)
- data, readErr := filesys.NoLockFileRead(readPath)
+ data, readErr := filelock.NoLockFileRead(readPath)
if nil != readErr {
util.LogErrorf("read file [%s] failed: %s", readPath, readErr)
continue
diff --git a/kernel/model/file.go b/kernel/model/file.go
index f8f0e84ac..9e21e3245 100644
--- a/kernel/model/file.go
+++ b/kernel/model/file.go
@@ -39,6 +39,7 @@ import (
"github.com/dustin/go-humanize"
"github.com/facette/natsort"
"github.com/gin-gonic/gin"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/search"
@@ -133,9 +134,9 @@ func (box *Box) docIAL(p string) (ret map[string]string) {
filePath := filepath.Join(util.DataDir, box.ID, p)
- data, err := filesys.NoLockFileRead(filePath)
+ data, err := filelock.NoLockFileRead(filePath)
if util.IsCorruptedSYData(data) {
- filesys.UnlockFile(filePath)
+ filelock.UnlockFile(filePath)
if removeErr := os.RemoveAll(filePath); nil == removeErr {
util.LogInfof("removed corrupted data file [path=%s, length=%d]", filePath, len(data))
} else {
@@ -1043,9 +1044,9 @@ func MoveDoc(fromBoxID, fromPath, toBoxID, toPath string) (newPath string, err e
} else {
absFromPath := filepath.Join(util.DataDir, fromBoxID, fromFolder)
absToPath := filepath.Join(util.DataDir, toBoxID, newFolder)
- filesys.ReleaseFileLocks(absFromPath)
+ filelock.ReleaseFileLocks(absFromPath)
if gulu.File.IsExist(absToPath) {
- filesys.ReleaseFileLocks(absToPath)
+ filelock.ReleaseFileLocks(absToPath)
os.RemoveAll(absToPath)
}
if err = os.Rename(absFromPath, absToPath); nil != err {
@@ -1073,7 +1074,7 @@ func MoveDoc(fromBoxID, fromPath, toBoxID, toPath string) (newPath string, err e
} else {
absFromPath := filepath.Join(util.DataDir, fromBoxID, fromPath)
absToPath := filepath.Join(util.DataDir, toBoxID, newPath)
- filesys.ReleaseFileLocks(absFromPath)
+ filelock.ReleaseFileLocks(absFromPath)
if err = os.Rename(absFromPath, absToPath); nil != err {
msg := fmt.Sprintf(Conf.Language(5), fromBox.Name, fromPath, err)
util.LogErrorf("move [path=%s] in box [%s] failed: %s", fromPath, fromBoxID, err)
@@ -1118,7 +1119,7 @@ func RemoveDoc(boxID, p string) (err error) {
historyPath := filepath.Join(historyDir, boxID, p)
absPath := filepath.Join(util.DataDir, boxID, p)
- filesys.ReleaseFileLocks(absPath)
+ filelock.ReleaseFileLocks(absPath)
if err = gulu.File.Copy(absPath, historyPath); nil != err {
return errors.New(fmt.Sprintf(Conf.Language(70), box.Name, absPath, err))
}
@@ -1375,7 +1376,7 @@ func moveSorts(rootID, fromBox, toBox string) {
fromConfPath := filepath.Join(util.DataDir, fromBox, ".siyuan", "sort.json")
fromFullSortIDs := map[string]int{}
if gulu.File.IsExist(fromConfPath) {
- data, err := filesys.LockFileRead(fromConfPath)
+ data, err := filelock.LockFileRead(fromConfPath)
if nil != err {
util.LogErrorf("read sort conf failed: %s", err)
return
@@ -1392,7 +1393,7 @@ func moveSorts(rootID, fromBox, toBox string) {
toConfPath := filepath.Join(util.DataDir, toBox, ".siyuan", "sort.json")
toFullSortIDs := map[string]int{}
if gulu.File.IsExist(toConfPath) {
- data, err := filesys.LockFileRead(toConfPath)
+ data, err := filelock.LockFileRead(toConfPath)
if nil != err {
util.LogErrorf("read sort conf failed: %s", err)
return
@@ -1413,7 +1414,7 @@ func moveSorts(rootID, fromBox, toBox string) {
util.LogErrorf("marshal sort conf failed: %s", err)
return
}
- if err = filesys.LockFileWrite(toConfPath, data); nil != err {
+ if err = filelock.LockFileWrite(toConfPath, data); nil != err {
util.LogErrorf("write sort conf failed: %s", err)
return
}
@@ -1490,7 +1491,7 @@ func ChangeFileTreeSort(boxID string, paths []string) {
fullSortIDs := map[string]int{}
var data []byte
if gulu.File.IsExist(confPath) {
- data, err = filesys.LockFileRead(confPath)
+ data, err = filelock.LockFileRead(confPath)
if nil != err {
util.LogErrorf("read sort conf failed: %s", err)
return
@@ -1510,7 +1511,7 @@ func ChangeFileTreeSort(boxID string, paths []string) {
util.LogErrorf("marshal sort conf failed: %s", err)
return
}
- if err = filesys.LockFileWrite(confPath, data); nil != err {
+ if err = filelock.LockFileWrite(confPath, data); nil != err {
util.LogErrorf("write sort conf failed: %s", err)
return
}
@@ -1524,7 +1525,7 @@ func (box *Box) fillSort(files *[]*File) {
return
}
- data, err := filesys.LockFileRead(confPath)
+ data, err := filelock.LockFileRead(confPath)
if nil != err {
util.LogErrorf("read sort conf failed: %s", err)
return
@@ -1571,7 +1572,7 @@ func (box *Box) removeSort(rootID, path string) {
return
}
- data, err := filesys.LockFileRead(confPath)
+ data, err := filelock.LockFileRead(confPath)
if nil != err {
util.LogErrorf("read sort conf failed: %s", err)
return
@@ -1592,7 +1593,7 @@ func (box *Box) removeSort(rootID, path string) {
util.LogErrorf("marshal sort conf failed: %s", err)
return
}
- if err = filesys.LockFileWrite(confPath, data); nil != err {
+ if err = filelock.LockFileWrite(confPath, data); nil != err {
util.LogErrorf("write sort conf failed: %s", err)
return
}
@@ -1601,8 +1602,8 @@ func (box *Box) removeSort(rootID, path string) {
func ServeFile(c *gin.Context, filePath string) (err error) {
WaitForWritingFiles()
- if filesys.IsLocked(filePath) {
- if err = filesys.UnlockFile(filePath); nil == err {
+ if filelock.IsLocked(filePath) {
+ if err = filelock.UnlockFile(filePath); nil == err {
util.LogInfof("unlocked file [%s]", filePath)
} else {
msg := fmt.Sprintf("unlock file [%s] failed: %s", filePath, err)
diff --git a/kernel/model/format.go b/kernel/model/format.go
index 126ea6e36..27a676f67 100644
--- a/kernel/model/format.go
+++ b/kernel/model/format.go
@@ -25,7 +25,7 @@ import (
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/88250/lute/render"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -102,7 +102,7 @@ func generateFormatHistory(tree *parse.Tree) {
}
var data []byte
- if data, err = filesys.NoLockFileRead(filepath.Join(util.DataDir, tree.Box, tree.Path)); err != nil {
+ if data, err = filelock.NoLockFileRead(filepath.Join(util.DataDir, tree.Box, tree.Path)); err != nil {
util.LogErrorf("generate history failed: %s", err)
return
}
diff --git a/kernel/model/history.go b/kernel/model/history.go
index 320f7cc93..53b3cd91e 100644
--- a/kernel/model/history.go
+++ b/kernel/model/history.go
@@ -28,8 +28,8 @@ import (
"github.com/88250/gulu"
"github.com/88250/protyle"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/conf"
- "github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -133,7 +133,7 @@ func GetDocHistoryContent(historyPath string) (content string, err error) {
return
}
- data, err := filesys.NoLockFileRead(historyPath)
+ data, err := filelock.NoLockFileRead(historyPath)
if nil != err {
util.LogErrorf("read file [%s] failed: %s", historyPath, err)
return
@@ -162,7 +162,7 @@ func RollbackDocHistory(boxID, historyPath string) (err error) {
baseName := filepath.Base(historyPath)
id := strings.TrimSuffix(baseName, ".sy")
- filesys.ReleaseFileLocks(filepath.Join(util.DataDir, boxID))
+ filelock.ReleaseFileLocks(filepath.Join(util.DataDir, boxID))
workingDoc := treenode.GetBlockTree(id)
if nil != workingDoc {
if err = os.RemoveAll(filepath.Join(util.DataDir, boxID, workingDoc.Path)); nil != err {
@@ -285,7 +285,7 @@ func GetDocHistory(boxID string) (ret []*History, err error) {
return nil
}
- data, err := filesys.NoLockFileRead(path)
+ data, err := filelock.NoLockFileRead(path)
if nil != err {
util.LogErrorf("read file [%s] failed: %s", path, err)
return nil
@@ -489,7 +489,7 @@ func (box *Box) generateDocHistory0() {
}
var data []byte
- if data, err = filesys.NoLockFileRead(file); err != nil {
+ if data, err = filelock.NoLockFileRead(file); err != nil {
util.LogErrorf("generate history failed: %s", err)
return
}
diff --git a/kernel/model/import.go b/kernel/model/import.go
index a5cfef20d..e08dc59a4 100644
--- a/kernel/model/import.go
+++ b/kernel/model/import.go
@@ -39,6 +39,7 @@ import (
"github.com/88250/lute/parse"
"github.com/88250/protyle"
"github.com/mattn/go-zglob"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
@@ -253,7 +254,7 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
writingDataLock.Lock()
defer writingDataLock.Unlock()
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
var baseTargetPath string
if "/" == toPath {
@@ -330,7 +331,7 @@ func ImportData(zipPath string) (err error) {
writingDataLock.Lock()
defer writingDataLock.Unlock()
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
tmpDataPath := filepath.Dir(filepath.Dir(confPath))
if err = stableCopy(tmpDataPath, util.DataDir); nil != err {
util.LogErrorf("copy data dir from [%s] to [%s] failed: %s", tmpDataPath, util.DataDir, err)
diff --git a/kernel/model/index.go b/kernel/model/index.go
index 8dea1154b..60c6ef7e1 100644
--- a/kernel/model/index.go
+++ b/kernel/model/index.go
@@ -31,6 +31,7 @@ import (
"github.com/88250/lute/parse"
"github.com/dustin/go-humanize"
"github.com/emirpasic/gods/sets/hashset"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
@@ -69,7 +70,7 @@ func (box *Box) BootIndex() {
// 缓存块树
treenode.IndexBlockTree(tree)
if 1 < i && 0 == i%64 {
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
}
i++
}
@@ -130,7 +131,7 @@ func (box *Box) Index(fullRebuildIndex bool) (treeCount int, treeSize int64) {
idHashMap[tree.ID] = tree.Hash
if 1 < i && 0 == i%64 {
util.PushEndlessProgress(fmt.Sprintf(Conf.Language(88), i, len(files)-i))
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
}
i++
}
@@ -210,7 +211,7 @@ func (box *Box) Index(fullRebuildIndex bool) (treeCount int, treeSize int64) {
}
if 1 < i && 0 == i%64 {
util.PushEndlessProgress(fmt.Sprintf("["+box.Name+"] "+Conf.Language(53), i, treeCount-i))
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
}
i++
}
@@ -348,7 +349,7 @@ func IndexRefs() {
}
if 1 < i && 0 == i%64 {
util.PushEndlessProgress(fmt.Sprintf(Conf.Language(55), i))
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
}
i++
}
diff --git a/kernel/model/mount.go b/kernel/model/mount.go
index dc288493a..ad2f82ac8 100644
--- a/kernel/model/mount.go
+++ b/kernel/model/mount.go
@@ -27,7 +27,7 @@ import (
"github.com/88250/gulu"
"github.com/88250/lute/ast"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -87,7 +87,7 @@ func RemoveBox(boxID string) (err error) {
return errors.New(fmt.Sprintf("can not remove [%s] caused by it is not a dir", boxID))
}
- filesys.ReleaseFileLocks(localPath)
+ filelock.ReleaseFileLocks(localPath)
if !isUserGuide(boxID) {
var historyDir string
historyDir, err = util.GetHistoryDir("delete")
diff --git a/kernel/model/repository.go b/kernel/model/repository.go
index b9d1f5458..a327287bb 100644
--- a/kernel/model/repository.go
+++ b/kernel/model/repository.go
@@ -27,7 +27,7 @@ import (
"github.com/siyuan-note/dejavu"
"github.com/siyuan-note/dejavu/entity"
"github.com/siyuan-note/encryption"
- "github.com/siyuan-note/siyuan/kernel/filesys"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/util"
)
@@ -136,7 +136,7 @@ func CheckoutRepo(id string) (err error) {
defer writingDataLock.Unlock()
WaitForWritingFiles()
sql.WaitForWritingDatabase()
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
CloseWatchAssets()
defer WatchAssets()
@@ -196,8 +196,7 @@ func IndexRepo(memo string) (err error) {
defer writingDataLock.Unlock()
WaitForWritingFiles()
sql.WaitForWritingDatabase()
- filesys.ReleaseAllFileLocks()
-
+ filelock.ReleaseAllFileLocks()
_, err = repo.Index(memo, util.PushEndlessProgress, indexCallbacks)
util.PushClearProgress()
return
diff --git a/kernel/model/sync.go b/kernel/model/sync.go
index 4a3ff5629..e253a7455 100644
--- a/kernel/model/sync.go
+++ b/kernel/model/sync.go
@@ -37,6 +37,7 @@ import (
"github.com/emirpasic/gods/sets/hashset"
"github.com/mattn/go-zglob"
"github.com/siyuan-note/encryption"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
@@ -584,7 +585,7 @@ func syncDir2WorkspaceData(boot bool) (upsertFiles, removeFiles []string, err er
// 2. 将 data 中新增/修改的文件加密后拷贝到 sync 中
func workspaceData2SyncDir() (removeList, upsertList map[string]bool, err error) {
start := time.Now()
- filesys.ReleaseAllFileLocks()
+ filelock.ReleaseAllFileLocks()
passwd := Conf.E2EEPasswd
unchangedDataList, removeList, err := calcUnchangedDataList(passwd)
@@ -653,7 +654,7 @@ func genCloudIndex(localDirPath string, excludes map[string]bool, calcHash bool)
util.LogErrorf("marshal sync cloud index failed: %s", err)
return
}
- if err = os.WriteFile(filepath.Join(localDirPath, "index.json"), data, 0644); nil != err {
+ if err = gulu.File.WriteFileSafer(filepath.Join(localDirPath, "index.json"), data, 0644); nil != err {
util.LogErrorf("write sync cloud index failed: %s", err)
return
}
@@ -747,7 +748,7 @@ func recoverSyncData(metaPath, indexPath string, modified map[string]bool) (decr
}
}
- if err0 = os.WriteFile(plainP, data, 0644); nil != err0 {
+ if err0 = gulu.File.WriteFileSafer(plainP, data, 0644); nil != err0 {
util.LogErrorf("write file [%s] failed: %s", plainP, err0)
err = err0
return io.EOF
@@ -820,7 +821,7 @@ func prepareSyncData(passwd string, unchangedDataList map[string]bool) (encrypte
return io.EOF
}
- data, err0 := filesys.NoLockFileRead(path)
+ data, err0 := filelock.NoLockFileRead(path)
if nil != err0 {
util.LogErrorf("read file [%s] failed: %s", path, err0)
err = err0
@@ -835,7 +836,7 @@ func prepareSyncData(passwd string, unchangedDataList map[string]bool) (encrypte
}
}
- err0 = os.WriteFile(p, data, 0644)
+ err0 = gulu.File.WriteFileSafer(p, data, 0644)
if nil != err0 {
util.LogErrorf("write file [%s] failed: %s", p, err0)
err = err0
@@ -894,7 +895,7 @@ func prepareSyncData(passwd string, unchangedDataList map[string]bool) (encrypte
util.LogErrorf("encrypt file failed: %s", err)
return
}
- if err = os.WriteFile(filepath.Join(encryptedDataDir, pathJSON), data, 0644); nil != err {
+ if err = gulu.File.WriteFileSafer(filepath.Join(encryptedDataDir, pathJSON), data, 0644); nil != err {
return
}
return
@@ -1077,13 +1078,13 @@ func getWorkspaceDataConf() (conf *filesys.DataConf, err error) {
if !gulu.File.IsExist(confPath) {
os.MkdirAll(filepath.Dir(confPath), 0755)
data, _ := gulu.JSON.MarshalIndentJSON(conf, "", " ")
- if err = os.WriteFile(confPath, data, 0644); nil != err {
+ if err = filelock.NoLockFileWrite(confPath, data); nil != err {
util.LogErrorf("save sync conf [%s] failed: %s", confPath, err)
}
return
}
- data, err := os.ReadFile(confPath)
+ data, err := filelock.NoLockFileRead(confPath)
if nil != err {
util.LogErrorf("read sync conf [%s] failed: %s", confPath, err)
return
@@ -1106,7 +1107,7 @@ func incLocalSyncVer() {
conf.SyncVer++
data, _ := gulu.JSON.MarshalIndentJSON(conf, "", " ")
confPath := filepath.Join(Conf.Sync.GetSaveDir(), ".siyuan", "conf.json")
- if err = os.WriteFile(confPath, data, 0644); nil != err {
+ if err = gulu.File.WriteFileSafer(confPath, data, 0644); nil != err {
util.LogErrorf("save sync conf [%s] failed: %s", confPath, err)
}
return
@@ -1204,7 +1205,7 @@ func genSyncHistory(now, p string) {
relativePath := strings.TrimPrefix(p, util.DataDir)
historyPath := filepath.Join(historyDir, relativePath)
- filesys.ReleaseFileLocks(p)
+ filelock.ReleaseFileLocks(p)
if err = gulu.File.Copy(p, historyPath); nil != err {
util.LogErrorf("gen sync history failed: %s", err)
return
@@ -1258,7 +1259,7 @@ func getSyncIgnoreList() (ret *hashset.Set) {
ignore := filepath.Join(util.DataDir, ".siyuan", "syncignore")
os.MkdirAll(filepath.Dir(ignore), 0755)
if !gulu.File.IsExist(ignore) {
- if err := os.WriteFile(ignore, nil, 0644); nil != err {
+ if err := gulu.File.WriteFileSafer(ignore, nil, 0644); nil != err {
util.LogErrorf("create syncignore [%s] failed: %s", ignore, err)
return
}
diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go
index 5c32db7e4..9e31de010 100644
--- a/kernel/model/transaction.go
+++ b/kernel/model/transaction.go
@@ -32,8 +32,8 @@ import (
"github.com/88250/lute/parse"
util2 "github.com/88250/lute/util"
"github.com/emirpasic/gods/sets/hashset"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/cache"
- "github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -434,7 +434,7 @@ func (tx *Transaction) doPrependInsert(operation *Operation) (ret *TxErr) {
return &TxErr{code: TxErrCodeBlockNotFound, id: operation.ParentID}
}
tree, err := tx.loadTree(block.ID)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: block.ID}
}
if nil != err {
@@ -522,7 +522,7 @@ func (tx *Transaction) doAppendInsert(operation *Operation) (ret *TxErr) {
return &TxErr{code: TxErrCodeBlockNotFound, id: operation.ParentID}
}
tree, err := tx.loadTree(block.ID)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: block.ID}
}
if nil != err {
@@ -723,7 +723,7 @@ func (tx *Transaction) doLargeInsert() (ret *TxErr) {
}
id := parentBlock.ID
tree, err := tx.loadTree(id)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: id}
}
if nil != err {
@@ -784,7 +784,7 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) {
var err error
id := operation.ID
tree, err := tx.loadTree(id)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: id}
}
if ErrBlockNotFound == err {
@@ -835,7 +835,7 @@ func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
}
}
tree, err := tx.loadTree(block.ID)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: block.ID}
}
if nil != err {
@@ -969,7 +969,7 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
id := operation.ID
tree, err := tx.loadTree(id)
- if filesys.ErrUnableLockFile == err {
+ if errors.Is(err, filelock.ErrUnableLockFile) {
return &TxErr{code: TxErrCodeUnableLockFile, msg: err.Error(), id: id}
}
if nil != err {
diff --git a/kernel/model/tree.go b/kernel/model/tree.go
index 445bc0070..a247e6fdc 100644
--- a/kernel/model/tree.go
+++ b/kernel/model/tree.go
@@ -24,6 +24,7 @@ import (
"github.com/88250/lute/parse"
"github.com/88250/protyle"
+ "github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
@@ -40,7 +41,7 @@ func loadTrees(localPath string) (ret []*parse.Tree) {
return nil
}
- data, err := filesys.NoLockFileRead(path)
+ data, err := filelock.NoLockFileRead(path)
if nil != err {
util.LogErrorf("get data [path=%s] failed: %s", path, err)
return nil
diff --git a/kernel/util/file.go b/kernel/util/file.go
index c68b4dd89..409fabd5c 100644
--- a/kernel/util/file.go
+++ b/kernel/util/file.go
@@ -38,24 +38,6 @@ func IsEmptyDir(p string) bool {
return 1 > len(files)
}
-func IsValidJSON(p string) bool {
- if !gulu.File.IsExist(p) {
- return false
- }
- data, err := os.ReadFile(p)
- if nil != err {
- LogErrorf("read json file [%s] failed: %s", p, err)
- return false
- }
-
- json := map[string]interface{}{}
- if err = gulu.JSON.UnmarshalJSON(data, &json); nil != err {
- LogErrorf("parse json file [%s] failed: %s", p, err)
- return false
- }
- return true
-}
-
func RemoveID(name string) string {
ext := path.Ext(name)
name = strings.TrimSuffix(name, ext)