1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2014 Fujitsu Ltd. 4 * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com> 5 */ 6/* 7 * DESCRIPTION 8 * check mkdirat() with various error conditions that should produce 9 * ELOOP and EROFS. 10 */ 11 12#define _GNU_SOURCE 13#include "tst_test.h" 14#include "lapi/mkdirat.h" 15 16#define MNT_POINT "mntpoint" 17#define TEST_DIR "mntpoint/test_dir" 18#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 19 S_IXGRP|S_IROTH|S_IXOTH) 20 21static int dir_fd; 22static int cur_fd = AT_FDCWD; 23static char test_dir[PATH_MAX] = "."; 24 25static struct tcase { 26 int *dirfd; 27 char *pathname; 28 int exp_errno; 29} tcases[] = { 30 {&dir_fd, TEST_DIR, EROFS}, 31 {&cur_fd, TEST_DIR, EROFS}, 32 {&dir_fd, test_dir, ELOOP}, 33 {&cur_fd, test_dir, ELOOP}, 34}; 35 36static void setup(void) 37{ 38 unsigned int i; 39 40 dir_fd = SAFE_OPEN(".", O_DIRECTORY); 41 42 SAFE_MKDIR("test_eloop", DIR_MODE); 43 SAFE_SYMLINK("../test_eloop", "test_eloop/test_eloop"); 44 45 /* 46 * NOTE: the ELOOP test is written based on that the consecutive 47 * symlinks limits in kernel is hardwired to 40. 48 */ 49 for (i = 0; i < 43; i++) 50 strcat(test_dir, "/test_eloop"); 51} 52 53static void mkdirat_verify(unsigned int i) 54{ 55 struct tcase *test = &tcases[i]; 56 57 TEST(mkdirat(*test->dirfd, test->pathname, 0777)); 58 59 if (TST_RET != -1) { 60 tst_res(TFAIL, "mkdirat() succeeded unexpectedly (%li)", 61 TST_RET); 62 return; 63 } 64 65 if (TST_ERR == test->exp_errno) { 66 tst_res(TPASS | TTERRNO, "mkdirat() failed as expected"); 67 return; 68 } 69 70 tst_res(TFAIL | TTERRNO, 71 "mkdirat() failed unexpectedly; expected: %d - %s", 72 test->exp_errno, tst_strerrno(test->exp_errno)); 73} 74 75static struct tst_test test = { 76 .setup = setup, 77 .test = mkdirat_verify, 78 .tcnt = ARRAY_SIZE(tcases), 79 .needs_root = 1, 80 .needs_rofs = 1, 81 .mntpoint = MNT_POINT, 82}; 83