• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
4  * Author: Yang Xu <xuyang2018.jy@cn.jujitsu.com>
5  *
6  * This is a basic ioctl error test about loopdevice
7  * LOOP_SET_BLOCK_SIZE.
8  */
9 
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <stdlib.h>
14 #include "lapi/loop.h"
15 #include "tst_test.h"
16 
17 static char dev_path[1024];
18 static int dev_num, dev_fd, attach_flag;
19 static unsigned int invalid_value, half_value, unalign_value;
20 
21 static struct tcase {
22 	unsigned int *setvalue;
23 	int exp_err;
24 	char *message;
25 } tcases[] = {
26 	{&half_value, EINVAL, "arg < 512"},
27 	{&invalid_value, EINVAL, "arg > PAGE_SIZE"},
28 	{&unalign_value, EINVAL, "arg != power_of_2"},
29 };
30 
verify_ioctl_loop(unsigned int n)31 static void verify_ioctl_loop(unsigned int n)
32 {
33 	struct tcase *tc = &tcases[n];
34 
35 	tst_res(TINFO, "%s", tc->message);
36 	TEST(ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, *(tc->setvalue)));
37 	if (TST_RET == 0) {
38 		tst_res(TFAIL, "LOOP_SET_BLOCK_SIZE succeed unexpectedly");
39 		return;
40 	}
41 
42 	if (TST_ERR == tc->exp_err) {
43 		tst_res(TPASS | TTERRNO, "LOOP_SET_BLOCK_SIZE failed as expected");
44 	} else {
45 		tst_res(TFAIL | TTERRNO, "LOOP_SET_BLOCK_SIZE failed expected %s got",
46 				tst_strerrno(tc->exp_err));
47 	}
48 }
49 
setup(void)50 static void setup(void)
51 {
52 	unsigned int pg_size;
53 
54 	dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
55 	if (dev_num < 0)
56 		tst_brk(TBROK, "Failed to find free loop device");
57 
58 	tst_fill_file("test.img", 0, 1024, 1024);
59 	tst_attach_device(dev_path, "test.img");
60 	attach_flag = 1;
61 	half_value = 256;
62 	pg_size = getpagesize();
63 	invalid_value = pg_size * 2 ;
64 	unalign_value = pg_size - 1;
65 
66 	dev_fd = SAFE_OPEN(dev_path, O_RDWR);
67 
68 	if (ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 512) && errno == EINVAL)
69 		tst_brk(TCONF, "LOOP_SET_BLOCK_SIZE is not supported");
70 }
71 
cleanup(void)72 static void cleanup(void)
73 {
74 	if (dev_fd > 0)
75 		SAFE_CLOSE(dev_fd);
76 	if (attach_flag)
77 		tst_detach_device(dev_path);
78 }
79 
80 static struct tst_test test = {
81 	.setup = setup,
82 	.cleanup = cleanup,
83 	.test = verify_ioctl_loop,
84 	.tcnt = ARRAY_SIZE(tcases),
85 	.needs_root = 1,
86 	.needs_tmpdir = 1,
87 	.needs_drivers = (const char *const []) {
88 		"loop",
89 		NULL
90 	}
91 };
92