mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
saner FASYNC handling on file close
As it is, all instances of ->release() for files that have ->fasync() need to remember to evict file from fasync lists; forgetting that creates a hole and we actually have a bunch that *does* forget. So let's keep our lives simple - let __fput() check FASYNC in file->f_flags and call ->fasync() there if it's been set. And lose that crap in ->release() instances - leaving it there is still valid, but we don't have to bother anymore. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
@@ -1995,11 +1995,6 @@ pfm_close(struct inode *inode, struct file *filp)
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
if (filp->f_flags & FASYNC) {
|
||||
DPRINT(("cleaning up async_queue=%p\n", ctx->ctx_async_queue));
|
||||
pfm_do_fasync(-1, filp, ctx, 0);
|
||||
}
|
||||
|
||||
PROTECT_CTX(ctx, flags);
|
||||
|
||||
state = ctx->ctx_state;
|
||||
|
||||
@@ -427,9 +427,6 @@ static int hpet_release(struct inode *inode, struct file *file)
|
||||
if (irq)
|
||||
free_irq(irq, devp);
|
||||
|
||||
if (file->f_flags & FASYNC)
|
||||
hpet_fasync(-1, file, 0);
|
||||
|
||||
file->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,8 +162,6 @@ static int ipmi_release(struct inode *inode, struct file *file)
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
ipmi_fasync (-1, file, 0);
|
||||
|
||||
/* FIXME - free the messages in the list. */
|
||||
kfree(priv);
|
||||
|
||||
|
||||
@@ -870,7 +870,6 @@ static int ipmi_close(struct inode *ino, struct file *filep)
|
||||
clear_bit(0, &ipmi_wdog_open);
|
||||
}
|
||||
|
||||
ipmi_fasync(-1, filep, 0);
|
||||
expect_close = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1139,18 +1139,12 @@ static int random_fasync(int fd, struct file *filp, int on)
|
||||
return fasync_helper(fd, filp, on, &fasync);
|
||||
}
|
||||
|
||||
static int random_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
return fasync_helper(-1, filp, 0, &fasync);
|
||||
}
|
||||
|
||||
const struct file_operations random_fops = {
|
||||
.read = random_read,
|
||||
.write = random_write,
|
||||
.poll = random_poll,
|
||||
.unlocked_ioctl = random_ioctl,
|
||||
.fasync = random_fasync,
|
||||
.release = random_release,
|
||||
};
|
||||
|
||||
const struct file_operations urandom_fops = {
|
||||
@@ -1158,7 +1152,6 @@ const struct file_operations urandom_fops = {
|
||||
.write = random_write,
|
||||
.unlocked_ioctl = random_ioctl,
|
||||
.fasync = random_fasync,
|
||||
.release = random_release,
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
|
||||
@@ -788,8 +788,6 @@ static int rtc_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
|
||||
if (file->f_flags & FASYNC)
|
||||
rtc_fasync(-1, file, 0);
|
||||
no_irq:
|
||||
#endif
|
||||
|
||||
|
||||
@@ -898,7 +898,6 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on)
|
||||
|
||||
static int sonypi_misc_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
sonypi_misc_fasync(-1, file, 0);
|
||||
mutex_lock(&sonypi_device.lock);
|
||||
sonypi_device.open_count--;
|
||||
mutex_unlock(&sonypi_device.lock);
|
||||
|
||||
@@ -406,8 +406,6 @@ int drm_release(struct inode *inode, struct file *filp)
|
||||
if (dev->driver->driver_features & DRIVER_GEM)
|
||||
drm_gem_release(dev, file_priv);
|
||||
|
||||
drm_fasync(-1, filp, 0);
|
||||
|
||||
mutex_lock(&dev->ctxlist_mutex);
|
||||
if (!list_empty(&dev->ctxlist)) {
|
||||
struct drm_ctx_list *pos, *n;
|
||||
|
||||
@@ -242,8 +242,6 @@ static int hiddev_release(struct inode * inode, struct file * file)
|
||||
struct hiddev_list *list = file->private_data;
|
||||
unsigned long flags;
|
||||
|
||||
hiddev_fasync(-1, file, 0);
|
||||
|
||||
spin_lock_irqsave(&list->hiddev->list_lock, flags);
|
||||
list_del(&list->node);
|
||||
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
|
||||
|
||||
@@ -1828,9 +1828,6 @@ static int dv1394_release(struct inode *inode, struct file *file)
|
||||
/* OK to free the DMA buffer, no more mappings can exist */
|
||||
do_dv1394_shutdown(video, 1);
|
||||
|
||||
/* clean up async I/O users */
|
||||
dv1394_fasync(-1, file, 0);
|
||||
|
||||
/* give someone else a turn */
|
||||
clear_bit(0, &video->open);
|
||||
|
||||
|
||||
@@ -358,8 +358,6 @@ static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
|
||||
}
|
||||
spin_unlock_irq(&file->lock);
|
||||
|
||||
ib_uverbs_event_fasync(-1, filp, 0);
|
||||
|
||||
if (file->is_async) {
|
||||
ib_unregister_event_handler(&file->uverbs_file->event_handler);
|
||||
kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
|
||||
|
||||
@@ -235,7 +235,6 @@ static int evdev_release(struct inode *inode, struct file *file)
|
||||
evdev_ungrab(evdev, client);
|
||||
mutex_unlock(&evdev->mutex);
|
||||
|
||||
evdev_fasync(-1, file, 0);
|
||||
evdev_detach_client(evdev, client);
|
||||
kfree(client);
|
||||
|
||||
|
||||
@@ -244,7 +244,6 @@ static int joydev_release(struct inode *inode, struct file *file)
|
||||
struct joydev_client *client = file->private_data;
|
||||
struct joydev *joydev = client->joydev;
|
||||
|
||||
joydev_fasync(-1, file, 0);
|
||||
joydev_detach_client(joydev, client);
|
||||
kfree(client);
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
|
||||
static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait);
|
||||
|
||||
static int hp_sdc_rtc_open(struct inode *inode, struct file *file);
|
||||
static int hp_sdc_rtc_release(struct inode *inode, struct file *file);
|
||||
static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on);
|
||||
|
||||
static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
|
||||
@@ -414,17 +413,6 @@ static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hp_sdc_rtc_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
/* Turn off interrupts? */
|
||||
|
||||
if (file->f_flags & FASYNC) {
|
||||
hp_sdc_rtc_fasync (-1, file, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on)
|
||||
{
|
||||
return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue);
|
||||
@@ -680,7 +668,6 @@ static const struct file_operations hp_sdc_rtc_fops = {
|
||||
.poll = hp_sdc_rtc_poll,
|
||||
.ioctl = hp_sdc_rtc_ioctl,
|
||||
.open = hp_sdc_rtc_open,
|
||||
.release = hp_sdc_rtc_release,
|
||||
.fasync = hp_sdc_rtc_fasync,
|
||||
};
|
||||
|
||||
|
||||
@@ -519,7 +519,6 @@ static int mousedev_release(struct inode *inode, struct file *file)
|
||||
struct mousedev_client *client = file->private_data;
|
||||
struct mousedev *mousedev = client->mousedev;
|
||||
|
||||
mousedev_fasync(-1, file, 0);
|
||||
mousedev_detach_client(mousedev, client);
|
||||
kfree(client);
|
||||
|
||||
|
||||
@@ -135,7 +135,6 @@ static int serio_raw_release(struct inode *inode, struct file *file)
|
||||
|
||||
mutex_lock(&serio_raw_mutex);
|
||||
|
||||
serio_raw_fasync(-1, file, 0);
|
||||
serio_raw_cleanup(serio_raw);
|
||||
|
||||
mutex_unlock(&serio_raw_mutex);
|
||||
|
||||
@@ -559,12 +559,6 @@ mptctl_fasync(int fd, struct file *filep, int mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mptctl_release(struct inode *inode, struct file *filep)
|
||||
{
|
||||
return fasync_helper(-1, filep, 0, &async_queue);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* MPT ioctl handler
|
||||
@@ -2706,7 +2700,6 @@ mptctl_hp_targetinfo(unsigned long arg)
|
||||
static const struct file_operations mptctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.release = mptctl_release,
|
||||
.fasync = mptctl_fasync,
|
||||
.unlocked_ioctl = mptctl_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
@@ -1097,28 +1097,17 @@ static int cfg_fasync(int fd, struct file *fp, int on)
|
||||
static int cfg_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
ulong id = (ulong) file->private_data;
|
||||
struct i2o_cfg_info *p1, *p2;
|
||||
struct i2o_cfg_info *p, **q;
|
||||
unsigned long flags;
|
||||
|
||||
lock_kernel();
|
||||
p1 = p2 = NULL;
|
||||
|
||||
spin_lock_irqsave(&i2o_config_lock, flags);
|
||||
for (p1 = open_files; p1;) {
|
||||
if (p1->q_id == id) {
|
||||
|
||||
if (p1->fasync)
|
||||
cfg_fasync(-1, file, 0);
|
||||
if (p2)
|
||||
p2->next = p1->next;
|
||||
else
|
||||
open_files = p1->next;
|
||||
|
||||
kfree(p1);
|
||||
for (q = &open_files; (p = *q) != NULL; q = &p->next) {
|
||||
if (p->q_id == id) {
|
||||
*q = p->next;
|
||||
kfree(p);
|
||||
break;
|
||||
}
|
||||
p2 = p1;
|
||||
p1 = p1->next;
|
||||
}
|
||||
spin_unlock_irqrestore(&i2o_config_lock, flags);
|
||||
unlock_kernel();
|
||||
|
||||
@@ -1920,7 +1920,6 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on)
|
||||
|
||||
static int sonypi_misc_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
sonypi_misc_fasync(-1, file, 0);
|
||||
atomic_dec(&sonypi_compat.open_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1070,8 +1070,6 @@ static int tun_chr_close(struct inode *inode, struct file *file)
|
||||
|
||||
DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
|
||||
|
||||
tun_chr_fasync(-1, file, 0);
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
/* Detach from net device */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user