NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/48958: kevent(2): EVFILT_VNODE filter miscounting hardlinks
The following reply was made to PR kern/48958; it has been noted by GNATS.
From: rudolf <netbsd%eq.cz@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/48958: kevent(2): EVFILT_VNODE filter miscounting hardlinks
Date: Wed, 02 Jul 2014 14:09:58 +0200
This is a multi-part message in MIME format.
--------------000306090607060304090203
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Attached is a test program with two test cases for PR kern/48958. It is
suitable for inclusion to the /usr/src/tests/kernel/kqueue directory.
Tested under NetBSD 6.1_STABLE amd64.
r.
--------------000306090607060304090203
Content-Type: text/x-csrc;
name="t_vnode1.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="t_vnode1.c"
#include <sys/event.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <atf-c.h>
static const char *dir_target = "dir";
static const char *dir_inside = "dir/foo";
static const char *dir_outside = "bar";
int init_kqueue(int);
int init_target(void);
void cleanup(void);
int
init_target()
{
if (mkdir(dir_target, S_IRWXU) < 0) {
return -1;
} else {
return open(dir_target, O_RDONLY, 0);
}
}
int
init_kqueue(int target_fd)
{
int kq, ke;
struct kevent eventlist[1];
kq = kqueue();
if (kq < 0) {
return -1;
}
EV_SET(&eventlist[0], target_fd, EVFILT_VNODE,
EV_ADD | EV_ONESHOT, NOTE_DELETE |
NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB |
NOTE_LINK | NOTE_RENAME | NOTE_REVOKE, 0, 0);
ke = kevent(kq, eventlist, 1, NULL, 0, NULL);
if (ke < 0) {
return -1;
}
return kq;
}
void
cleanup(void)
{
(void)unlink(dir_inside);
(void)unlink(dir_outside);
(void)unlink(dir_target);
}
ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_in);
ATF_TC_HEAD(dir_note_link_mv_dir_in, tc)
{
atf_tc_set_md_var(tc, "descr", "This test case ensures "
"that kevent(2) returns NOTE_LINK for the directory "
"'foo' if a directory 'bar' is renamed to 'foo/bar'.");
}
ATF_TC_BODY(dir_note_link_mv_dir_in, tc)
{
int kq, target;
struct kevent changelist[1];
struct timespec ts = {0, 0};
target = init_target();
ATF_REQUIRE(target != -1);
ATF_REQUIRE(mkdir(dir_outside, S_IRWXU) != -1);
kq = init_kqueue(target);
ATF_REQUIRE(kq != -1);
ATF_REQUIRE(rename(dir_outside, dir_inside) != -1);
ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1);
ATF_REQUIRE(changelist[0].fflags & NOTE_LINK);
}
ATF_TC_CLEANUP(dir_note_link_mv_dir_in, tc)
{
cleanup();
}
ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_out);
ATF_TC_HEAD(dir_note_link_mv_dir_out, tc)
{
atf_tc_set_md_var(tc, "descr", "This test case ensures "
"that kevent(2) returns NOTE_LINK for the directory "
"'foo' if a directory 'foo/bar' is renamed to 'bar'.");
}
ATF_TC_BODY(dir_note_link_mv_dir_out, tc)
{
int kq, target;
struct kevent changelist[1];
struct timespec ts = {0, 0};
target = init_target();
ATF_REQUIRE(target != -1);
ATF_REQUIRE(mkdir(dir_inside, S_IRWXU) != -1);
kq = init_kqueue(target);
ATF_REQUIRE(kq != -1);
ATF_REQUIRE(rename(dir_inside, dir_outside) != -1);
ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1);
ATF_REQUIRE(changelist[0].fflags & NOTE_LINK);
}
ATF_TC_CLEANUP(dir_note_link_mv_dir_out, tc)
{
cleanup();
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, dir_note_link_mv_dir_in);
ATF_TP_ADD_TC(tp, dir_note_link_mv_dir_out);
return atf_no_error();
}
--------------000306090607060304090203--
Home |
Main Index |
Thread Index |
Old Index