public inbox for [email protected]
 help / color / mirror / Atom feed
From: Stefan Roesch <[email protected]>
To: <[email protected]>, <[email protected]>
Cc: <[email protected]>
Subject: [PATCH v2 4/4] liburing: Add new test program to verify xattr support
Date: Wed, 23 Mar 2022 08:44:57 -0700	[thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>

Summary:

This adds a new test program to test the xattr support:
- fgetxattr
- fsetxattr
- getxattr
- setxattr

It also includes test cases for failure conditions and
for passing in an invalid sqe. The test case for checking
of invalid SQE, must be enabled by defining
DESTRUCTIVE_TESTING.

Signed-off-by: Stefan Roesch <[email protected]>
---
 test/Makefile |   1 +
 test/xattr.c  | 425 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 426 insertions(+)
 create mode 100644 test/xattr.c

diff --git a/test/Makefile b/test/Makefile
index 84c23c8..a4a7caf 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -154,6 +154,7 @@ test_srcs := \
 	timeout-overflow.c \
 	unlink.c \
 	wakeup-hang.c \
+	xattr.c \
 	skip-cqe.c \
 	# EOL
 
diff --git a/test/xattr.c b/test/xattr.c
new file mode 100644
index 0000000..017017e
--- /dev/null
+++ b/test/xattr.c
@@ -0,0 +1,425 @@
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/xattr.h>
+#include <unistd.h>
+
+#include "helpers.h"
+#include "liburing.h"
+
+/* Define constants. */
+#define XATTR_SIZE  255
+#define QUEUE_DEPTH 32
+
+#define FILENAME    "xattr.test"
+#define KEY1        "user.val1"
+#define KEY2        "user.val2"
+#define VALUE1      "value1"
+#define VALUE2      "value2-a-lot-longer"
+
+
+/* Call fsetxattr. */
+int io_uring_fsetxattr(struct io_uring *ring,
+		       int              fd,
+		       const char      *name,
+		       const void      *value,
+		       size_t           size,
+		       int              flags)
+{
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
+	int ret;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		fprintf(stderr, "Error cannot get sqe\n");
+		return -1;
+	}
+
+	io_uring_prep_fsetxattr(sqe, fd, name, value, flags, size);
+
+	ret = io_uring_submit(ring);
+	if (ret != 1) {
+		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = cqe->res;
+	io_uring_cqe_seen(ring, cqe);
+
+	return ret;
+}
+
+/* Submit fgetxattr request. */
+int io_uring_fgetxattr(struct io_uring *ring,
+		       int              fd,
+		       const char      *name,
+		       void            *value,
+		       size_t           size)
+{
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
+	int ret;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		fprintf(stderr, "Error cannot get sqe\n");
+		return -1;
+	}
+
+	io_uring_prep_fgetxattr(sqe, fd, name, value, size);
+
+	ret = io_uring_submit(ring);
+	if (ret != 1) {
+		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = cqe->res;
+	if (ret == -1) {
+		fprintf(stderr, "Error couldn'tget value\n");
+		return -1;
+	}
+
+	io_uring_cqe_seen(ring, cqe);
+	return ret;
+}
+
+/* Call setxattr. */
+int io_uring_setxattr(struct io_uring *ring,
+		      const char      *path,
+		      const char      *name,
+		      const void      *value,
+		      size_t           size,
+		      int              flags)
+{
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
+	int ret;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		fprintf(stderr, "Error cannot get sqe\n");
+		return -1;
+	}
+
+	io_uring_prep_setxattr(sqe, name, value, path, flags, size);
+
+	ret = io_uring_submit_and_wait(ring, 1);
+	if (ret != 1) {
+		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = cqe->res;
+	io_uring_cqe_seen(ring, cqe);
+
+	return ret;
+}
+
+/* Submit getxattr request. */
+int io_uring_getxattr(struct io_uring *ring,
+		      const char      *path,
+		      const char      *name,
+		      void            *value,
+		      size_t           size)
+{
+	struct io_uring_sqe *sqe;
+	struct io_uring_cqe *cqe;
+	int ret;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		fprintf(stderr, "Error cannot get sqe\n");
+		return -1;
+	}
+
+	io_uring_prep_getxattr(sqe, name, value, path, size);
+
+	ret = io_uring_submit(ring);
+	if (ret != 1) {
+		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = cqe->res;
+	if (ret == -1) {
+		fprintf(stderr, "Error couldn'tget value\n");
+		return -1;
+	}
+
+	io_uring_cqe_seen(ring, cqe);
+	return ret;
+}
+
+/* Test driver for fsetxattr and fgetxattr. */
+int test_fxattr(void)
+{
+	int rc = 0;
+	size_t value_len;
+	struct io_uring ring;
+	char value[XATTR_SIZE];
+
+	/* Init io-uring queue. */
+	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "child: ring setup failed: %d\n", ret);
+		return -1;
+	}
+
+	/* Create the test file. */
+	int fd = open(FILENAME, O_CREAT | O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "Error: cannot open file: ret=%d\n", fd);
+		return -1;
+	}
+
+	/* Test writing attributes. */
+	if (io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, strlen(VALUE1), 0) == -1) {
+		fprintf(stderr, "Error fsetxattr cannot write key1\n");
+		rc = -1;
+		goto Exit;
+	}
+
+	if (io_uring_fsetxattr(&ring, fd, KEY2, VALUE2, strlen(VALUE2), 0) == -1) {
+		fprintf(stderr, "Error fsetxattr cannot write key1\n");
+		rc = -1;
+		goto Exit;
+	}
+
+	/* Test reading attributes. */
+	value_len = io_uring_fgetxattr(&ring, fd, KEY1, value, XATTR_SIZE);
+	if (value_len != strlen(value) || strncmp(value, VALUE1, value_len)) {
+		fprintf(stderr, "Error: fgetxattr expectd value: %s, returned value: %s\n", VALUE1, value);
+		rc = -1;
+		goto Exit;
+	}
+
+	value_len = io_uring_fgetxattr(&ring, fd, KEY2, value, XATTR_SIZE);
+	if (value_len != strlen(value)|| strncmp(value, VALUE2, value_len)) {
+		fprintf(stderr, "Error: fgetxattr expectd value: %s, returned value: %s\n", VALUE2, value);
+		rc = -1;
+		goto Exit;
+	}
+
+	/* Cleanup. */
+Exit:
+	close(fd);
+	unlink(FILENAME);
+
+	io_uring_queue_exit(&ring);
+
+	return rc;
+}
+
+/* Test driver for setxattr and getxattr. */
+int test_xattr(void)
+{
+	int rc = 0;
+	int value_len;
+	struct io_uring ring;
+	char value[XATTR_SIZE];
+
+	/* Init io-uring queue. */
+	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "child: ring setup failed: %d\n", ret);
+		return -1;
+	}
+
+	/* Create the test file. */
+	t_create_file(FILENAME, 0);
+
+	/* Test writing attributes. */
+	if (io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, strlen(VALUE1), 0) == -1) {
+		fprintf(stderr, "Error setxattr cannot write key1\n");
+		rc = -1;
+		goto Exit;
+	}
+
+	if (io_uring_setxattr(&ring, FILENAME, KEY2, VALUE2, strlen(VALUE2), 0) == -1) {
+		fprintf(stderr, "Error setxattr cannot write key1\n");
+		rc = -1;
+		goto Exit;
+	}
+
+	/* Test reading attributes. */
+	value_len = io_uring_getxattr(&ring, FILENAME, KEY1, value, XATTR_SIZE);
+	if (value_len != strlen(VALUE1) || strncmp(value, VALUE1, value_len)) {
+		fprintf(stderr, "Error: getxattr expectd value: %s, returned value: %s\n", VALUE1, value);
+		rc = -1;
+		goto Exit;
+	}
+
+	value_len = io_uring_getxattr(&ring, FILENAME, KEY2, value, XATTR_SIZE);
+	if (value_len != strlen(VALUE2) || strncmp(value, VALUE2, value_len)) {
+		fprintf(stderr, "Error: getxattr expectd value: %s, returned value: %s\n", VALUE2, value);
+		rc = -1;
+		goto Exit;
+	}
+
+	/* Cleanup. */
+Exit:
+	io_uring_queue_exit(&ring);
+	unlink(FILENAME);
+
+	return rc;
+}
+
+/* Test driver for failure cases of fsetxattr and fgetxattr. */
+int test_failure_fxattr(void)
+{
+	int rc = 0;
+	struct io_uring ring;
+	char value[XATTR_SIZE];
+
+	/* Init io-uring queue. */
+	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "child: ring setup failed: %d\n", ret);
+		return -1;
+	}
+
+	/* Create the test file. */
+	int fd = open(FILENAME, O_CREAT | O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "Error: cannot open file: ret=%d\n", fd);
+		return -1;
+	}
+
+	/* Test writing attributes. */
+	assert(io_uring_fsetxattr(&ring, -1, KEY1, VALUE1, strlen(VALUE1), 0) < 0);
+	assert(io_uring_fsetxattr(&ring, fd, NULL, VALUE1, strlen(VALUE1), 0) < 0);
+	assert(io_uring_fsetxattr(&ring, fd, KEY1, NULL,   strlen(VALUE1), 0) < 0);
+	assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, 0,              0) == 0);
+	assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, -1,             0) < 0);
+
+	/* Test reading attributes. */
+	assert(io_uring_fgetxattr(&ring, -1, KEY1, value, XATTR_SIZE) < 0);
+	assert(io_uring_fgetxattr(&ring, fd, NULL, value, XATTR_SIZE) < 0);
+	assert(io_uring_fgetxattr(&ring, fd, KEY1, value, 0)          == 0);
+
+	/* Cleanup. */
+	close(fd);
+	unlink(FILENAME);
+
+	io_uring_queue_exit(&ring);
+
+	return rc;
+}
+
+
+/* Test driver for failure cases for setxattr and getxattr. */
+int test_failure_xattr(void)
+{
+	int rc = 0;
+	struct io_uring ring;
+	char value[XATTR_SIZE];
+
+	/* Init io-uring queue. */
+	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "child: ring setup failed: %d\n", ret);
+		return -1;
+	}
+
+	/* Create the test file. */
+	t_create_file(FILENAME, 0);
+
+	/* Test writing attributes. */
+	assert(io_uring_setxattr(&ring, "complete garbage", KEY1, VALUE1, strlen(VALUE1), 0) < 0);
+	assert(io_uring_setxattr(&ring, NULL,     KEY1, VALUE1, strlen(VALUE1), 0) < 0);
+	assert(io_uring_setxattr(&ring, FILENAME, NULL, VALUE1, strlen(VALUE1), 0) < 0);
+	assert(io_uring_setxattr(&ring, FILENAME, KEY1, NULL,   strlen(VALUE1), 0) < 0);
+	assert(io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, 0,              0) == 0);
+
+	/* Test reading attributes. */
+	assert(io_uring_getxattr(&ring, "complete garbage", KEY1, value, XATTR_SIZE) < 0);
+	assert(io_uring_getxattr(&ring, NULL,     KEY1, value, XATTR_SIZE) < 0);
+	assert(io_uring_getxattr(&ring, FILENAME, NULL, value, XATTR_SIZE) < 0);
+	assert(io_uring_getxattr(&ring, FILENAME, KEY1, NULL,  XATTR_SIZE) == 0);
+	assert(io_uring_getxattr(&ring, FILENAME, KEY1, value, 0)          == 0);
+
+	/* Cleanup. */
+	io_uring_queue_exit(&ring);
+	unlink(FILENAME);
+
+	return rc;
+}
+
+/* Test for invalid SQE, this will cause a segmentation fault if enabled. */
+int test_invalid_sqe(void)
+{
+#ifdef DESTRUCTIVE_TEST
+	struct io_uring_sqe *sqe = NULL;
+	struct io_uring_cqe *cqe = NULL;
+	struct io_uring ring;
+
+	/* Init io-uring queue. */
+	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
+	if (ret) {
+		fprintf(stderr, "child: ring setup failed: %d\n", ret);
+		return -1;
+	}
+
+	/* Pass invalid SQE. */
+	io_uring_prep_setxattr(sqe, FILENAME, KEY1, VALUE1, strlen(VALUE1), 0);
+
+	ret = io_uring_submit(&ring);
+	if (ret != 1) {
+		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = io_uring_wait_cqe(&ring, &cqe);
+	if (ret) {
+		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
+		return -1;
+	}
+
+	ret = cqe->res;
+	io_uring_cqe_seen(&ring, cqe);
+
+	return ret;
+#else
+	return 0;
+#endif
+}
+
+/* Test driver. */
+int main(int argc, char **argv) {
+	if (test_fxattr()
+		|| test_xattr()
+	    || test_failure_fxattr()
+		|| test_failure_xattr()
+	    || test_invalid_sqe())
+		return EXIT_FAILURE;
+
+	return EXIT_SUCCESS;
+}
-- 
2.30.2



  parent reply	other threads:[~2022-03-23 15:45 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-23 15:44 [PATCH v2 0/4] liburing: support xattr functions Stefan Roesch
2022-03-23 15:44 ` [PATCH v2 1/4] liburing: Update io_uring in liburing Stefan Roesch
2022-03-23 15:44 ` [PATCH v2 2/4] liburing: add helper functions for setxattr and fsetxattr Stefan Roesch
2022-03-23 15:44 ` [PATCH v2 3/4] liburing: Add helper functions for fgetxattr and getxattr Stefan Roesch
2022-03-23 15:44 ` Stefan Roesch [this message]
2022-03-30 20:47 ` [PATCH v2 0/4] liburing: support xattr functions Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox