Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143855096
D41600.id126574.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D41600.id126574.diff
View Options
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -82,6 +82,7 @@
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/thr.h>
+#include <sys/timerfd.h>
#include <sys/timex.h>
#include <sys/unistd.h>
#include <sys/ucontext.h>
@@ -3138,6 +3139,60 @@
return (error);
}
+int
+freebsd32_timerfd_gettime(struct thread *td,
+ struct freebsd32_timerfd_gettime_args *uap)
+{
+ struct itimerspec curr_value;
+ struct itimerspec32 curr_value32;
+ int error;
+
+ error = kern_timerfd_gettime(td, uap->fd, &curr_value);
+ if (error == 0) {
+ CP(curr_value, curr_value32, it_value.tv_sec);
+ CP(curr_value, curr_value32, it_value.tv_nsec);
+ CP(curr_value, curr_value32, it_interval.tv_sec);
+ CP(curr_value, curr_value32, it_interval.tv_nsec);
+ error = copyout(&curr_value32, uap->curr_value,
+ sizeof(curr_value32));
+ }
+
+ return (error);
+}
+
+int
+freebsd32_timerfd_settime(struct thread *td,
+ struct freebsd32_timerfd_settime_args *uap)
+{
+ struct itimerspec new_value, old_value;
+ struct itimerspec32 new_value32, old_value32;
+ int error;
+
+ error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
+ if (error != 0)
+ return (error);
+ CP(new_value32, new_value, it_value.tv_sec);
+ CP(new_value32, new_value, it_value.tv_nsec);
+ CP(new_value32, new_value, it_interval.tv_sec);
+ CP(new_value32, new_value, it_interval.tv_nsec);
+ if (uap->old_value == NULL) {
+ error = kern_timerfd_settime(td, uap->fd, uap->flags,
+ &new_value, NULL);
+ } else {
+ error = kern_timerfd_settime(td, uap->fd, uap->flags,
+ &new_value, &old_value);
+ if (error == 0) {
+ CP(old_value, old_value32, it_value.tv_sec);
+ CP(old_value, old_value32, it_value.tv_nsec);
+ CP(old_value, old_value32, it_interval.tv_sec);
+ CP(old_value, old_value32, it_interval.tv_nsec);
+ error = copyout(&old_value32, uap->old_value,
+ sizeof(old_value32));
+ }
+ }
+ return (error);
+}
+
int
freebsd32_clock_getcpuclockid2(struct thread *td,
struct freebsd32_clock_getcpuclockid2_args *uap)
diff --git a/sys/kern/sys_timerfd.c b/sys/kern/sys_timerfd.c
--- a/sys/kern/sys_timerfd.c
+++ b/sys/kern/sys_timerfd.c
@@ -54,11 +54,6 @@
#include <security/audit/audit.h>
-#ifdef COMPAT_FREEBSD32
-#include <compat/freebsd32/freebsd32.h>
-#include <compat/freebsd32/freebsd32_proto.h>
-#endif
-
static MALLOC_DEFINE(M_TIMERFD, "timerfd", "timerfd structures");
static struct sx timerfd_list_lock;
@@ -73,28 +68,36 @@
#define TFD_CANCELED 4 /* Jumped, CANCEL_ON_SET=true. */
#define TFD_JUMPED (TFD_ZREAD | TFD_CANCELED)
+/*
+ * One structure allocated per timerfd descriptor.
+ *
+ * Locking semantics:
+ * (t) locked by tfd_lock mtx
+ * (l) locked by timerfd_list_lock sx
+ * (c) const until freeing
+ */
struct timerfd {
/* User specified. */
- struct itimerspec tfd_time; /* tfd timer */
- clockid_t tfd_clockid; /* timing base */
- int tfd_flags; /* creation flags */
- int tfd_timflags; /* timer flags */
+ struct itimerspec tfd_time; /* (t) tfd timer */
+ clockid_t tfd_clockid; /* (c) timing base */
+ int tfd_flags; /* (c) creation flags */
+ int tfd_timflags; /* (t) timer flags */
/* Used internally. */
- timerfd_t tfd_count; /* expiration count since last read */
- bool tfd_expired; /* true upon initial expiration */
- struct mtx tfd_lock; /* mtx lock */
- struct callout tfd_callout; /* expiration notification */
- struct selinfo tfd_sel; /* I/O alerts */
- struct timespec tfd_boottim; /* cached boottime */
- int tfd_jumped; /* timer jump status */
- LIST_ENTRY(timerfd) entry; /* entry in list */
+ timerfd_t tfd_count; /* (t) expiration count since read */
+ bool tfd_expired; /* (t) true upon initial expiration */
+ struct mtx tfd_lock; /* tfd mtx lock */
+ struct callout tfd_callout; /* (t) expiration notification */
+ struct selinfo tfd_sel; /* (t) I/O alerts */
+ struct timespec tfd_boottim; /* (t) cached boottime */
+ int tfd_jumped; /* (t) timer jump status */
+ LIST_ENTRY(timerfd) entry; /* (l) entry in list */
/* For stat(2). */
- ino_t tfd_ino; /* inode number */
- struct timespec tfd_atim; /* time of last read */
- struct timespec tfd_mtim; /* time of last settime */
- struct timespec tfd_birthtim; /* creation time */
+ ino_t tfd_ino; /* (c) inode number */
+ struct timespec tfd_atim; /* (t) time of last read */
+ struct timespec tfd_mtim; /* (t) time of last settime */
+ struct timespec tfd_birthtim; /* (c) creation time */
};
static void
@@ -109,6 +112,7 @@
timerfd_getboottime(struct timespec *ts)
{
struct timeval tv;
+
getboottime(&tv);
TIMEVAL_TO_TIMESPEC(&tv, ts);
}
@@ -274,6 +278,8 @@
{
struct timerfd *tfd = kn->kn_hook;
+ mtx_assert(&tfd->tfd_lock, MA_OWNED);
+ kn->kn_data = (int64_t)tfd->tfd_count;
return (tfd->tfd_count > 0);
}
@@ -308,13 +314,13 @@
sb->st_uid = fp->f_cred->cr_uid;
sb->st_gid = fp->f_cred->cr_gid;
sb->st_blksize = PAGE_SIZE;
-
mtx_lock(&tfd->tfd_lock);
- sb->st_ino = tfd->tfd_ino;
sb->st_atim = tfd->tfd_atim;
sb->st_mtim = tfd->tfd_mtim;
- sb->st_birthtim = tfd->tfd_birthtim;
mtx_unlock(&tfd->tfd_lock);
+ sb->st_ctim = sb->st_mtim;
+ sb->st_ino = tfd->tfd_ino;
+ sb->st_birthtim = tfd->tfd_birthtim;
return (0);
}
@@ -342,15 +348,12 @@
timerfd_fill_kinfo(struct file *fp, struct kinfo_file *kif,
struct filedesc *fdp)
{
-
struct timerfd *tfd = fp->f_data;
kif->kf_type = KF_TYPE_TIMERFD;
- mtx_lock(&tfd->tfd_lock);
kif->kf_un.kf_timerfd.kf_timerfd_clockid = tfd->tfd_clockid;
kif->kf_un.kf_timerfd.kf_timerfd_flags = tfd->tfd_flags;
kif->kf_un.kf_timerfd.kf_timerfd_addr = (uintptr_t)tfd;
- mtx_unlock(&tfd->tfd_lock);
return (0);
}
@@ -376,6 +379,7 @@
{
struct timespec curr_value;
+ mtx_assert(&tfd->tfd_lock, MA_OWNED);
*old_value = tfd->tfd_time;
if (timespecisset(&tfd->tfd_time.it_value)) {
nanouptime(&curr_value);
@@ -472,11 +476,11 @@
error = fget(td, fd, &cap_write_rights, &fp);
if (error != 0)
return (error);
- tfd = fp->f_data;
- if (tfd == NULL || fp->f_type != DTYPE_TIMERFD) {
+ if (fp->f_type != DTYPE_TIMERFD) {
fdrop(fp, td);
return (EINVAL);
}
+ tfd = fp->f_data;
mtx_lock(&tfd->tfd_lock);
timerfd_curval(tfd, curr_value);
@@ -504,11 +508,11 @@
error = fget(td, fd, &cap_write_rights, &fp);
if (error != 0)
return (error);
- tfd = fp->f_data;
- if (tfd == NULL || fp->f_type != DTYPE_TIMERFD) {
+ if (fp->f_type != DTYPE_TIMERFD) {
fdrop(fp, td);
return (EINVAL);
}
+ tfd = fp->f_data;
mtx_lock(&tfd->tfd_lock);
getnanotime(&tfd->tfd_mtim);
@@ -589,59 +593,3 @@
}
return (error);
}
-
-#ifdef COMPAT_FREEBSD32
-int
-freebsd32_timerfd_gettime(struct thread *td,
- struct freebsd32_timerfd_gettime_args *uap)
-{
- struct itimerspec curr_value;
- struct itimerspec32 curr_value32;
- int error;
-
- error = kern_timerfd_gettime(td, uap->fd, &curr_value);
- if (error == 0) {
- CP(curr_value, curr_value32, it_value.tv_sec);
- CP(curr_value, curr_value32, it_value.tv_nsec);
- CP(curr_value, curr_value32, it_interval.tv_sec);
- CP(curr_value, curr_value32, it_interval.tv_nsec);
- error = copyout(&curr_value32, uap->curr_value,
- sizeof(curr_value32));
- }
-
- return (error);
-}
-
-int
-freebsd32_timerfd_settime(struct thread *td,
- struct freebsd32_timerfd_settime_args *uap)
-{
- struct itimerspec new_value, old_value;
- struct itimerspec32 new_value32, old_value32;
- int error;
-
- error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
- if (error != 0)
- return (error);
- CP(new_value32, new_value, it_value.tv_sec);
- CP(new_value32, new_value, it_value.tv_nsec);
- CP(new_value32, new_value, it_interval.tv_sec);
- CP(new_value32, new_value, it_interval.tv_nsec);
- if (uap->old_value == NULL) {
- error = kern_timerfd_settime(td, uap->fd, uap->flags,
- &new_value, NULL);
- } else {
- error = kern_timerfd_settime(td, uap->fd, uap->flags,
- &new_value, &old_value);
- if (error == 0) {
- CP(old_value, old_value32, it_value.tv_sec);
- CP(old_value, old_value32, it_value.tv_nsec);
- CP(old_value, old_value32, it_interval.tv_sec);
- CP(old_value, old_value32, it_interval.tv_nsec);
- error = copyout(&old_value32, uap->old_value,
- sizeof(old_value32));
- }
- }
- return (error);
-}
-#endif
diff --git a/sys/sys/timerfd.h b/sys/sys/timerfd.h
--- a/sys/sys/timerfd.h
+++ b/sys/sys/timerfd.h
@@ -30,7 +30,6 @@
#include <sys/types.h>
#include <sys/fcntl.h>
-#include <sys/proc.h>
#include <sys/timespec.h>
typedef uint64_t timerfd_t;
@@ -54,6 +53,8 @@
#else /* _KERNEL */
+struct thread;
+
int kern_timerfd_create(struct thread *td, int clockid, int flags);
int kern_timerfd_gettime(struct thread *td, int fd,
struct itimerspec *curr_value);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 2, 1:55 AM (10 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28408984
Default Alt Text
D41600.id126574.diff (8 KB)
Attached To
Mode
D41600: timerfd: Define a locking regime
Attached
Detach File
Event Timeline
Log In to Comment