mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
562787a5c3
Split the anonfd interface into a bare file pointer creation one, and a file pointer creation plus install one. There are cases, like the usage of eventfds inside other kernel interfaces, where the file pointer created by anonfd needs to be used inside the initialization of other structures. As it is right now, as soon as anon_inode_getfd() returns, the kenrle can race with userspace closing the newly installed file descriptor. This patch, while keeping the old anon_inode_getfd(), introduces a new anon_inode_getfile() (whose services are reused in anon_inode_getfd()) that allows to split the file creation phase and the fd install one. Once all the kernel structures are initialized, the code can call the proper fd_install(). Gregory manifested the need for something like this inside KVM. Signed-off-by: Davide Libenzi <davidel@xmailserver.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: James Morris <jmorris@namei.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Gregory Haskins <ghaskins@novell.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Acked-by: Roland Dreier <rolandd@cisco.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
67 lines
1.6 KiB
C
67 lines
1.6 KiB
C
/*
|
|
* include/linux/eventfd.h
|
|
*
|
|
* Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
|
|
*
|
|
*/
|
|
|
|
#ifndef _LINUX_EVENTFD_H
|
|
#define _LINUX_EVENTFD_H
|
|
|
|
#include <linux/fcntl.h>
|
|
#include <linux/file.h>
|
|
|
|
/*
|
|
* CAREFUL: Check include/asm-generic/fcntl.h when defining
|
|
* new flags, since they might collide with O_* ones. We want
|
|
* to re-use O_* flags that couldn't possibly have a meaning
|
|
* from eventfd, in order to leave a free define-space for
|
|
* shared O_* flags.
|
|
*/
|
|
#define EFD_SEMAPHORE (1 << 0)
|
|
#define EFD_CLOEXEC O_CLOEXEC
|
|
#define EFD_NONBLOCK O_NONBLOCK
|
|
|
|
#define EFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
|
|
#define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE)
|
|
|
|
#ifdef CONFIG_EVENTFD
|
|
|
|
struct file *eventfd_file_create(unsigned int count, int flags);
|
|
struct eventfd_ctx *eventfd_ctx_get(struct eventfd_ctx *ctx);
|
|
void eventfd_ctx_put(struct eventfd_ctx *ctx);
|
|
struct file *eventfd_fget(int fd);
|
|
struct eventfd_ctx *eventfd_ctx_fdget(int fd);
|
|
struct eventfd_ctx *eventfd_ctx_fileget(struct file *file);
|
|
int eventfd_signal(struct eventfd_ctx *ctx, int n);
|
|
|
|
#else /* CONFIG_EVENTFD */
|
|
|
|
/*
|
|
* Ugly ugly ugly error layer to support modules that uses eventfd but
|
|
* pretend to work in !CONFIG_EVENTFD configurations. Namely, AIO.
|
|
*/
|
|
static inline struct file *eventfd_file_create(unsigned int count, int flags)
|
|
{
|
|
return ERR_PTR(-ENOSYS);
|
|
}
|
|
|
|
static inline struct eventfd_ctx *eventfd_ctx_fdget(int fd)
|
|
{
|
|
return ERR_PTR(-ENOSYS);
|
|
}
|
|
|
|
static inline int eventfd_signal(struct eventfd_ctx *ctx, int n)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
|
|
static inline void eventfd_ctx_put(struct eventfd_ctx *ctx)
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* _LINUX_EVENTFD_H */
|
|
|