Bump reva to pull in the latest fixes

This commit is contained in:
André Duffeck
2025-03-21 12:29:25 +01:00
parent 5953f950ef
commit 00d49804cf
103 changed files with 14057 additions and 1640 deletions
@@ -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
View File
@@ -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:
@@ -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
View File
@@ -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 {
@@ -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()
}
@@ -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")
@@ -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
}
@@ -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