Bump reva to pull in the latest fixes
This commit is contained in:
+4
-4
@@ -45,7 +45,7 @@ import (
|
||||
|
||||
var tracer trace.Tracer
|
||||
|
||||
const RevisionsDir = ".oc-nodes"
|
||||
const MetadataDir = ".oc-nodes"
|
||||
|
||||
var _spaceTypePersonal = "personal"
|
||||
var _spaceTypeProject = "project"
|
||||
@@ -288,7 +288,7 @@ func (lu *Lookup) InternalPath(spaceID, nodeID string) string {
|
||||
if len(spaceRoot) == 0 {
|
||||
return ""
|
||||
}
|
||||
return filepath.Join(spaceRoot, RevisionsDir, Pathify(nodeID, 4, 2))
|
||||
return filepath.Join(spaceRoot, MetadataDir, Pathify(nodeID, 4, 2))
|
||||
}
|
||||
|
||||
path, _ := lu.IDCache.Get(context.Background(), spaceID, nodeID)
|
||||
@@ -303,7 +303,7 @@ func (lu *Lookup) VersionPath(spaceID, nodeID, version string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return filepath.Join(spaceRoot, RevisionsDir, Pathify(nodeID, 4, 2)+node.RevisionIDDelimiter+version)
|
||||
return filepath.Join(spaceRoot, MetadataDir, Pathify(nodeID, 4, 2)+node.RevisionIDDelimiter+version)
|
||||
}
|
||||
|
||||
// VersionPath returns the "current" path of the node
|
||||
@@ -313,7 +313,7 @@ func (lu *Lookup) CurrentPath(spaceID, nodeID string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return filepath.Join(spaceRoot, RevisionsDir, Pathify(nodeID, 4, 2)+node.CurrentIDDelimiter)
|
||||
return filepath.Join(spaceRoot, MetadataDir, Pathify(nodeID, 4, 2)+node.CurrentIDDelimiter)
|
||||
}
|
||||
|
||||
// refFromCS3 creates a CS3 reference from a set of bytes. This method should remain private
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ func New(m map[string]interface{}, stream events.Stream, log *zerolog.Logger) (s
|
||||
return ""
|
||||
}
|
||||
|
||||
return filepath.Join(spaceRoot, lookup.RevisionsDir, lookup.Pathify(n.GetID(), 4, 2)+".mpk")
|
||||
return filepath.Join(spaceRoot, lookup.MetadataDir)
|
||||
},
|
||||
o.FileMetadataCache), um, o, &timemanager.Manager{})
|
||||
default:
|
||||
|
||||
+39
-1
@@ -24,6 +24,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -63,7 +64,44 @@ func (tp *Tree) CreateRevision(ctx context.Context, n *node.Node, version string
|
||||
vf, err := os.OpenFile(versionPath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600)
|
||||
if err != nil {
|
||||
if os.IsExist(err) {
|
||||
err := os.Remove(versionPath)
|
||||
dir := filepath.Dir(versionPath)
|
||||
base := filepath.Base(versionPath)
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// find revision with highest number
|
||||
highest := 0
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := file.Name()
|
||||
if !strings.HasPrefix(name, base) {
|
||||
continue
|
||||
}
|
||||
ext := strings.TrimPrefix(name, base+".")
|
||||
if ext == "" || ext == base {
|
||||
continue
|
||||
}
|
||||
num, err := strconv.Atoi(ext)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if num > highest {
|
||||
highest = num
|
||||
}
|
||||
}
|
||||
|
||||
// rename existing revision
|
||||
oldNode := node.NewBaseNode(n.SpaceID, n.ID+node.RevisionIDDelimiter+version+"."+strconv.Itoa(highest+1), tp.lookup)
|
||||
err = tp.lookup.MetadataBackend().Rename(revNode, oldNode)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
newPath := versionPath + "." + strconv.Itoa(highest+1)
|
||||
err = os.Rename(versionPath, newPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
+1
-1
@@ -662,7 +662,7 @@ func (t *Tree) isIndex(path string) bool {
|
||||
func (t *Tree) isInternal(path string) bool {
|
||||
return path == t.options.Root ||
|
||||
path == filepath.Join(t.options.Root, "users") ||
|
||||
t.isIndex(path) || strings.Contains(path, lookup.RevisionsDir)
|
||||
t.isIndex(path) || strings.Contains(path, lookup.MetadataDir)
|
||||
}
|
||||
|
||||
func isLockFile(path string) bool {
|
||||
|
||||
Generated
Vendored
+39
-9
@@ -199,15 +199,11 @@ func (b HybridBackend) Set(ctx context.Context, n MetadataNode, key string, val
|
||||
func (b HybridBackend) SetMultiple(ctx context.Context, n MetadataNode, attribs map[string][]byte, acquireLock bool) (err error) {
|
||||
path := n.InternalPath()
|
||||
if acquireLock {
|
||||
err := os.MkdirAll(filepath.Dir(path), 0600)
|
||||
unlock, err := b.Lock(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockedFile, err := lockedfile.OpenFile(b.LockfilePath(n), os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanupLockfile(ctx, lockedFile)
|
||||
defer func() { _ = unlock() }()
|
||||
}
|
||||
|
||||
offloadAttr, err := xattr.Get(path, _metadataOffloadedAttr)
|
||||
@@ -476,17 +472,37 @@ func (b HybridBackend) Rename(oldNode, newNode MetadataNode) error {
|
||||
}
|
||||
|
||||
// MetadataPath returns the path of the file holding the metadata for the given path
|
||||
func (b HybridBackend) MetadataPath(n MetadataNode) string { return b.metadataPathFunc(n) }
|
||||
func (b HybridBackend) MetadataPath(n MetadataNode) string {
|
||||
base := b.metadataPathFunc(n)
|
||||
|
||||
return filepath.Join(base, pathify(n.GetID(), 4, 2)+".mpk")
|
||||
}
|
||||
|
||||
// LockfilePath returns the path of the lock file
|
||||
func (HybridBackend) LockfilePath(n MetadataNode) string { return n.InternalPath() + ".mlock" }
|
||||
func (b HybridBackend) LockfilePath(n MetadataNode) string {
|
||||
base := b.metadataPathFunc(n)
|
||||
|
||||
return filepath.Join(base, "locks", n.GetID()+".mlock")
|
||||
}
|
||||
|
||||
// Lock locks the metadata for the given path
|
||||
func (b HybridBackend) Lock(n MetadataNode) (UnlockFunc, error) {
|
||||
metaLockPath := b.LockfilePath(n)
|
||||
mlock, err := lockedfile.OpenFile(metaLockPath, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
// create the parent directory
|
||||
err = os.MkdirAll(filepath.Dir(metaLockPath), 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mlock, err = lockedfile.OpenFile(metaLockPath, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return func() error {
|
||||
err := mlock.Close()
|
||||
@@ -513,3 +529,17 @@ func (b HybridBackend) cacheKey(n MetadataNode) string {
|
||||
func isOffloadingAttribute(key string) bool {
|
||||
return strings.HasPrefix(key, prefixes.GrantPrefix) || strings.HasPrefix(key, prefixes.MetadataPrefix)
|
||||
}
|
||||
|
||||
func pathify(id string, depth, width int) string {
|
||||
b := strings.Builder{}
|
||||
i := 0
|
||||
for ; i < depth; i++ {
|
||||
if len(id) <= i*width+width {
|
||||
break
|
||||
}
|
||||
b.WriteString(id[i*width : i*width+width])
|
||||
b.WriteRune(filepath.Separator)
|
||||
}
|
||||
b.WriteString(id[i*width:])
|
||||
return b.String()
|
||||
}
|
||||
|
||||
Generated
Vendored
+2
-12
@@ -43,12 +43,6 @@ type MessagePackBackend struct {
|
||||
metaCache cache.FileMetadataCache
|
||||
}
|
||||
|
||||
type readWriteCloseSeekTruncater interface {
|
||||
io.ReadWriteCloser
|
||||
io.Seeker
|
||||
Truncate(int64) error
|
||||
}
|
||||
|
||||
// NewMessagePackBackend returns a new MessagePackBackend instance
|
||||
func NewMessagePackBackend(o cache.Config) MessagePackBackend {
|
||||
return MessagePackBackend{
|
||||
@@ -148,7 +142,6 @@ func (b MessagePackBackend) AllWithLockedSource(ctx context.Context, n MetadataN
|
||||
func (b MessagePackBackend) saveAttributes(ctx context.Context, n MetadataNode, setAttribs map[string][]byte, deleteAttribs []string, acquireLock bool) error {
|
||||
var (
|
||||
err error
|
||||
f readWriteCloseSeekTruncater
|
||||
)
|
||||
ctx, span := tracer.Start(ctx, "saveAttributes")
|
||||
defer func() {
|
||||
@@ -160,16 +153,13 @@ func (b MessagePackBackend) saveAttributes(ctx context.Context, n MetadataNode,
|
||||
span.End()
|
||||
}()
|
||||
|
||||
lockPath := b.LockfilePath(n)
|
||||
metaPath := b.MetadataPath(n)
|
||||
if acquireLock {
|
||||
_, subspan := tracer.Start(ctx, "lockedfile.OpenFile")
|
||||
f, err = lockedfile.OpenFile(lockPath, os.O_RDWR|os.O_CREATE, 0600)
|
||||
subspan.End()
|
||||
unlock, err := b.Lock(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() { _ = unlock() }()
|
||||
}
|
||||
// Read current state
|
||||
_, subspan := tracer.Start(ctx, "os.ReadFile")
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -168,7 +168,7 @@ func (b XattrsBackend) Set(ctx context.Context, n MetadataNode, key string, val
|
||||
func (b XattrsBackend) SetMultiple(ctx context.Context, n MetadataNode, attribs map[string][]byte, acquireLock bool) (err error) {
|
||||
path := n.InternalPath()
|
||||
if acquireLock {
|
||||
err := os.MkdirAll(filepath.Dir(path), 0600)
|
||||
err := os.MkdirAll(filepath.Dir(path), 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Generated
Vendored
+33
-17
@@ -24,13 +24,13 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rogpeppe/go-internal/lockedfile"
|
||||
"github.com/shamaton/msgpack/v2"
|
||||
|
||||
"github.com/opencloud-eu/reva/v2/pkg/appctx"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
@@ -63,32 +63,48 @@ func (tp *Tree) CreateRevision(ctx context.Context, n *node.Node, version string
|
||||
vf, err := os.OpenFile(versionPath, os.O_CREATE|os.O_EXCL, 0600)
|
||||
if err != nil {
|
||||
if os.IsExist(err) {
|
||||
revisionNode := node.NewBaseNode(n.SpaceID, n.ID+node.RevisionIDDelimiter+version, tp.lookup)
|
||||
revisionPath := tp.lookup.MetadataBackend().MetadataPath(revisionNode)
|
||||
b, err := os.ReadFile(revisionPath)
|
||||
dir := filepath.Dir(versionPath)
|
||||
base := filepath.Base(versionPath)
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
m := map[string][]byte{}
|
||||
if err := msgpack.Unmarshal(b, &m); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
bid := m["user.oc.blobid"]
|
||||
if string(bid) != "" {
|
||||
if err := tp.DeleteBlob(&node.Node{
|
||||
BaseNode: *revisionNode,
|
||||
BlobID: string(bid),
|
||||
}); err != nil {
|
||||
return "", err
|
||||
// find revision with highest number
|
||||
highest := 0
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := file.Name()
|
||||
if !strings.HasPrefix(name, base) || strings.HasSuffix(name, ".mpk") {
|
||||
continue
|
||||
}
|
||||
ext := strings.TrimPrefix(name, base+".")
|
||||
if ext == "" || ext == base {
|
||||
continue
|
||||
}
|
||||
num, err := strconv.Atoi(ext)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if num > highest {
|
||||
highest = num
|
||||
}
|
||||
}
|
||||
|
||||
err = os.Remove(versionPath)
|
||||
// rename existing revision
|
||||
oldNode := node.NewBaseNode(n.SpaceID, n.ID+node.RevisionIDDelimiter+version+"."+strconv.Itoa(highest+1), tp.lookup)
|
||||
err = tp.lookup.MetadataBackend().Rename(versionNode, oldNode)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
newPath := versionPath + "." + strconv.Itoa(highest+1)
|
||||
err = os.Rename(versionPath, newPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
vf, err = os.OpenFile(versionPath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0600)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
Reference in New Issue
Block a user