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 * Test Description: 8 * Verify that, 9 * 1. link() fails with -1 return value and sets errno to EPERM 10 * if oldpath is a directory. 11 * 2. link() fails with -1 return value and sets errno to EXDEV 12 * if oldpath and newpath are not on the same mounted file system( Linux 13 * permits a file system to be mounted at multiple points, but link() 14 * does not work across different mount points, even if the same 15 * file system is mounted on both. ). 16 * 3. link() fails with -1 return value and sets errno to EROFS 17 * if the file is on a read-only file system. 18 * 4. link() fails with -1 return value and sets errno to ELOOP 19 * if too many symbolic links were encountered in resolving path. 20 */ 21#include <errno.h> 22#include "tst_test.h" 23 24#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \ 25 S_IXGRP|S_IROTH|S_IXOTH) 26#define MNT_POINT "mntpoint" 27#define TEST_FILE "testfile" 28#define TEST_FILE1 "testfile1" 29#define TEST_FILE2 "mntpoint/file" 30#define TEST_FILE3 "mntpoint/testfile4" 31 32static char test_file4[PATH_MAX] = "."; 33static void setup(void); 34 35static struct tcase { 36 char *oldpath; 37 char *newpath; 38 int exp_errno; 39} tcases[] = { 40 {TEST_FILE1, TEST_FILE, EPERM}, 41 {TEST_FILE2, TEST_FILE, EXDEV}, 42 {TEST_FILE2, TEST_FILE3, EROFS}, 43 {test_file4, TEST_FILE, ELOOP}, 44}; 45 46static void link_verify(unsigned int i) 47{ 48 struct tcase *tc = &tcases[i]; 49 50 TEST(link(tc->oldpath, tc->newpath)); 51 52 if (TST_RET != -1) { 53 tst_res(TFAIL, "link() succeeded unexpectedly (%li)", 54 TST_RET); 55 return; 56 } 57 58 if (TST_ERR == tc->exp_errno) { 59 tst_res(TPASS | TTERRNO, "link() failed as expected"); 60 return; 61 } 62 63 tst_res(TFAIL | TTERRNO, 64 "link() failed unexpectedly; expected: %d - %s", 65 tc->exp_errno, tst_strerrno(tc->exp_errno)); 66} 67 68static void setup(void) 69{ 70 int i; 71 72 SAFE_MKDIR(TEST_FILE1, DIR_MODE); 73 74 SAFE_MKDIR("test_eloop", DIR_MODE); 75 SAFE_SYMLINK("../test_eloop", "test_eloop/test_eloop"); 76 for (i = 0; i < 43; i++) 77 strcat(test_file4, "/test_eloop"); 78} 79 80static struct tst_test test = { 81 .setup = setup, 82 .test = link_verify, 83 .tcnt = ARRAY_SIZE(tcases), 84 .needs_root = 1, 85 .needs_rofs = 1, 86 .mntpoint = MNT_POINT, 87}; 88