diff --git a/pkg/storage/fs/nextcloud/nextcloud_test.go b/pkg/storage/fs/nextcloud/nextcloud_test.go index 8f660bf6697..6dd00aa0b62 100644 --- a/pkg/storage/fs/nextcloud/nextcloud_test.go +++ b/pkg/storage/fs/nextcloud/nextcloud_test.go @@ -1023,7 +1023,7 @@ var _ = Describe("Nextcloud", func() { mock, teardown := nextcloud.TestingHTTPClient(h) defer teardown() nc.SetHTTPClient(mock) - maxBytes, maxFiles, err := nc.GetQuota(ctx) + maxBytes, maxFiles, err := nc.GetQuota(ctx, nil) Expect(err).ToNot(HaveOccurred()) Expect(maxBytes).To(Equal(uint64(456))) Expect(maxFiles).To(Equal(uint64(123))) diff --git a/pkg/storage/utils/decomposedfs/decomposedfs.go b/pkg/storage/utils/decomposedfs/decomposedfs.go index e88f4fe91b9..c1fffd27a0a 100644 --- a/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -295,7 +295,7 @@ func (fs *Decomposedfs) CreateDir(ctx context.Context, ref *provider.Reference) err = fs.tp.CreateDir(ctx, n) - if fs.o.TreeTimeAccounting { + if fs.o.TreeTimeAccounting || fs.o.TreeSizeAccounting { nodePath := n.InternalPath() // mark the home node as the end of propagation if err = xattr.Set(nodePath, xattrs.PropagationAttr, []byte("1")); err != nil { diff --git a/pkg/storage/utils/decomposedfs/lookup.go b/pkg/storage/utils/decomposedfs/lookup.go index a5285217de9..94379b3012c 100644 --- a/pkg/storage/utils/decomposedfs/lookup.go +++ b/pkg/storage/utils/decomposedfs/lookup.go @@ -49,22 +49,22 @@ func (lu *Lookup) NodeFromResource(ctx context.Context, ref *provider.Reference) if err != nil { return nil, err } - n := spaceRoot - p := filepath.Clean(ref.Path) - if p != "." { - // walk the relative path - n, err = lu.WalkPath(ctx, n, p, false, func(ctx context.Context, n *node.Node) error { - return nil - }) - if err != nil { - return nil, err + // is this a relative reference? + if ref.Path != "" { + p := filepath.Clean(ref.Path) + if p != "." { + // walk the relative path + n, err = lu.WalkPath(ctx, n, p, false, func(ctx context.Context, n *node.Node) error { + return nil + }) + if err != nil { + return nil, err + } } // use reference id as space root for relative references n.SpaceRoot = spaceRoot - return n, nil } - return n, nil } diff --git a/pkg/storage/utils/decomposedfs/node/node.go b/pkg/storage/utils/decomposedfs/node/node.go index a375e79c631..bfac1410d7e 100644 --- a/pkg/storage/utils/decomposedfs/node/node.go +++ b/pkg/storage/utils/decomposedfs/node/node.go @@ -240,9 +240,10 @@ func (n *Node) Child(ctx context.Context, name string) (*Node, error) { if err != nil { if os.IsNotExist(err) || isNotDir(err) { c := &Node{ - lu: n.lu, - ParentID: n.ID, - Name: name, + lu: n.lu, + ParentID: n.ID, + Name: name, + SpaceRoot: n.SpaceRoot, } return c, nil // if the file does not exist we return a node that has Exists = false } @@ -269,8 +270,9 @@ func (n *Node) Parent() (p *Node, err error) { return nil, fmt.Errorf("Decomposedfs: root has no parent") } p = &Node{ - lu: n.lu, - ID: n.ParentID, + lu: n.lu, + ID: n.ParentID, + SpaceRoot: n.SpaceRoot, } parentPath := n.lu.InternalPath(n.ParentID) @@ -612,9 +614,12 @@ func (n *Node) AsResourceInfo(ctx context.Context, rp *provider.ResourcePermissi if n.SpaceRoot != nil { quotaPath = n.SpaceRoot.InternalPath() } else { - sublog.Error().Err(err).Msg("error determining the space root node for quota") + root, err := n.lu.HomeOrRootNode(ctx) + if err != nil { + sublog.Error().Err(err).Msg("error determining the space root node for quota") + } + quotaPath = root.InternalPath() } - quotaPath = n.InternalPath() readQuotaIntoOpaque(ctx, quotaPath, ri) } diff --git a/pkg/storage/utils/decomposedfs/node/permissions.go b/pkg/storage/utils/decomposedfs/node/permissions.go index 05a1282e864..9bd6923c5f1 100644 --- a/pkg/storage/utils/decomposedfs/node/permissions.go +++ b/pkg/storage/utils/decomposedfs/node/permissions.go @@ -287,7 +287,13 @@ func (p *Permissions) getUserAndPermissions(ctx context.Context, n *Node) (*user func isNoData(err error) bool { if xerr, ok := err.(*xattr.Error); ok { if serr, ok2 := xerr.Err.(syscall.Errno); ok2 { - return serr == syscall.ENODATA + switch serr { + case syscall.ENODATA: + case syscall.ENOATTR: + return true + default: + return false + } } } return false diff --git a/pkg/storage/utils/decomposedfs/spaces.go b/pkg/storage/utils/decomposedfs/spaces.go index 7bc82296c63..473fdabab66 100644 --- a/pkg/storage/utils/decomposedfs/spaces.go +++ b/pkg/storage/utils/decomposedfs/spaces.go @@ -66,6 +66,14 @@ func (fs *Decomposedfs) CreateStorageSpace(ctx context.Context, req *provider.Cr return nil, err } + // always enable propagation on the storage space root + nodePath := n.InternalPath() + // mark the space root node as the end of propagation + if err = xattr.Set(nodePath, xattrs.PropagationAttr, []byte("1")); err != nil { + appctx.GetLogger(ctx).Error().Err(err).Interface("node", n).Msg("could not mark node to propagate") + return nil, err + } + if err := fs.createHiddenSpaceFolder(ctx, n); err != nil { return nil, err } diff --git a/pkg/storage/utils/decomposedfs/tree/tree.go b/pkg/storage/utils/decomposedfs/tree/tree.go index 6d0da24d001..30752f16cb0 100644 --- a/pkg/storage/utils/decomposedfs/tree/tree.go +++ b/pkg/storage/utils/decomposedfs/tree/tree.go @@ -578,8 +578,12 @@ func (t *Tree) Propagate(ctx context.Context, n *node.Node) (err error) { // is propagation enabled for the parent node? var root *node.Node - if root, err = t.lookup.HomeOrRootNode(ctx); err != nil { - return + if n.SpaceRoot == nil { + if root, err = t.lookup.HomeOrRootNode(ctx); err != nil { + return + } + } else { + root = n.SpaceRoot } // use a sync time and don't rely on the mtime of the current node, as the stat might not change when a rename happened too quickly diff --git a/pkg/storage/utils/decomposedfs/upload.go b/pkg/storage/utils/decomposedfs/upload.go index 1287fdaebc6..31a70c2db69 100644 --- a/pkg/storage/utils/decomposedfs/upload.go +++ b/pkg/storage/utils/decomposedfs/upload.go @@ -252,12 +252,14 @@ func (fs *Decomposedfs) NewUpload(ctx context.Context, info tusd.FileInfo) (uplo } info.Storage = map[string]string{ + // Todo: add storage space root "Type": "OCISStore", "BinPath": binPath, "NodeId": n.ID, "NodeParentId": n.ParentID, "NodeName": n.Name, + "SpaceRoot": n.SpaceRoot.ID, "Idp": usr.Id.Idp, "UserId": usr.Id.OpaqueId, @@ -474,7 +476,9 @@ func (upload *fileUpload) FinishUpload(ctx context.Context) (err error) { nil, upload.fs.lu, ) - + n.SpaceRoot = &node.Node{ + ID: upload.info.Storage["SpaceRoot"], + } if n.ID == "" { n.ID = uuid.New().String() }