Skip to content

Storage Space semantics in the CS3APIs #3693

Open
@labkode

Description

@labkode

This writeup comes from a deep investigation performed by @ishank011 @gmgigi96 @glpatcern as part of our activity to run OCIS edge branch at CERN.

Examples on edge branch running ocisfs

4c510ada-c86b-4815-8820-42cdf82c3d51 -> / is the home space ID
254d0b60-20e4-4340-9eae-6fa9103ae7d7 -> /app-try
7321538e-15da-4352-8dd7-d59b3319e7ef -> /app-try/app-new-try.txt

  • A
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::path (TYPE_STRING) =>

"id": {
      "opaqueId": "4c510ada-c86b-4815-8820-42cdf82c3d51",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },
"path": "/",
  • B
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) =>
ref::resource_id::opaque_id (TYPE_STRING) =>
ref::path (TYPE_STRING) => /

{
  "status": {
    "code": "CODE_NOT_FOUND",
    "message": "gateway could not find space for ref=resource_id:\u003c\u003e path:\"/\" ",
    "trace": "909ed9213ca8a16c59d3cb0f545e0767"
  }
}
  • C
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 254d0b60-20e4-4340-9eae-6fa9103ae7d7
ref::path (TYPE_STRING) =>

"id": {
      "opaqueId": "254d0b60-20e4-4340-9eae-6fa9103ae7d7",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    }
"path": "/app-try",
  • D
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::path (TYPE_STRING) => /app-try

"id": {
      "opaqueId": "254d0b60-20e4-4340-9eae-6fa9103ae7d7",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },
"path": "/app-try"
  • E
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::path (TYPE_STRING) => /app-try/app-new-try.txt

"id": {
      "opaqueId": "7321538e-15da-4352-8dd7-d59b3319e7ef",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },
"path": "/app-try/app-new-try.txt",
  • F
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::path (TYPE_STRING) => ./app-try/app-new-try.txt

"id": {
      "opaqueId": "7321538e-15da-4352-8dd7-d59b3319e7ef",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },
"path": "app-new-try.txt",
  • G
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) =>
ref::resource_id::opaque_id (TYPE_STRING) =>
ref::path (TYPE_STRING) => /app-try/app-new-try.txt
<repeated> arbitrary_metadata_keys (TYPE_STRING) =>
{
  "status": {
    "code": "CODE_NOT_FOUND",
    "message": "gateway could not find space for ref=resource_id:\u003c\u003e path:\"/app-try/app-new-try.txt\" ",
    "trace": "c2ed541c740faa4ba9362366368d8479"
  }
}
  • H
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 7321538e-15da-4352-8dd7-d59b3319e7ef
ref::path (TYPE_STRING) => .

"id": {
      "opaqueId": "7321538e-15da-4352-8dd7-d59b3319e7ef",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },
"path": "app-new-try.txt",
  • I
cs3.gateway.v1beta1.GatewayAPI@localhost:19000> call Stat
<repeated> opaque::map::key (TYPE_STRING) =>
ref::resource_id::storage_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::resource_id::opaque_id (TYPE_STRING) => 4c510ada-c86b-4815-8820-42cdf82c3d51
ref::path (TYPE_STRING) => .

"id": {
      "opaqueId": "4c510ada-c86b-4815-8820-42cdf82c3d51",
      "storageId": "4c510ada-c86b-4815-8820-42cdf82c3d51"
    },

Expected desired behaviour

Request:                                    Response
    res_id = nil                                res_id = {storage_id, opaque_id_c}
    path   = /top/a/b/c                         path   = /top/a/b/c
                                                parent_id = {storage_id, opaque_id_b}

eos file info /a/b/c                                                
                                                
------------------------------------------------------------------------------------

Request:                                    Response
    res_id = {storage_id, opaque_id_c}          res_id = {storage_id, opaque_id_c}
    path   = nil                                path   = /top/a/b/c       # edge is returning /c, needs to be fixed
                                                parent_id = {storage_id, opaque_id_b}

eos file info inode:opaque_id_c                                                
                                                
------------------------------------------------------------------------------------

Request:                                    Response
    res_id = {storage_id, opaque_id_a}          res_id = {storage_id, opaque_id_c}
    path   = ./b/c                              path   = /top/a/b/c       # edge is returning c, needs to be fixed
                                                parent_id = {storage_id, opaque_id_b}

path_a = eos file info inode:opaque_id_a                                                
eos file info path_a/b/c                                                

------------------------------------------------------------------------------------

Request:                                    Response
    res_id = {storage_id, opaque_id_c}          res_id = {storage_id, opaque_id_c}
    path   = .                                  path   = /top/a/b/c      # edge is returning c, needs to be fixed
                                                parent_id = {storage_id, opaque_id_b}
eos file info inode:opaque_id_c 

------------------------------------------------------------------------------------

Request:                                    Response    # eosfs will always return HTTP 404 here
    res_id = {storage_id, storage_id}           res_id = {storage_id, storage_id}
    path   = nil                                path   = nil   # the "name" of the space root node is not exposed
                                                parent_id = nil?
--
In the Request, nil or "." or "" paths SHALL be considered synonyms

The comment about semantics of path field will need to be amended:
https://cs3org.github.io/cs3apis/#cs3.storage.provider.v1beta1.ResourceInfo

Conclusion

Firstly, examples A and G show a defective implementation that doesn't honour the CS3APIs. Paths are a first class citizen of the API and are expected to work.

Secondly, the current implementation in ocisfs is poorly designed with potential nefarious consequences for clients.
Simply put, clients will need to have memory and and traversing trees will not be performant.

For example, having the tree /a/b/c/d a client that works with paths can query /a, /a/b or/a/b/c.

A client that works with ids and that knows about d will need to query the parent of d, which is c, then the parent of c which is b and then the parent of b which is a. Performance will be a function of tree depth. A workaround you may suggest is to "remember" node information in the client, however this pushes complexity to any client using the API (desktop sync, mobile) and basically anyone willing to integrate with OCIS in an optimal way.

To illustrate this behaviour from UNIX/POSIX environment, we're inside folder /var/tmp/data/log/2022/05/03/proxy.

In your case to go to: /var folder you need to do:

cd ..
cd ..
cd ..
cd ..
cd ..

By path you do:

cd /var/

@butonic @micbar @dragotin

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Needs Tests

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions