xref: /aosp_15_r20/external/liburing/test/xattr.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker #include <assert.h>
2*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
3*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
4*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
5*25da2beaSAndroid Build Coastguard Worker #include <string.h>
6*25da2beaSAndroid Build Coastguard Worker #include <sys/xattr.h>
7*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
8*25da2beaSAndroid Build Coastguard Worker 
9*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
10*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
11*25da2beaSAndroid Build Coastguard Worker 
12*25da2beaSAndroid Build Coastguard Worker static int no_xattr;
13*25da2beaSAndroid Build Coastguard Worker 
14*25da2beaSAndroid Build Coastguard Worker /* Define constants. */
15*25da2beaSAndroid Build Coastguard Worker #define XATTR_SIZE  255
16*25da2beaSAndroid Build Coastguard Worker #define QUEUE_DEPTH 32
17*25da2beaSAndroid Build Coastguard Worker 
18*25da2beaSAndroid Build Coastguard Worker #define FILENAME    "xattr.test"
19*25da2beaSAndroid Build Coastguard Worker #define KEY1        "user.val1"
20*25da2beaSAndroid Build Coastguard Worker #define KEY2        "user.val2"
21*25da2beaSAndroid Build Coastguard Worker #define VALUE1      "value1"
22*25da2beaSAndroid Build Coastguard Worker #define VALUE2      "value2-a-lot-longer"
23*25da2beaSAndroid Build Coastguard Worker 
24*25da2beaSAndroid Build Coastguard Worker 
25*25da2beaSAndroid Build Coastguard Worker /* Call fsetxattr. */
io_uring_fsetxattr(struct io_uring * ring,int fd,const char * name,const void * value,size_t size,int flags)26*25da2beaSAndroid Build Coastguard Worker static int io_uring_fsetxattr(struct io_uring *ring, int fd, const char *name,
27*25da2beaSAndroid Build Coastguard Worker 			      const void *value, size_t size, int flags)
28*25da2beaSAndroid Build Coastguard Worker {
29*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
30*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
31*25da2beaSAndroid Build Coastguard Worker 	int ret;
32*25da2beaSAndroid Build Coastguard Worker 
33*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
34*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
35*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error cannot get sqe\n");
36*25da2beaSAndroid Build Coastguard Worker 		return -1;
37*25da2beaSAndroid Build Coastguard Worker 	}
38*25da2beaSAndroid Build Coastguard Worker 
39*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fsetxattr(sqe, fd, name, value, flags, size);
40*25da2beaSAndroid Build Coastguard Worker 
41*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
42*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
43*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
44*25da2beaSAndroid Build Coastguard Worker 		return -1;
45*25da2beaSAndroid Build Coastguard Worker 	}
46*25da2beaSAndroid Build Coastguard Worker 
47*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
48*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
49*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
50*25da2beaSAndroid Build Coastguard Worker 		return -1;
51*25da2beaSAndroid Build Coastguard Worker 	}
52*25da2beaSAndroid Build Coastguard Worker 
53*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
54*25da2beaSAndroid Build Coastguard Worker 	if (ret == -EINVAL)
55*25da2beaSAndroid Build Coastguard Worker 		no_xattr = 1;
56*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
57*25da2beaSAndroid Build Coastguard Worker 
58*25da2beaSAndroid Build Coastguard Worker 	return ret;
59*25da2beaSAndroid Build Coastguard Worker }
60*25da2beaSAndroid Build Coastguard Worker 
61*25da2beaSAndroid Build Coastguard Worker /* Submit fgetxattr request. */
io_uring_fgetxattr(struct io_uring * ring,int fd,const char * name,void * value,size_t size)62*25da2beaSAndroid Build Coastguard Worker static int io_uring_fgetxattr(struct io_uring *ring, int fd, const char *name,
63*25da2beaSAndroid Build Coastguard Worker 			      void *value, size_t size)
64*25da2beaSAndroid Build Coastguard Worker {
65*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
66*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
67*25da2beaSAndroid Build Coastguard Worker 	int ret;
68*25da2beaSAndroid Build Coastguard Worker 
69*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
70*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
71*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error cannot get sqe\n");
72*25da2beaSAndroid Build Coastguard Worker 		return -1;
73*25da2beaSAndroid Build Coastguard Worker 	}
74*25da2beaSAndroid Build Coastguard Worker 
75*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fgetxattr(sqe, fd, name, value, size);
76*25da2beaSAndroid Build Coastguard Worker 
77*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
78*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
79*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
80*25da2beaSAndroid Build Coastguard Worker 		return -1;
81*25da2beaSAndroid Build Coastguard Worker 	}
82*25da2beaSAndroid Build Coastguard Worker 
83*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
84*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
85*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
86*25da2beaSAndroid Build Coastguard Worker 		return -1;
87*25da2beaSAndroid Build Coastguard Worker 	}
88*25da2beaSAndroid Build Coastguard Worker 
89*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
90*25da2beaSAndroid Build Coastguard Worker 	if (ret == -1) {
91*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error couldn'tget value\n");
92*25da2beaSAndroid Build Coastguard Worker 		return -1;
93*25da2beaSAndroid Build Coastguard Worker 	}
94*25da2beaSAndroid Build Coastguard Worker 
95*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
96*25da2beaSAndroid Build Coastguard Worker 	return ret;
97*25da2beaSAndroid Build Coastguard Worker }
98*25da2beaSAndroid Build Coastguard Worker 
99*25da2beaSAndroid Build Coastguard Worker /* Call setxattr. */
io_uring_setxattr(struct io_uring * ring,const char * path,const char * name,const void * value,size_t size,int flags)100*25da2beaSAndroid Build Coastguard Worker static int io_uring_setxattr(struct io_uring *ring, const char *path,
101*25da2beaSAndroid Build Coastguard Worker 			     const char *name, const void *value, size_t size,
102*25da2beaSAndroid Build Coastguard Worker 			     int flags)
103*25da2beaSAndroid Build Coastguard Worker {
104*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
105*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
106*25da2beaSAndroid Build Coastguard Worker 	int ret;
107*25da2beaSAndroid Build Coastguard Worker 
108*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
109*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
110*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error cannot get sqe\n");
111*25da2beaSAndroid Build Coastguard Worker 		return -1;
112*25da2beaSAndroid Build Coastguard Worker 	}
113*25da2beaSAndroid Build Coastguard Worker 
114*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_setxattr(sqe, name, value, path, flags, size);
115*25da2beaSAndroid Build Coastguard Worker 
116*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit_and_wait(ring, 1);
117*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
118*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
119*25da2beaSAndroid Build Coastguard Worker 		return -1;
120*25da2beaSAndroid Build Coastguard Worker 	}
121*25da2beaSAndroid Build Coastguard Worker 
122*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
123*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
124*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
125*25da2beaSAndroid Build Coastguard Worker 		return -1;
126*25da2beaSAndroid Build Coastguard Worker 	}
127*25da2beaSAndroid Build Coastguard Worker 
128*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
129*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
130*25da2beaSAndroid Build Coastguard Worker 
131*25da2beaSAndroid Build Coastguard Worker 	return ret;
132*25da2beaSAndroid Build Coastguard Worker }
133*25da2beaSAndroid Build Coastguard Worker 
134*25da2beaSAndroid Build Coastguard Worker /* Submit getxattr request. */
io_uring_getxattr(struct io_uring * ring,const char * path,const char * name,void * value,size_t size)135*25da2beaSAndroid Build Coastguard Worker static int io_uring_getxattr(struct io_uring *ring, const char *path,
136*25da2beaSAndroid Build Coastguard Worker 			     const char *name, void *value, size_t size)
137*25da2beaSAndroid Build Coastguard Worker {
138*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
139*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
140*25da2beaSAndroid Build Coastguard Worker 	int ret;
141*25da2beaSAndroid Build Coastguard Worker 
142*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
143*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
144*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error cannot get sqe\n");
145*25da2beaSAndroid Build Coastguard Worker 		return -1;
146*25da2beaSAndroid Build Coastguard Worker 	}
147*25da2beaSAndroid Build Coastguard Worker 
148*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_getxattr(sqe, name, value, path, size);
149*25da2beaSAndroid Build Coastguard Worker 
150*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
151*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
152*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
153*25da2beaSAndroid Build Coastguard Worker 		return -1;
154*25da2beaSAndroid Build Coastguard Worker 	}
155*25da2beaSAndroid Build Coastguard Worker 
156*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
157*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
158*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
159*25da2beaSAndroid Build Coastguard Worker 		return -1;
160*25da2beaSAndroid Build Coastguard Worker 	}
161*25da2beaSAndroid Build Coastguard Worker 
162*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
163*25da2beaSAndroid Build Coastguard Worker 	if (ret == -1) {
164*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error couldn'tget value\n");
165*25da2beaSAndroid Build Coastguard Worker 		return -1;
166*25da2beaSAndroid Build Coastguard Worker 	}
167*25da2beaSAndroid Build Coastguard Worker 
168*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
169*25da2beaSAndroid Build Coastguard Worker 	return ret;
170*25da2beaSAndroid Build Coastguard Worker }
171*25da2beaSAndroid Build Coastguard Worker 
172*25da2beaSAndroid Build Coastguard Worker /* Test driver for fsetxattr and fgetxattr. */
test_fxattr(void)173*25da2beaSAndroid Build Coastguard Worker static int test_fxattr(void)
174*25da2beaSAndroid Build Coastguard Worker {
175*25da2beaSAndroid Build Coastguard Worker 	int rc = 0;
176*25da2beaSAndroid Build Coastguard Worker 	size_t value_len;
177*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
178*25da2beaSAndroid Build Coastguard Worker 	char value[XATTR_SIZE];
179*25da2beaSAndroid Build Coastguard Worker 
180*25da2beaSAndroid Build Coastguard Worker 	/* Init io-uring queue. */
181*25da2beaSAndroid Build Coastguard Worker 	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
182*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
183*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: ring setup failed: %d\n", ret);
184*25da2beaSAndroid Build Coastguard Worker 		return -1;
185*25da2beaSAndroid Build Coastguard Worker 	}
186*25da2beaSAndroid Build Coastguard Worker 
187*25da2beaSAndroid Build Coastguard Worker 	/* Create the test file. */
188*25da2beaSAndroid Build Coastguard Worker 	int fd = open(FILENAME, O_CREAT | O_RDWR, 0644);
189*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
190*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: cannot open file: ret=%d\n", fd);
191*25da2beaSAndroid Build Coastguard Worker 		return -1;
192*25da2beaSAndroid Build Coastguard Worker 	}
193*25da2beaSAndroid Build Coastguard Worker 
194*25da2beaSAndroid Build Coastguard Worker 	/* Test writing attributes. */
195*25da2beaSAndroid Build Coastguard Worker 	if (io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, strlen(VALUE1), 0) < 0) {
196*25da2beaSAndroid Build Coastguard Worker 		if (no_xattr) {
197*25da2beaSAndroid Build Coastguard Worker 			fprintf(stdout, "No xattr support, skipping\n");
198*25da2beaSAndroid Build Coastguard Worker 			goto Exit;
199*25da2beaSAndroid Build Coastguard Worker 		}
200*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error fsetxattr cannot write key1\n");
201*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
202*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
203*25da2beaSAndroid Build Coastguard Worker 	}
204*25da2beaSAndroid Build Coastguard Worker 
205*25da2beaSAndroid Build Coastguard Worker 	if (io_uring_fsetxattr(&ring, fd, KEY2, VALUE2, strlen(VALUE2), 0) < 0) {
206*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error fsetxattr cannot write key1\n");
207*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
208*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
209*25da2beaSAndroid Build Coastguard Worker 	}
210*25da2beaSAndroid Build Coastguard Worker 
211*25da2beaSAndroid Build Coastguard Worker 	/* Test reading attributes. */
212*25da2beaSAndroid Build Coastguard Worker 	value_len = io_uring_fgetxattr(&ring, fd, KEY1, value, XATTR_SIZE);
213*25da2beaSAndroid Build Coastguard Worker 	if (value_len != strlen(value) || strncmp(value, VALUE1, value_len)) {
214*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: fgetxattr expected value: %s, returned value: %s\n", VALUE1, value);
215*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
216*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
217*25da2beaSAndroid Build Coastguard Worker 	}
218*25da2beaSAndroid Build Coastguard Worker 
219*25da2beaSAndroid Build Coastguard Worker 	value_len = io_uring_fgetxattr(&ring, fd, KEY2, value, XATTR_SIZE);
220*25da2beaSAndroid Build Coastguard Worker 	if (value_len != strlen(value)|| strncmp(value, VALUE2, value_len)) {
221*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: fgetxattr expected value: %s, returned value: %s\n", VALUE2, value);
222*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
223*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
224*25da2beaSAndroid Build Coastguard Worker 	}
225*25da2beaSAndroid Build Coastguard Worker 
226*25da2beaSAndroid Build Coastguard Worker 	/* Cleanup. */
227*25da2beaSAndroid Build Coastguard Worker Exit:
228*25da2beaSAndroid Build Coastguard Worker 	close(fd);
229*25da2beaSAndroid Build Coastguard Worker 	unlink(FILENAME);
230*25da2beaSAndroid Build Coastguard Worker 
231*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
232*25da2beaSAndroid Build Coastguard Worker 
233*25da2beaSAndroid Build Coastguard Worker 	return rc;
234*25da2beaSAndroid Build Coastguard Worker }
235*25da2beaSAndroid Build Coastguard Worker 
236*25da2beaSAndroid Build Coastguard Worker /* Test driver for setxattr and getxattr. */
test_xattr(void)237*25da2beaSAndroid Build Coastguard Worker static int test_xattr(void)
238*25da2beaSAndroid Build Coastguard Worker {
239*25da2beaSAndroid Build Coastguard Worker 	int rc = 0;
240*25da2beaSAndroid Build Coastguard Worker 	int value_len;
241*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
242*25da2beaSAndroid Build Coastguard Worker 	char value[XATTR_SIZE];
243*25da2beaSAndroid Build Coastguard Worker 
244*25da2beaSAndroid Build Coastguard Worker 	/* Init io-uring queue. */
245*25da2beaSAndroid Build Coastguard Worker 	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
246*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
247*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: ring setup failed: %d\n", ret);
248*25da2beaSAndroid Build Coastguard Worker 		return -1;
249*25da2beaSAndroid Build Coastguard Worker 	}
250*25da2beaSAndroid Build Coastguard Worker 
251*25da2beaSAndroid Build Coastguard Worker 	/* Create the test file. */
252*25da2beaSAndroid Build Coastguard Worker 	t_create_file(FILENAME, 0);
253*25da2beaSAndroid Build Coastguard Worker 
254*25da2beaSAndroid Build Coastguard Worker 	/* Test writing attributes. */
255*25da2beaSAndroid Build Coastguard Worker 	if (io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, strlen(VALUE1), 0) < 0) {
256*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error setxattr cannot write key1\n");
257*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
258*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
259*25da2beaSAndroid Build Coastguard Worker 	}
260*25da2beaSAndroid Build Coastguard Worker 
261*25da2beaSAndroid Build Coastguard Worker 	if (io_uring_setxattr(&ring, FILENAME, KEY2, VALUE2, strlen(VALUE2), 0) < 0) {
262*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error setxattr cannot write key1\n");
263*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
264*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
265*25da2beaSAndroid Build Coastguard Worker 	}
266*25da2beaSAndroid Build Coastguard Worker 
267*25da2beaSAndroid Build Coastguard Worker 	/* Test reading attributes. */
268*25da2beaSAndroid Build Coastguard Worker 	value_len = io_uring_getxattr(&ring, FILENAME, KEY1, value, XATTR_SIZE);
269*25da2beaSAndroid Build Coastguard Worker 	if (value_len != strlen(VALUE1) || strncmp(value, VALUE1, value_len)) {
270*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: getxattr expected value: %s, returned value: %s\n", VALUE1, value);
271*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
272*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
273*25da2beaSAndroid Build Coastguard Worker 	}
274*25da2beaSAndroid Build Coastguard Worker 
275*25da2beaSAndroid Build Coastguard Worker 	value_len = io_uring_getxattr(&ring, FILENAME, KEY2, value, XATTR_SIZE);
276*25da2beaSAndroid Build Coastguard Worker 	if (value_len != strlen(VALUE2) || strncmp(value, VALUE2, value_len)) {
277*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: getxattr expected value: %s, returned value: %s\n", VALUE2, value);
278*25da2beaSAndroid Build Coastguard Worker 		rc = -1;
279*25da2beaSAndroid Build Coastguard Worker 		goto Exit;
280*25da2beaSAndroid Build Coastguard Worker 	}
281*25da2beaSAndroid Build Coastguard Worker 
282*25da2beaSAndroid Build Coastguard Worker 	/* Cleanup. */
283*25da2beaSAndroid Build Coastguard Worker Exit:
284*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
285*25da2beaSAndroid Build Coastguard Worker 	unlink(FILENAME);
286*25da2beaSAndroid Build Coastguard Worker 
287*25da2beaSAndroid Build Coastguard Worker 	return rc;
288*25da2beaSAndroid Build Coastguard Worker }
289*25da2beaSAndroid Build Coastguard Worker 
290*25da2beaSAndroid Build Coastguard Worker /* Test driver for failure cases of fsetxattr and fgetxattr. */
test_failure_fxattr(void)291*25da2beaSAndroid Build Coastguard Worker static int test_failure_fxattr(void)
292*25da2beaSAndroid Build Coastguard Worker {
293*25da2beaSAndroid Build Coastguard Worker 	int rc = 0;
294*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
295*25da2beaSAndroid Build Coastguard Worker 	char value[XATTR_SIZE];
296*25da2beaSAndroid Build Coastguard Worker 
297*25da2beaSAndroid Build Coastguard Worker 	/* Init io-uring queue. */
298*25da2beaSAndroid Build Coastguard Worker 	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
299*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
300*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: ring setup failed: %d\n", ret);
301*25da2beaSAndroid Build Coastguard Worker 		return -1;
302*25da2beaSAndroid Build Coastguard Worker 	}
303*25da2beaSAndroid Build Coastguard Worker 
304*25da2beaSAndroid Build Coastguard Worker 	/* Create the test file. */
305*25da2beaSAndroid Build Coastguard Worker 	int fd = open(FILENAME, O_CREAT | O_RDWR, 0644);
306*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
307*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error: cannot open file: ret=%d\n", fd);
308*25da2beaSAndroid Build Coastguard Worker 		return -1;
309*25da2beaSAndroid Build Coastguard Worker 	}
310*25da2beaSAndroid Build Coastguard Worker 
311*25da2beaSAndroid Build Coastguard Worker 	/* Test writing attributes. */
312*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fsetxattr(&ring, -1, KEY1, VALUE1, strlen(VALUE1), 0) < 0);
313*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fsetxattr(&ring, fd, NULL, VALUE1, strlen(VALUE1), 0) < 0);
314*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fsetxattr(&ring, fd, KEY1, NULL,   strlen(VALUE1), 0) < 0);
315*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, 0,              0) == 0);
316*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fsetxattr(&ring, fd, KEY1, VALUE1, -1,             0) < 0);
317*25da2beaSAndroid Build Coastguard Worker 
318*25da2beaSAndroid Build Coastguard Worker 	/* Test reading attributes. */
319*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fgetxattr(&ring, -1, KEY1, value, XATTR_SIZE) < 0);
320*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fgetxattr(&ring, fd, NULL, value, XATTR_SIZE) < 0);
321*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_fgetxattr(&ring, fd, KEY1, value, 0)          == 0);
322*25da2beaSAndroid Build Coastguard Worker 
323*25da2beaSAndroid Build Coastguard Worker 	/* Cleanup. */
324*25da2beaSAndroid Build Coastguard Worker 	close(fd);
325*25da2beaSAndroid Build Coastguard Worker 	unlink(FILENAME);
326*25da2beaSAndroid Build Coastguard Worker 
327*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
328*25da2beaSAndroid Build Coastguard Worker 
329*25da2beaSAndroid Build Coastguard Worker 	return rc;
330*25da2beaSAndroid Build Coastguard Worker }
331*25da2beaSAndroid Build Coastguard Worker 
332*25da2beaSAndroid Build Coastguard Worker 
333*25da2beaSAndroid Build Coastguard Worker /* Test driver for failure cases for setxattr and getxattr. */
test_failure_xattr(void)334*25da2beaSAndroid Build Coastguard Worker static int test_failure_xattr(void)
335*25da2beaSAndroid Build Coastguard Worker {
336*25da2beaSAndroid Build Coastguard Worker 	int rc = 0;
337*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
338*25da2beaSAndroid Build Coastguard Worker 	char value[XATTR_SIZE];
339*25da2beaSAndroid Build Coastguard Worker 
340*25da2beaSAndroid Build Coastguard Worker 	/* Init io-uring queue. */
341*25da2beaSAndroid Build Coastguard Worker 	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
342*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
343*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: ring setup failed: %d\n", ret);
344*25da2beaSAndroid Build Coastguard Worker 		return -1;
345*25da2beaSAndroid Build Coastguard Worker 	}
346*25da2beaSAndroid Build Coastguard Worker 
347*25da2beaSAndroid Build Coastguard Worker 	/* Create the test file. */
348*25da2beaSAndroid Build Coastguard Worker 	t_create_file(FILENAME, 0);
349*25da2beaSAndroid Build Coastguard Worker 
350*25da2beaSAndroid Build Coastguard Worker 	/* Test writing attributes. */
351*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_setxattr(&ring, "complete garbage", KEY1, VALUE1, strlen(VALUE1), 0) < 0);
352*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_setxattr(&ring, NULL,     KEY1, VALUE1, strlen(VALUE1), 0) < 0);
353*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_setxattr(&ring, FILENAME, NULL, VALUE1, strlen(VALUE1), 0) < 0);
354*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_setxattr(&ring, FILENAME, KEY1, NULL,   strlen(VALUE1), 0) < 0);
355*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_setxattr(&ring, FILENAME, KEY1, VALUE1, 0,              0) == 0);
356*25da2beaSAndroid Build Coastguard Worker 
357*25da2beaSAndroid Build Coastguard Worker 	/* Test reading attributes. */
358*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_getxattr(&ring, "complete garbage", KEY1, value, XATTR_SIZE) < 0);
359*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_getxattr(&ring, NULL,     KEY1, value, XATTR_SIZE) < 0);
360*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_getxattr(&ring, FILENAME, NULL, value, XATTR_SIZE) < 0);
361*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_getxattr(&ring, FILENAME, KEY1, NULL,  XATTR_SIZE) == 0);
362*25da2beaSAndroid Build Coastguard Worker 	assert(io_uring_getxattr(&ring, FILENAME, KEY1, value, 0)          == 0);
363*25da2beaSAndroid Build Coastguard Worker 
364*25da2beaSAndroid Build Coastguard Worker 	/* Cleanup. */
365*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
366*25da2beaSAndroid Build Coastguard Worker 	unlink(FILENAME);
367*25da2beaSAndroid Build Coastguard Worker 
368*25da2beaSAndroid Build Coastguard Worker 	return rc;
369*25da2beaSAndroid Build Coastguard Worker }
370*25da2beaSAndroid Build Coastguard Worker 
371*25da2beaSAndroid Build Coastguard Worker /* Test for invalid SQE, this will cause a segmentation fault if enabled. */
test_invalid_sqe(void)372*25da2beaSAndroid Build Coastguard Worker static int test_invalid_sqe(void)
373*25da2beaSAndroid Build Coastguard Worker {
374*25da2beaSAndroid Build Coastguard Worker #ifdef DESTRUCTIVE_TEST
375*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe = NULL;
376*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe = NULL;
377*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
378*25da2beaSAndroid Build Coastguard Worker 
379*25da2beaSAndroid Build Coastguard Worker 	/* Init io-uring queue. */
380*25da2beaSAndroid Build Coastguard Worker 	int ret = io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
381*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
382*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child: ring setup failed: %d\n", ret);
383*25da2beaSAndroid Build Coastguard Worker 		return -1;
384*25da2beaSAndroid Build Coastguard Worker 	}
385*25da2beaSAndroid Build Coastguard Worker 
386*25da2beaSAndroid Build Coastguard Worker 	/* Pass invalid SQE. */
387*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_setxattr(sqe, FILENAME, KEY1, VALUE1, strlen(VALUE1), 0);
388*25da2beaSAndroid Build Coastguard Worker 
389*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(&ring);
390*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
391*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_submit_and_wait: ret=%d\n", ret);
392*25da2beaSAndroid Build Coastguard Worker 		return -1;
393*25da2beaSAndroid Build Coastguard Worker 	}
394*25da2beaSAndroid Build Coastguard Worker 
395*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
396*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
397*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Error io_uring_wait_cqe: ret=%d\n", ret);
398*25da2beaSAndroid Build Coastguard Worker 		return -1;
399*25da2beaSAndroid Build Coastguard Worker 	}
400*25da2beaSAndroid Build Coastguard Worker 
401*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
402*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(&ring, cqe);
403*25da2beaSAndroid Build Coastguard Worker 
404*25da2beaSAndroid Build Coastguard Worker 	return ret;
405*25da2beaSAndroid Build Coastguard Worker #else
406*25da2beaSAndroid Build Coastguard Worker 	return 0;
407*25da2beaSAndroid Build Coastguard Worker #endif
408*25da2beaSAndroid Build Coastguard Worker }
409*25da2beaSAndroid Build Coastguard Worker 
410*25da2beaSAndroid Build Coastguard Worker /* Test driver. */
main(int argc,char * argv[])411*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
412*25da2beaSAndroid Build Coastguard Worker {
413*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
414*25da2beaSAndroid Build Coastguard Worker 		return 0;
415*25da2beaSAndroid Build Coastguard Worker 
416*25da2beaSAndroid Build Coastguard Worker 	if (test_fxattr())
417*25da2beaSAndroid Build Coastguard Worker 		return EXIT_FAILURE;
418*25da2beaSAndroid Build Coastguard Worker 	if (no_xattr)
419*25da2beaSAndroid Build Coastguard Worker 		return EXIT_SUCCESS;
420*25da2beaSAndroid Build Coastguard Worker 	if (test_xattr() || test_failure_fxattr() || test_failure_xattr() ||
421*25da2beaSAndroid Build Coastguard Worker 	    test_invalid_sqe())
422*25da2beaSAndroid Build Coastguard Worker 		return EXIT_FAILURE;
423*25da2beaSAndroid Build Coastguard Worker 
424*25da2beaSAndroid Build Coastguard Worker 	return EXIT_SUCCESS;
425*25da2beaSAndroid Build Coastguard Worker }
426