Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lvol): snapshot labels #46

Open
wants to merge 3 commits into
base: longhorn-v24.09
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/blob/cli/blobcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ show_blob(struct cli_context_t *cli_context)
case SPDK_BLOB_STATE_DIRTY:
printf("state: DIRTY\n");
break;
case SPDK_BLOB_STATE_DIRTY_XATTR:
printf("state: DIRTY XATTR\n");
break;
case SPDK_BLOB_STATE_CLEAN:
printf("state: CLEAN\n");
break;
Expand Down
8 changes: 4 additions & 4 deletions lib/blob/blobstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ blob_serialize(const struct spdk_blob *blob, struct spdk_blob_md_page **pages,
assert(pages != NULL);
assert(page_count != NULL);
assert(blob != NULL);
assert(blob->state == SPDK_BLOB_STATE_DIRTY);
assert(blob->state == SPDK_BLOB_STATE_DIRTY || blob->state == SPDK_BLOB_STATE_DIRTY_XATTR);

*pages = NULL;
*page_count = 0;
Expand Down Expand Up @@ -8970,7 +8970,7 @@ spdk_blob_sync_md(struct spdk_blob *blob, spdk_blob_op_complete cb_fn, void *cb_

SPDK_DEBUGLOG(blob, "Syncing blob 0x%" PRIx64 "\n", blob->id);

if (blob->md_ro) {
if (blob->md_ro && blob->state != SPDK_BLOB_STATE_DIRTY_XATTR) {
assert(blob->state == SPDK_BLOB_STATE_CLEAN);
cb_fn(cb_arg, 0);
return;
Expand Down Expand Up @@ -9574,7 +9574,7 @@ blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value,
xattr->value = tmp;
memcpy(xattr->value, value, value_len);

blob->state = SPDK_BLOB_STATE_DIRTY;
blob->state = SPDK_BLOB_STATE_DIRTY_XATTR;

return 0;
}
Expand All @@ -9601,7 +9601,7 @@ blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value,
memcpy(xattr->value, value, value_len);
TAILQ_INSERT_TAIL(xattrs, xattr, link);

blob->state = SPDK_BLOB_STATE_DIRTY;
blob->state = SPDK_BLOB_STATE_DIRTY_XATTR;

return 0;
}
Expand Down
8 changes: 8 additions & 0 deletions lib/blob/blobstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ enum spdk_blob_state {
*/
SPDK_BLOB_STATE_DIRTY,

/* The blob in-memory version does not match the on-disk
* version because xattrs have been added or updated.
* This state is used to add or update xattrs to read
* only blobs, for which it is not possible to change
* other blob metadata.
*/
SPDK_BLOB_STATE_DIRTY_XATTR,

/* The blob in memory version of the blob matches the on disk
* version.
*/
Expand Down
6 changes: 0 additions & 6 deletions lib/lvol/lvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1812,12 +1812,6 @@ spdk_lvol_set_xattr(struct spdk_lvol *lvol, const char *name, const char *value,
struct spdk_lvol_req *req;
int rc;

if (spdk_blob_is_read_only(blob)) {
SPDK_ERRLOG("Cannot set xattr to read only lvol\n");
cb_fn(cb_arg, -EPERM);
return;
}

req = calloc(1, sizeof(*req));
if (!req) {
SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
Expand Down
5 changes: 3 additions & 2 deletions test/lvol/xattr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ function test_set_xattr() {
value=$(rpc_cmd bdev_lvol_get_xattr "$lvol_uuid" "foo")
[ "\"bar\"" = "$value" ]

# Snapshot is read-only, so setting xattr should fail
# Snapshot is read-only, but setting xattr is permitted
snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
NOT rpc_cmd bdev_lvol_set_xattr "$snapshot_uuid" "foo" "bar"
rpc_cmd bdev_lvol_set_xattr "$snapshot_uuid" "foo" "bar"
rpc_cmd bdev_lvol_set_xattr "$snapshot_uuid" "foo" "bar2"

# Create snapshot with xattr
snapshotx_uuid=$(rpc_cmd bdev_lvol_snapshot --xattr snapshot_timestamp=2024-01-16T16:06:46Z lvs_test/lvol_test lvol_snapshotx)
Expand Down
23 changes: 22 additions & 1 deletion test/unit/lib/blob/blob.c/blob_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -2242,14 +2242,35 @@ blob_xattr(void)
CU_ASSERT(value_len == 8);
blob->md_ro = false;

/* set_xattr, for both add and update xattrs, should still work even if md_ro flag is set. */
value = NULL;
blob->md_ro = true;
length = 4567;
rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
CU_ASSERT(rc == 0);
rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len);
CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(value != NULL);
CU_ASSERT(*(uint64_t *)value == length);
CU_ASSERT(value_len == 8);
length = 5678;
rc = spdk_blob_set_xattr(blob, "length2", &length, sizeof(length));
CU_ASSERT(rc == 0);
rc = spdk_blob_get_xattr_value(blob, "length2", &value, &value_len);
CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(value != NULL);
CU_ASSERT(*(uint64_t *)value == length);
CU_ASSERT(value_len == 8);
blob->md_ro = false;

rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
CU_ASSERT(rc == -ENOENT);

names = NULL;
rc = spdk_blob_get_xattr_names(blob, &names);
CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(names != NULL);
CU_ASSERT(spdk_xattr_names_get_count(names) == 2);
CU_ASSERT(spdk_xattr_names_get_count(names) == 3);
name1 = spdk_xattr_names_get_name(names, 0);
SPDK_CU_ASSERT_FATAL(name1 != NULL);
CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length"));
Expand Down