Message ID | 20240709-stat04-v2-1-2693a473a2ab@suse.com |
---|---|
State | Accepted |
Headers | show |
Series | symlink01 split | expand |
Hi all, > From: Andrea Cervesato <andrea.cervesato@suse.com> > This test has been extracted from symlink01 test and it checks that > stat() executed on file provide the same information of symlink linking > to it. > Reviewed-by: Li Wang <liwang@redhat.com> > Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> > --- > runtest/smoketest | 4 +- > runtest/syscalls | 4 +- > testcases/kernel/syscalls/stat/.gitignore | 2 + > testcases/kernel/syscalls/stat/stat04.c | 120 ++++++++++++++++++++++++++++++ > 4 files changed, 126 insertions(+), 4 deletions(-) > diff --git a/runtest/smoketest b/runtest/smoketest > index f6f14fd2b..5608417f9 100644 > --- a/runtest/smoketest > +++ b/runtest/smoketest > @@ -8,8 +8,8 @@ time01 time01 > wait02 wait02 > write01 write01 > symlink01 symlink01 > -stat04 symlink01 -T stat04 > -utime07 utime07 > +stat04 stat04 > +utime01A symlink01 -T utime01 nit: Why replace utime07 with utime01? I suggest to merge without this change (modify only stat04). Original test also tested ENOENT and ELOOP, but we have this in stat03.c. (you probably have been discussing this previously.) @Cyril: will you add your RBT (you reviewed v1). > rename01A symlink01 -T rename01 > splice02 splice02 -s 20 > df01_sh df01.sh > diff --git a/runtest/syscalls b/runtest/syscalls > index b6cadb2df..1e1203503 100644 > --- a/runtest/syscalls > +++ b/runtest/syscalls > @@ -1535,8 +1535,8 @@ stat02 stat02 > stat02_64 stat02_64 > stat03 stat03 > stat03_64 stat03_64 > -stat04 symlink01 -T stat04 > -stat04_64 symlink01 -T stat04_64 > +stat04 stat04 > +stat04_64 stat04_64 OT: Out of curiosity, I'm looking into testcases/kernel/syscalls/utils/newer_64.mk, I have no idea why there is utils/newer_64.h part. > statfs01 statfs01 > statfs01_64 statfs01_64 > diff --git a/testcases/kernel/syscalls/stat/.gitignore b/testcases/kernel/syscalls/stat/.gitignore > index fa0a4ce9f..0a62dc6ee 100644 > --- a/testcases/kernel/syscalls/stat/.gitignore > +++ b/testcases/kernel/syscalls/stat/.gitignore > @@ -4,3 +4,5 @@ > /stat02_64 > /stat03 > /stat03_64 > +/stat04 > +/stat04_64 > diff --git a/testcases/kernel/syscalls/stat/stat04.c b/testcases/kernel/syscalls/stat/stat04.c > new file mode 100644 > index 000000000..4609f02d8 > --- /dev/null > +++ b/testcases/kernel/syscalls/stat/stat04.c > @@ -0,0 +1,120 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later Also, original test was GPL v2 only, but with rewrite like this I guess we can have GPL v2+. > +/* > + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. > + * Author: David Fenner, Jon Hendrickson > + * Copyright (C) 2024 Andrea Cervesato <andrea.cervesato@suse.com> > + */ > + > +/*\ > + * [Description] > + * > + * This test checks that stat() executed on file provide the same information > + * of symlink linking to it. > + */ > + > +#include <stdlib.h> > +#include "tst_test.h" > + > +#define FILENAME "file.txt" > +#define MNTPOINT "mntpoint" > +#define SYMBNAME MNTPOINT"/file_symlink" > + > +static char symb_path[PATH_MAX]; > +static char file_path[PATH_MAX]; > +static struct stat *file_stat; > +static struct stat *symb_stat; > +static char *tmpdir; > + > +static void run(void) > +{ > + SAFE_STAT(file_path, file_stat); > + SAFE_STAT(symb_path, symb_stat); > + > + TST_EXP_EQ_LI(file_stat->st_dev, symb_stat->st_dev); > + TST_EXP_EQ_LI(file_stat->st_mode, symb_stat->st_mode); > + TST_EXP_EQ_LI(file_stat->st_nlink, symb_stat->st_nlink); > + TST_EXP_EQ_LI(file_stat->st_uid, symb_stat->st_uid); > + TST_EXP_EQ_LI(file_stat->st_gid, symb_stat->st_gid); > + TST_EXP_EQ_LI(file_stat->st_size, symb_stat->st_size); > + TST_EXP_EQ_LI(file_stat->st_atime, symb_stat->st_atime); > + TST_EXP_EQ_LI(file_stat->st_mtime, symb_stat->st_mtime); > + TST_EXP_EQ_LI(file_stat->st_ctime, symb_stat->st_ctime); > +} > + > +static void setup(void) > +{ > + char opt_bsize[32]; > + const char *const fs_opts[] = {opt_bsize, NULL}; > + struct stat sb; > + int pagesize; > + int fd; > + > + tmpdir = tst_get_tmpdir(); > + > + if (strlen(tmpdir) >= (PATH_MAX - strlen(FILENAME))) { > + tst_brk(TCONF, "Temporary folder name is too long. " > + "Can't create file"); > + } > + > + if (strlen(tmpdir) >= (PATH_MAX - strlen(SYMBNAME))) { > + tst_brk(TCONF, "Temporary folder name is too long. " > + "Can't create symbolic link"); > + } PATH_MAX is 4096, right? Is it really needed to test the length? > + > + /* change st_blksize / st_dev */ > + SAFE_STAT(".", &sb); > + pagesize = sb.st_blksize == 4096 ? 1024 : 4096; > + > + snprintf(opt_bsize, sizeof(opt_bsize), "-b %i", pagesize); > + SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL); > + SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, 0); Isn't symlink filesystem related? Shouldn't this be run on all_filesystems? But we could not force block size change. > + > + SAFE_TOUCH(FILENAME, 0777, NULL); > + > + /* change st_nlink */ > + SAFE_LINK(FILENAME, "linked_file"); > + > + /* change st_uid and st_gid */ > + SAFE_CHOWN(FILENAME, 1000, 1000); > + > + /* change st_size */ > + fd = SAFE_OPEN(FILENAME, O_WRONLY, 0777); > + tst_fill_fd(fd, 'a', TST_KB, 500); > + SAFE_CLOSE(fd); > + > + /* change st_atime / st_mtime / st_ctime */ > + usleep(1001000); > + > + memset(file_path, 0, PATH_MAX); > + snprintf(file_path, PATH_MAX, "%s/%s", tmpdir, FILENAME); > + > + memset(symb_path, 0, PATH_MAX); > + snprintf(symb_path, PATH_MAX, "%s/%s", tmpdir, SYMBNAME); > + > + SAFE_SYMLINK(file_path, symb_path); > +} > + > +static void cleanup(void) > +{ > + free(tmpdir); nit: I know that tst_get_tmpdir() is first thing in setup(), but I would still guard it with if (tmpdir) (code may change later). > + > + SAFE_UNLINK(SYMBNAME); nit: Ideally this would be guarded by flag that SAFE_SYMLINK(file_path, symb_path) got executed. > + > + if (tst_is_mounted(MNTPOINT)) > + SAFE_UMOUNT(MNTPOINT); > +} > + > +static struct tst_test test = { > + .setup = setup, > + .cleanup = cleanup, > + .test_all = run, > + .needs_root = 1, > + .needs_tmpdir = 1, nit: useless tag: needs_tmpdir (can be removed before merge). Reviewed-by: Petr Vorel <pvorel@suse.cz> Kind regards, Petr > + .needs_device = 1, > + .mntpoint = MNTPOINT, > + .bufs = (struct tst_buffers []) { > + {&file_stat, .size = sizeof(struct stat)}, > + {&symb_stat, .size = sizeof(struct stat)}, > + {} > + } > +};
Hi, On 7/9/24 23:13, Petr Vorel wrote: > Hi all, > >> From: Andrea Cervesato <andrea.cervesato@suse.com> >> This test has been extracted from symlink01 test and it checks that >> stat() executed on file provide the same information of symlink linking >> to it. >> Reviewed-by: Li Wang <liwang@redhat.com> >> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> >> --- >> runtest/smoketest | 4 +- >> runtest/syscalls | 4 +- >> testcases/kernel/syscalls/stat/.gitignore | 2 + >> testcases/kernel/syscalls/stat/stat04.c | 120 ++++++++++++++++++++++++++++++ >> 4 files changed, 126 insertions(+), 4 deletions(-) >> diff --git a/runtest/smoketest b/runtest/smoketest >> index f6f14fd2b..5608417f9 100644 >> --- a/runtest/smoketest >> +++ b/runtest/smoketest >> @@ -8,8 +8,8 @@ time01 time01 >> wait02 wait02 >> write01 write01 >> symlink01 symlink01 >> -stat04 symlink01 -T stat04 >> -utime07 utime07 >> +stat04 stat04 >> +utime01A symlink01 -T utime01 > nit: Why replace utime07 with utime01? I suggest to merge without this change > (modify only stat04). This must be an error > Original test also tested ENOENT and ELOOP, but we have this in stat03.c. > (you probably have been discussing this previously.) Yeah there's no need for that since it's tested somewhere else. > > @Cyril: will you add your RBT (you reviewed v1). > >> rename01A symlink01 -T rename01 >> splice02 splice02 -s 20 >> df01_sh df01.sh >> diff --git a/runtest/syscalls b/runtest/syscalls >> index b6cadb2df..1e1203503 100644 >> --- a/runtest/syscalls >> +++ b/runtest/syscalls >> @@ -1535,8 +1535,8 @@ stat02 stat02 >> stat02_64 stat02_64 >> stat03 stat03 >> stat03_64 stat03_64 >> -stat04 symlink01 -T stat04 >> -stat04_64 symlink01 -T stat04_64 >> +stat04 stat04 >> +stat04_64 stat04_64 > OT: Out of curiosity, I'm looking into > testcases/kernel/syscalls/utils/newer_64.mk, I have no idea why there is > utils/newer_64.h part. no idea... >> statfs01 statfs01 >> statfs01_64 statfs01_64 >> diff --git a/testcases/kernel/syscalls/stat/.gitignore b/testcases/kernel/syscalls/stat/.gitignore >> index fa0a4ce9f..0a62dc6ee 100644 >> --- a/testcases/kernel/syscalls/stat/.gitignore >> +++ b/testcases/kernel/syscalls/stat/.gitignore >> @@ -4,3 +4,5 @@ >> /stat02_64 >> /stat03 >> /stat03_64 >> +/stat04 >> +/stat04_64 >> diff --git a/testcases/kernel/syscalls/stat/stat04.c b/testcases/kernel/syscalls/stat/stat04.c >> new file mode 100644 >> index 000000000..4609f02d8 >> --- /dev/null >> +++ b/testcases/kernel/syscalls/stat/stat04.c >> @@ -0,0 +1,120 @@ >> +// SPDX-License-Identifier: GPL-2.0-or-later > Also, original test was GPL v2 only, but with rewrite like this I guess we can > have GPL v2+. > >> +/* >> + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. >> + * Author: David Fenner, Jon Hendrickson >> + * Copyright (C) 2024 Andrea Cervesato <andrea.cervesato@suse.com> >> + */ >> + >> +/*\ >> + * [Description] >> + * >> + * This test checks that stat() executed on file provide the same information >> + * of symlink linking to it. >> + */ >> + >> +#include <stdlib.h> >> +#include "tst_test.h" >> + >> +#define FILENAME "file.txt" >> +#define MNTPOINT "mntpoint" >> +#define SYMBNAME MNTPOINT"/file_symlink" >> + >> +static char symb_path[PATH_MAX]; >> +static char file_path[PATH_MAX]; >> +static struct stat *file_stat; >> +static struct stat *symb_stat; >> +static char *tmpdir; >> + >> +static void run(void) >> +{ >> + SAFE_STAT(file_path, file_stat); >> + SAFE_STAT(symb_path, symb_stat); >> + >> + TST_EXP_EQ_LI(file_stat->st_dev, symb_stat->st_dev); >> + TST_EXP_EQ_LI(file_stat->st_mode, symb_stat->st_mode); >> + TST_EXP_EQ_LI(file_stat->st_nlink, symb_stat->st_nlink); >> + TST_EXP_EQ_LI(file_stat->st_uid, symb_stat->st_uid); >> + TST_EXP_EQ_LI(file_stat->st_gid, symb_stat->st_gid); >> + TST_EXP_EQ_LI(file_stat->st_size, symb_stat->st_size); >> + TST_EXP_EQ_LI(file_stat->st_atime, symb_stat->st_atime); >> + TST_EXP_EQ_LI(file_stat->st_mtime, symb_stat->st_mtime); >> + TST_EXP_EQ_LI(file_stat->st_ctime, symb_stat->st_ctime); >> +} >> + >> +static void setup(void) >> +{ >> + char opt_bsize[32]; >> + const char *const fs_opts[] = {opt_bsize, NULL}; >> + struct stat sb; >> + int pagesize; >> + int fd; >> + >> + tmpdir = tst_get_tmpdir(); >> + >> + if (strlen(tmpdir) >= (PATH_MAX - strlen(FILENAME))) { >> + tst_brk(TCONF, "Temporary folder name is too long. " >> + "Can't create file"); >> + } >> + >> + if (strlen(tmpdir) >= (PATH_MAX - strlen(SYMBNAME))) { >> + tst_brk(TCONF, "Temporary folder name is too long. " >> + "Can't create symbolic link"); >> + } > PATH_MAX is 4096, right? Is it really needed to test the length? Yes, check previous conversation (easily buffer overflow). >> + >> + /* change st_blksize / st_dev */ >> + SAFE_STAT(".", &sb); >> + pagesize = sb.st_blksize == 4096 ? 1024 : 4096; >> + >> + snprintf(opt_bsize, sizeof(opt_bsize), "-b %i", pagesize); >> + SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL); >> + SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, 0); > Isn't symlink filesystem related? Shouldn't this be run on all_filesystems? > But we could not force block size change. This was suggested by @Cyril > >> + >> + SAFE_TOUCH(FILENAME, 0777, NULL); >> + >> + /* change st_nlink */ >> + SAFE_LINK(FILENAME, "linked_file"); >> + >> + /* change st_uid and st_gid */ >> + SAFE_CHOWN(FILENAME, 1000, 1000); >> + >> + /* change st_size */ >> + fd = SAFE_OPEN(FILENAME, O_WRONLY, 0777); >> + tst_fill_fd(fd, 'a', TST_KB, 500); >> + SAFE_CLOSE(fd); >> + >> + /* change st_atime / st_mtime / st_ctime */ >> + usleep(1001000); >> + >> + memset(file_path, 0, PATH_MAX); >> + snprintf(file_path, PATH_MAX, "%s/%s", tmpdir, FILENAME); >> + >> + memset(symb_path, 0, PATH_MAX); >> + snprintf(symb_path, PATH_MAX, "%s/%s", tmpdir, SYMBNAME); >> + >> + SAFE_SYMLINK(file_path, symb_path); >> +} >> + >> +static void cleanup(void) >> +{ >> + free(tmpdir); > nit: I know that tst_get_tmpdir() is first thing in setup(), but I would still > guard it with if (tmpdir) (code may change later). > >> + >> + SAFE_UNLINK(SYMBNAME); > nit: Ideally this would be guarded by flag that SAFE_SYMLINK(file_path, > symb_path) got executed. What if it doesn't? > >> + >> + if (tst_is_mounted(MNTPOINT)) >> + SAFE_UMOUNT(MNTPOINT); >> +} >> + >> +static struct tst_test test = { >> + .setup = setup, >> + .cleanup = cleanup, >> + .test_all = run, >> + .needs_root = 1, >> + .needs_tmpdir = 1, > nit: useless tag: needs_tmpdir (can be removed before merge). > > Reviewed-by: Petr Vorel <pvorel@suse.cz> > > Kind regards, > Petr > >> + .needs_device = 1, >> + .mntpoint = MNTPOINT, >> + .bufs = (struct tst_buffers []) { >> + {&file_stat, .size = sizeof(struct stat)}, >> + {&symb_stat, .size = sizeof(struct stat)}, >> + {} >> + } >> +}; Andrea
Hi Andrea, ... > > > +static void cleanup(void) > > > +{ > > > + free(tmpdir); > > nit: I know that tst_get_tmpdir() is first thing in setup(), but I would still > > guard it with if (tmpdir) (code may change later). > > > + > > > + SAFE_UNLINK(SYMBNAME); > > nit: Ideally this would be guarded by flag that SAFE_SYMLINK(file_path, > > symb_path) got executed. > What if it doesn't? Well, just one more WARN, no big deal. Just it might be misleading for a reviewer. I see you fixed it in v3, thanks! Kind regards, Petr
Hi! > PATH_MAX is 4096, right? Is it really needed to test the length? Contrary to the popular belief PATH_MAX is a limit for lenght of a single filesytem path component, i.e. directory or a file name. And yes I've seen bugreports for LTP where people pointed TMPDIR to a deep enough filesystem path for this to matter. Anyways I've proposed to allocate the paths instead with asprintf(). > > + > > + /* change st_blksize / st_dev */ > > + SAFE_STAT(".", &sb); > > + pagesize = sb.st_blksize == 4096 ? 1024 : 4096; > > + > > + snprintf(opt_bsize, sizeof(opt_bsize), "-b %i", pagesize); > > + SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL); > > + SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, 0); > > Isn't symlink filesystem related? Shouldn't this be run on all_filesystems? Hmm, I was assuming that symlink was a generic funcionality, but thinking about it the symlink data has to be stored in the filesystem so I suppose that there is some filesystem specific code to be tested after all. I guess that this could stil be implemented but we would have to add support for multiple devices. I can have a look later on, but I wouldn't block this patch because of that. > > + > > + SAFE_TOUCH(FILENAME, 0777, NULL); > > + > > + /* change st_nlink */ > > + SAFE_LINK(FILENAME, "linked_file"); > > + > > + /* change st_uid and st_gid */ > > + SAFE_CHOWN(FILENAME, 1000, 1000); > > + > > + /* change st_size */ > > + fd = SAFE_OPEN(FILENAME, O_WRONLY, 0777); > > + tst_fill_fd(fd, 'a', TST_KB, 500); > > + SAFE_CLOSE(fd); > > + > > + /* change st_atime / st_mtime / st_ctime */ > > + usleep(1001000); > > + > > + memset(file_path, 0, PATH_MAX); > > + snprintf(file_path, PATH_MAX, "%s/%s", tmpdir, FILENAME); > > + > > + memset(symb_path, 0, PATH_MAX); > > + snprintf(symb_path, PATH_MAX, "%s/%s", tmpdir, SYMBNAME); > > + > > + SAFE_SYMLINK(file_path, symb_path); > > +} > > + > > +static void cleanup(void) > > +{ > > + free(tmpdir); > nit: I know that tst_get_tmpdir() is first thing in setup(), but I would still > guard it with if (tmpdir) (code may change later). > > > + > > + SAFE_UNLINK(SYMBNAME); > nit: Ideally this would be guarded by flag that SAFE_SYMLINK(file_path, > symb_path) got executed. I do not think that we need to unlink the symlink, it should be removed by the test library when the temorary directory is removed. Or is there a problem with that?
diff --git a/runtest/smoketest b/runtest/smoketest index f6f14fd2b..5608417f9 100644 --- a/runtest/smoketest +++ b/runtest/smoketest @@ -8,8 +8,8 @@ time01 time01 wait02 wait02 write01 write01 symlink01 symlink01 -stat04 symlink01 -T stat04 -utime07 utime07 +stat04 stat04 +utime01A symlink01 -T utime01 rename01A symlink01 -T rename01 splice02 splice02 -s 20 df01_sh df01.sh diff --git a/runtest/syscalls b/runtest/syscalls index b6cadb2df..1e1203503 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1535,8 +1535,8 @@ stat02 stat02 stat02_64 stat02_64 stat03 stat03 stat03_64 stat03_64 -stat04 symlink01 -T stat04 -stat04_64 symlink01 -T stat04_64 +stat04 stat04 +stat04_64 stat04_64 statfs01 statfs01 statfs01_64 statfs01_64 diff --git a/testcases/kernel/syscalls/stat/.gitignore b/testcases/kernel/syscalls/stat/.gitignore index fa0a4ce9f..0a62dc6ee 100644 --- a/testcases/kernel/syscalls/stat/.gitignore +++ b/testcases/kernel/syscalls/stat/.gitignore @@ -4,3 +4,5 @@ /stat02_64 /stat03 /stat03_64 +/stat04 +/stat04_64 diff --git a/testcases/kernel/syscalls/stat/stat04.c b/testcases/kernel/syscalls/stat/stat04.c new file mode 100644 index 000000000..4609f02d8 --- /dev/null +++ b/testcases/kernel/syscalls/stat/stat04.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * Author: David Fenner, Jon Hendrickson + * Copyright (C) 2024 Andrea Cervesato <andrea.cervesato@suse.com> + */ + +/*\ + * [Description] + * + * This test checks that stat() executed on file provide the same information + * of symlink linking to it. + */ + +#include <stdlib.h> +#include "tst_test.h" + +#define FILENAME "file.txt" +#define MNTPOINT "mntpoint" +#define SYMBNAME MNTPOINT"/file_symlink" + +static char symb_path[PATH_MAX]; +static char file_path[PATH_MAX]; +static struct stat *file_stat; +static struct stat *symb_stat; +static char *tmpdir; + +static void run(void) +{ + SAFE_STAT(file_path, file_stat); + SAFE_STAT(symb_path, symb_stat); + + TST_EXP_EQ_LI(file_stat->st_dev, symb_stat->st_dev); + TST_EXP_EQ_LI(file_stat->st_mode, symb_stat->st_mode); + TST_EXP_EQ_LI(file_stat->st_nlink, symb_stat->st_nlink); + TST_EXP_EQ_LI(file_stat->st_uid, symb_stat->st_uid); + TST_EXP_EQ_LI(file_stat->st_gid, symb_stat->st_gid); + TST_EXP_EQ_LI(file_stat->st_size, symb_stat->st_size); + TST_EXP_EQ_LI(file_stat->st_atime, symb_stat->st_atime); + TST_EXP_EQ_LI(file_stat->st_mtime, symb_stat->st_mtime); + TST_EXP_EQ_LI(file_stat->st_ctime, symb_stat->st_ctime); +} + +static void setup(void) +{ + char opt_bsize[32]; + const char *const fs_opts[] = {opt_bsize, NULL}; + struct stat sb; + int pagesize; + int fd; + + tmpdir = tst_get_tmpdir(); + + if (strlen(tmpdir) >= (PATH_MAX - strlen(FILENAME))) { + tst_brk(TCONF, "Temporary folder name is too long. " + "Can't create file"); + } + + if (strlen(tmpdir) >= (PATH_MAX - strlen(SYMBNAME))) { + tst_brk(TCONF, "Temporary folder name is too long. " + "Can't create symbolic link"); + } + + /* change st_blksize / st_dev */ + SAFE_STAT(".", &sb); + pagesize = sb.st_blksize == 4096 ? 1024 : 4096; + + snprintf(opt_bsize, sizeof(opt_bsize), "-b %i", pagesize); + SAFE_MKFS(tst_device->dev, tst_device->fs_type, fs_opts, NULL); + SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, 0); + + SAFE_TOUCH(FILENAME, 0777, NULL); + + /* change st_nlink */ + SAFE_LINK(FILENAME, "linked_file"); + + /* change st_uid and st_gid */ + SAFE_CHOWN(FILENAME, 1000, 1000); + + /* change st_size */ + fd = SAFE_OPEN(FILENAME, O_WRONLY, 0777); + tst_fill_fd(fd, 'a', TST_KB, 500); + SAFE_CLOSE(fd); + + /* change st_atime / st_mtime / st_ctime */ + usleep(1001000); + + memset(file_path, 0, PATH_MAX); + snprintf(file_path, PATH_MAX, "%s/%s", tmpdir, FILENAME); + + memset(symb_path, 0, PATH_MAX); + snprintf(symb_path, PATH_MAX, "%s/%s", tmpdir, SYMBNAME); + + SAFE_SYMLINK(file_path, symb_path); +} + +static void cleanup(void) +{ + free(tmpdir); + + SAFE_UNLINK(SYMBNAME); + + if (tst_is_mounted(MNTPOINT)) + SAFE_UMOUNT(MNTPOINT); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = run, + .needs_root = 1, + .needs_tmpdir = 1, + .needs_device = 1, + .mntpoint = MNTPOINT, + .bufs = (struct tst_buffers []) { + {&file_stat, .size = sizeof(struct stat)}, + {&symb_stat, .size = sizeof(struct stat)}, + {} + } +};