1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or 6f08c3bdfSopenharmony_ci * modify it under the terms of the GNU General Public License as 7f08c3bdfSopenharmony_ci * published by the Free Software Foundation; either version 2 of 8f08c3bdfSopenharmony_ci * the License, or (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13f08c3bdfSopenharmony_ci * GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write the Free Software Foundation, 17f08c3bdfSopenharmony_ci * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * This is the main of your user space test program, 20f08c3bdfSopenharmony_ci * which will open the correct kernel bioule, find the 21f08c3bdfSopenharmony_ci * file descriptor value and use that value to make 22f08c3bdfSopenharmony_ci * ioctl calls to the system 23f08c3bdfSopenharmony_ci * 24f08c3bdfSopenharmony_ci * Use the ki_generic and other ki_testname functions 25f08c3bdfSopenharmony_ci * to abstract the calls from the main 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * FILE : user_tbio.c 28f08c3bdfSopenharmony_ci * USAGE : kernel_space:./load_tbio.sh 29f08c3bdfSopenharmony_ci * user_space :./test_bio 30f08c3bdfSopenharmony_ci * 31f08c3bdfSopenharmony_ci * DESCRIPTION : The bioule will test block i/o layer for kernel 2.5 32f08c3bdfSopenharmony_ci * REQUIREMENTS: 33f08c3bdfSopenharmony_ci * 1) glibc 2.1.91 or above. 34f08c3bdfSopenharmony_ci * 35f08c3bdfSopenharmony_ci * HISTORY : 36f08c3bdfSopenharmony_ci * 11/19/2003 Kai Zhao (ltcd3@cn.ibm.com) 37f08c3bdfSopenharmony_ci * 38f08c3bdfSopenharmony_ci * CODE COVERAGE: 74.9% - fs/bio.c (Total Coverage) 39f08c3bdfSopenharmony_ci * 40f08c3bdfSopenharmony_ci */ 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci#define _GNU_SOURCE 43f08c3bdfSopenharmony_ci#include <stdio.h> 44f08c3bdfSopenharmony_ci#include <stdlib.h> 45f08c3bdfSopenharmony_ci#include <sys/stat.h> 46f08c3bdfSopenharmony_ci#include <sys/ioctl.h> 47f08c3bdfSopenharmony_ci#include <fcntl.h> 48f08c3bdfSopenharmony_ci#include <errno.h> 49f08c3bdfSopenharmony_ci#include <sys/sysmacros.h> 50f08c3bdfSopenharmony_ci#include <sys/types.h> 51f08c3bdfSopenharmony_ci#include <linux/kernel.h> 52f08c3bdfSopenharmony_ci#include <unistd.h> 53f08c3bdfSopenharmony_ci#include <string.h> 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci#include "test.h" 56f08c3bdfSopenharmony_ci#include "safe_macros.h" 57f08c3bdfSopenharmony_ci#include "old_module.h" 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci#include "../tbio_kernel/tbio.h" 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_cichar *TCID = TBIO_DEVICE_NAME; 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic const char module_name[] = "ltp_tbio.ko"; 64f08c3bdfSopenharmony_cistatic int module_loaded; 65f08c3bdfSopenharmony_cistatic int tbio_fd = -1; 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_civoid cleanup(void) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci if (tbio_fd != -1) { 71f08c3bdfSopenharmony_ci close(tbio_fd); 72f08c3bdfSopenharmony_ci tbio_fd = -1; 73f08c3bdfSopenharmony_ci } 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci if (module_loaded) 76f08c3bdfSopenharmony_ci tst_module_unload(NULL, module_name); 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci if (unlink(DEVICE_NAME) && (errno != ENOENT)) 79f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "unlink failed"); 80f08c3bdfSopenharmony_ci} 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_civoid setup(void) 84f08c3bdfSopenharmony_ci{ 85f08c3bdfSopenharmony_ci dev_t devt; 86f08c3bdfSopenharmony_ci struct stat st; 87f08c3bdfSopenharmony_ci unsigned int i, valid_node_created; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci tst_require_root(); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci tst_module_load(cleanup, module_name, NULL); 92f08c3bdfSopenharmony_ci module_loaded = 1; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci SAFE_FILE_SCANF(cleanup, "/sys/class/block/tbio/dev", 95f08c3bdfSopenharmony_ci "%d:0", &TBIO_MAJOR); 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci devt = makedev(TBIO_MAJOR, 0); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci /* 100f08c3bdfSopenharmony_ci * Wait until udev creates the device node. 101f08c3bdfSopenharmony_ci * If the node is not created or invalid, create it manually. 102f08c3bdfSopenharmony_ci */ 103f08c3bdfSopenharmony_ci valid_node_created = 0; 104f08c3bdfSopenharmony_ci for (i = 0; i < 50; i++) { 105f08c3bdfSopenharmony_ci if (stat(DEVICE_NAME, &st)) { 106f08c3bdfSopenharmony_ci if (errno != ENOENT) 107f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, cleanup, 108f08c3bdfSopenharmony_ci "stat() failed"); 109f08c3bdfSopenharmony_ci } else { 110f08c3bdfSopenharmony_ci if ((st.st_mode & S_IFBLK) && (st.st_rdev == devt)) { 111f08c3bdfSopenharmony_ci valid_node_created = 1; 112f08c3bdfSopenharmony_ci break; 113f08c3bdfSopenharmony_ci } 114f08c3bdfSopenharmony_ci } 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci usleep(100000); 117f08c3bdfSopenharmony_ci } 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci if (!valid_node_created) { 120f08c3bdfSopenharmony_ci tst_resm(TINFO, 121f08c3bdfSopenharmony_ci "The device file was not created by udev, " 122f08c3bdfSopenharmony_ci "proceeding with manual creation"); 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci if (unlink(DEVICE_NAME) && (errno != ENOENT)) 125f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, cleanup, "unlink() failed"); 126f08c3bdfSopenharmony_ci if (mknod(DEVICE_NAME, S_IFBLK | S_IRUSR | S_IWUSR | 127f08c3bdfSopenharmony_ci S_IRGRP | S_IWGRP, devt)) 128f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, cleanup, "mknod() failed"); 129f08c3bdfSopenharmony_ci } 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci tbio_fd = SAFE_OPEN(cleanup, DEVICE_NAME, O_RDWR); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci tst_resm(TINFO, "Device opened successfully "); 134f08c3bdfSopenharmony_ci} 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_ciint tbio_to_dev(int fd, int flag) 138f08c3bdfSopenharmony_ci{ 139f08c3bdfSopenharmony_ci int rc; 140f08c3bdfSopenharmony_ci tbio_interface_t bif; 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci memset(&bif, 0, sizeof(tbio_interface_t)); 143f08c3bdfSopenharmony_ci rc = posix_memalign(&bif.data, 512, 1024); 144f08c3bdfSopenharmony_ci if (rc) { 145f08c3bdfSopenharmony_ci tst_resm(TINFO, "posix_memalign failed"); 146f08c3bdfSopenharmony_ci return -1; 147f08c3bdfSopenharmony_ci } 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_ci strcpy(bif.data, "User space data"); 150f08c3bdfSopenharmony_ci bif.data_len = 1024; 151f08c3bdfSopenharmony_ci bif.direction = TBIO_TO_DEV; 152f08c3bdfSopenharmony_ci bif.cmd = SAFE_MALLOC(cleanup, 6); 153f08c3bdfSopenharmony_ci if (bif.cmd == NULL) { 154f08c3bdfSopenharmony_ci tst_resm(TINFO, "malloc cmd space failed"); 155f08c3bdfSopenharmony_ci free(bif.data); 156f08c3bdfSopenharmony_ci return -1; 157f08c3bdfSopenharmony_ci } 158f08c3bdfSopenharmony_ci strcpy(bif.cmd, "WRITE"); 159f08c3bdfSopenharmony_ci bif.cmd_len = 6; 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_ci rc = ioctl(fd, flag, &bif); 162f08c3bdfSopenharmony_ci if (rc) { 163f08c3bdfSopenharmony_ci free(bif.data); 164f08c3bdfSopenharmony_ci free(bif.cmd); 165f08c3bdfSopenharmony_ci tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV"); 166f08c3bdfSopenharmony_ci return rc; 167f08c3bdfSopenharmony_ci } 168f08c3bdfSopenharmony_ci 169f08c3bdfSopenharmony_ci free(bif.data); 170f08c3bdfSopenharmony_ci free(bif.cmd); 171f08c3bdfSopenharmony_ci 172f08c3bdfSopenharmony_ci return 0; 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ci} 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ciint tbio_from_dev(int fd, int flag) 177f08c3bdfSopenharmony_ci{ 178f08c3bdfSopenharmony_ci int rc; 179f08c3bdfSopenharmony_ci tbio_interface_t bif; 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci memset(&bif, 0, sizeof(tbio_interface_t)); 182f08c3bdfSopenharmony_ci rc = posix_memalign(&bif.data, 512, 1024); 183f08c3bdfSopenharmony_ci if (rc) { 184f08c3bdfSopenharmony_ci tst_resm(TINFO, "posix_memalign failed"); 185f08c3bdfSopenharmony_ci return -1; 186f08c3bdfSopenharmony_ci } 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci memset(bif.data, 0, 1024); 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci bif.data_len = 1024; 191f08c3bdfSopenharmony_ci bif.direction = TBIO_FROM_DEV; 192f08c3bdfSopenharmony_ci bif.cmd = SAFE_MALLOC(cleanup, 5); 193f08c3bdfSopenharmony_ci if (bif.cmd == NULL) { 194f08c3bdfSopenharmony_ci tst_resm(TINFO, "malloc cmd space failed"); 195f08c3bdfSopenharmony_ci free(bif.data); 196f08c3bdfSopenharmony_ci return -1; 197f08c3bdfSopenharmony_ci } 198f08c3bdfSopenharmony_ci strcpy(bif.cmd, "READ"); 199f08c3bdfSopenharmony_ci bif.cmd_len = 5; 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci rc = ioctl(fd, flag, &bif); 202f08c3bdfSopenharmony_ci if (rc) { 203f08c3bdfSopenharmony_ci free(bif.data); 204f08c3bdfSopenharmony_ci free(bif.cmd); 205f08c3bdfSopenharmony_ci tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV"); 206f08c3bdfSopenharmony_ci return rc; 207f08c3bdfSopenharmony_ci } 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci if (strcmp(bif.data, "User space data")) { 210f08c3bdfSopenharmony_ci tst_resm(TINFO, "TBIO_FROM_DEV failed"); 211f08c3bdfSopenharmony_ci free(bif.data); 212f08c3bdfSopenharmony_ci free(bif.cmd); 213f08c3bdfSopenharmony_ci return -1; 214f08c3bdfSopenharmony_ci } 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci free(bif.data); 217f08c3bdfSopenharmony_ci free(bif.cmd); 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ci return 0; 220f08c3bdfSopenharmony_ci 221f08c3bdfSopenharmony_ci} 222f08c3bdfSopenharmony_ci 223f08c3bdfSopenharmony_ciint tbio_split_to_dev(int fd, int flag) 224f08c3bdfSopenharmony_ci{ 225f08c3bdfSopenharmony_ci int rc; 226f08c3bdfSopenharmony_ci tbio_interface_t bif; 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci memset(&bif, 0, sizeof(tbio_interface_t)); 229f08c3bdfSopenharmony_ci rc = posix_memalign(&bif.data, 512, 2048); 230f08c3bdfSopenharmony_ci if (rc) { 231f08c3bdfSopenharmony_ci tst_resm(TINFO, "posix_memalign failed"); 232f08c3bdfSopenharmony_ci return -1; 233f08c3bdfSopenharmony_ci } 234f08c3bdfSopenharmony_ci 235f08c3bdfSopenharmony_ci strcpy(bif.data, "User space data"); 236f08c3bdfSopenharmony_ci bif.data_len = 2048; 237f08c3bdfSopenharmony_ci bif.direction = TBIO_TO_DEV; 238f08c3bdfSopenharmony_ci bif.cmd = SAFE_MALLOC(cleanup, 6); 239f08c3bdfSopenharmony_ci if (bif.cmd == NULL) { 240f08c3bdfSopenharmony_ci tst_resm(TINFO, "malloc cmd space failed"); 241f08c3bdfSopenharmony_ci free(bif.data); 242f08c3bdfSopenharmony_ci return -1; 243f08c3bdfSopenharmony_ci } 244f08c3bdfSopenharmony_ci strcpy(bif.cmd, "WRITE"); 245f08c3bdfSopenharmony_ci bif.cmd_len = 6; 246f08c3bdfSopenharmony_ci 247f08c3bdfSopenharmony_ci rc = ioctl(fd, flag, &bif); 248f08c3bdfSopenharmony_ci if (rc) { 249f08c3bdfSopenharmony_ci free(bif.data); 250f08c3bdfSopenharmony_ci free(bif.cmd); 251f08c3bdfSopenharmony_ci tst_resm(TINFO, "Ioctl error for TBIO_TO_DEV"); 252f08c3bdfSopenharmony_ci return rc; 253f08c3bdfSopenharmony_ci } 254f08c3bdfSopenharmony_ci 255f08c3bdfSopenharmony_ci free(bif.data); 256f08c3bdfSopenharmony_ci free(bif.cmd); 257f08c3bdfSopenharmony_ci 258f08c3bdfSopenharmony_ci return 0; 259f08c3bdfSopenharmony_ci 260f08c3bdfSopenharmony_ci} 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ciint ki_generic(int fd, int flag) 263f08c3bdfSopenharmony_ci{ 264f08c3bdfSopenharmony_ci tbio_interface_t bif; 265f08c3bdfSopenharmony_ci 266f08c3bdfSopenharmony_ci int rc = ioctl(fd, flag, &bif); 267f08c3bdfSopenharmony_ci if (rc) 268f08c3bdfSopenharmony_ci tst_resm(TINFO | TERRNO, "ioctl error"); 269f08c3bdfSopenharmony_ci 270f08c3bdfSopenharmony_ci return rc; 271f08c3bdfSopenharmony_ci} 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci 274f08c3bdfSopenharmony_ciint main(void) 275f08c3bdfSopenharmony_ci{ 276f08c3bdfSopenharmony_ci setup(); 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci if (ki_generic(tbio_fd, LTP_TBIO_ALLOC)) 279f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_ALLOC test"); 280f08c3bdfSopenharmony_ci else 281f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_ALLOC test"); 282f08c3bdfSopenharmony_ci 283f08c3bdfSopenharmony_ci if (ki_generic(tbio_fd, LTP_TBIO_CLONE)) 284f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_CLONE test"); 285f08c3bdfSopenharmony_ci else 286f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_CLONE test"); 287f08c3bdfSopenharmony_ci 288f08c3bdfSopenharmony_ci if (ki_generic(tbio_fd, LTP_TBIO_GET_NR_VECS)) 289f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_GET_NR_VECS test"); 290f08c3bdfSopenharmony_ci else 291f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_GET_NR_VECS test"); 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ci if (ki_generic(tbio_fd, LTP_TBIO_ADD_PAGE)) 294f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_ADD_PAGE test"); 295f08c3bdfSopenharmony_ci else 296f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_ADD_PAGE test"); 297f08c3bdfSopenharmony_ci 298f08c3bdfSopenharmony_ci if (tbio_split_to_dev(tbio_fd, LTP_TBIO_SPLIT)) 299f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_SPLIT:write to dev"); 300f08c3bdfSopenharmony_ci else 301f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_SPLIT:write to dev"); 302f08c3bdfSopenharmony_ci 303f08c3bdfSopenharmony_ci if (tbio_to_dev(tbio_fd, LTP_TBIO_DO_IO)) 304f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:write to dev"); 305f08c3bdfSopenharmony_ci else 306f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_DO_IO:write to dev"); 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_ci if (tbio_from_dev(tbio_fd, LTP_TBIO_DO_IO)) 309f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_DO_IO:read from dev"); 310f08c3bdfSopenharmony_ci else 311f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_DO_IO:read from dev"); 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ci if (ki_generic(tbio_fd, LTP_TBIO_PUT)) 314f08c3bdfSopenharmony_ci tst_resm(TFAIL, "failed on LTP_TBIO_PUT test"); 315f08c3bdfSopenharmony_ci else 316f08c3bdfSopenharmony_ci tst_resm(TPASS, "success on LTP_TBIO_PUT test"); 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci cleanup(); 319f08c3bdfSopenharmony_ci 320f08c3bdfSopenharmony_ci tst_exit(); 321f08c3bdfSopenharmony_ci} 322