diff options
Diffstat (limited to 'fs/eventfd.c')
| -rw-r--r-- | fs/eventfd.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/fs/eventfd.c b/fs/eventfd.c index e0194b3e14d..d6a88e7812f 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -16,9 +16,11 @@ #include <linux/spinlock.h> #include <linux/anon_inodes.h> #include <linux/syscalls.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/kref.h> #include <linux/eventfd.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> struct eventfd_ctx { struct kref kref; @@ -46,20 +48,16 @@ struct eventfd_ctx { * value, and we signal this as overflow condition by returining a POLLERR * to poll(2). * - * Returns @n in case of success, a non-negative number lower than @n in case - * of overflow, or the following error codes: - * - * -EINVAL : The value of @n is negative. + * Returns the amount by which the counter was incrememnted. This will be less + * than @n if the counter has overflowed. */ -int eventfd_signal(struct eventfd_ctx *ctx, int n) +__u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n) { unsigned long flags; - if (n < 0) - return -EINVAL; spin_lock_irqsave(&ctx->wqh.lock, flags); if (ULLONG_MAX - ctx->count < n) - n = (int) (ULLONG_MAX - ctx->count); + n = ULLONG_MAX - ctx->count; ctx->count += n; if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, POLLIN); @@ -99,7 +97,7 @@ EXPORT_SYMBOL_GPL(eventfd_ctx_get); * @ctx: [in] Pointer to eventfd context. * * The eventfd context reference must have been previously acquired either - * with eventfd_ctx_get() or eventfd_ctx_fdget()). + * with eventfd_ctx_get() or eventfd_ctx_fdget(). */ void eventfd_ctx_put(struct eventfd_ctx *ctx) { @@ -146,9 +144,9 @@ static void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt) * eventfd_ctx_remove_wait_queue - Read the current counter and removes wait queue. * @ctx: [in] Pointer to eventfd context. * @wait: [in] Wait queue to be removed. - * @cnt: [out] Pointer to the 64bit conter value. + * @cnt: [out] Pointer to the 64-bit counter value. * - * Returns zero if successful, or the following error codes: + * Returns %0 if successful, or the following error codes: * * -EAGAIN : The operation would have blocked. * @@ -175,11 +173,11 @@ EXPORT_SYMBOL_GPL(eventfd_ctx_remove_wait_queue); * eventfd_ctx_read - Reads the eventfd counter or wait if it is zero. * @ctx: [in] Pointer to eventfd context. * @no_wait: [in] Different from zero if the operation should not block. - * @cnt: [out] Pointer to the 64bit conter value. + * @cnt: [out] Pointer to the 64-bit counter value. * - * Returns zero if successful, or the following error codes: + * Returns %0 if successful, or the following error codes: * - * -EAGAIN : The operation would have blocked but @no_wait was nonzero. + * -EAGAIN : The operation would have blocked but @no_wait was non-zero. * -ERESTARTSYS : A signal interrupted the wait operation. * * If @no_wait is zero, the function might sleep until the eventfd internal @@ -288,7 +286,25 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c return res; } +#ifdef CONFIG_PROC_FS +static int eventfd_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct eventfd_ctx *ctx = f->private_data; + int ret; + + spin_lock_irq(&ctx->wqh.lock); + ret = seq_printf(m, "eventfd-count: %16llx\n", + (unsigned long long)ctx->count); + spin_unlock_irq(&ctx->wqh.lock); + + return ret; +} +#endif + static const struct file_operations eventfd_fops = { +#ifdef CONFIG_PROC_FS + .show_fdinfo = eventfd_show_fdinfo, +#endif .release = eventfd_release, .poll = eventfd_poll, .read = eventfd_read, @@ -333,15 +349,12 @@ EXPORT_SYMBOL_GPL(eventfd_fget); */ struct eventfd_ctx *eventfd_ctx_fdget(int fd) { - struct file *file; struct eventfd_ctx *ctx; - - file = eventfd_fget(fd); - if (IS_ERR(file)) - return (struct eventfd_ctx *) file; - ctx = eventfd_ctx_get(file->private_data); - fput(file); - + struct fd f = fdget(fd); + if (!f.file) + return ERR_PTR(-EBADF); + ctx = eventfd_ctx_fileget(f.file); + fdput(f); return ctx; } EXPORT_SYMBOL_GPL(eventfd_ctx_fdget); |
