Revision d8a332730e757129e70675679f2b2a03f1ecf65e authored by Linus Torvalds on 27 April 2018, 17:39:38 UTC, committed by Linus Torvalds on 27 April 2018, 17:39:38 UTC
Pull char/misc driver fixes from Greg KH: "Here are some small char and misc driver fixes for 4.17-rc3 A variety of small things that have fallen out after 4.17-rc1 was out. Some vboxguest fixes for systems with lots of memory, amba bus fixes, some MAINTAINERS updates, uio_hv_generic driver fixes, and a few other minor things that resolve problems that people reported. The amba bus fixes took twice to get right, the first time I messed up applying the patches in the wrong order, hence the revert and later addition again with the correct fix, sorry about that. All of these have been in linux-next with no reported issues" * tag 'char-misc-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: ARM: amba: Fix race condition with driver_override ARM: amba: Make driver_override output consistent with other buses Revert "ARM: amba: Fix race condition with driver_override" ARM: amba: Don't read past the end of sysfs "driver_override" buffer ARM: amba: Fix race condition with driver_override virt: vbox: Log an error when we fail to get the host version virt: vbox: Use __get_free_pages instead of kmalloc for DMA32 memory virt: vbox: Add vbg_req_free() helper function virt: vbox: Move declarations of vboxguest private functions to private header slimbus: Fix out-of-bounds access in slim_slicesize() MAINTAINERS: add dri-devel&linaro-mm for Android ION fpga-manager: altera-ps-spi: preserve nCONFIG state MAINTAINERS: update my email address uio_hv_generic: fix subchannel ring mmap uio_hv_generic: use correct channel in isr uio_hv_generic: make ring buffer attribute for primary channel uio_hv_generic: set size of ring buffer attribute ANDROID: binder: prevent transactions into own process.
fs_pin.c
// SPDX-License-Identifier: GPL-2.0
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "internal.h"
#include "mount.h"
static DEFINE_SPINLOCK(pin_lock);
void pin_remove(struct fs_pin *pin)
{
spin_lock(&pin_lock);
hlist_del_init(&pin->m_list);
hlist_del_init(&pin->s_list);
spin_unlock(&pin_lock);
spin_lock_irq(&pin->wait.lock);
pin->done = 1;
wake_up_locked(&pin->wait);
spin_unlock_irq(&pin->wait.lock);
}
void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p)
{
spin_lock(&pin_lock);
if (p)
hlist_add_head(&pin->s_list, p);
hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins);
spin_unlock(&pin_lock);
}
void pin_insert(struct fs_pin *pin, struct vfsmount *m)
{
pin_insert_group(pin, m, &m->mnt_sb->s_pins);
}
void pin_kill(struct fs_pin *p)
{
wait_queue_entry_t wait;
if (!p) {
rcu_read_unlock();
return;
}
init_wait(&wait);
spin_lock_irq(&p->wait.lock);
if (likely(!p->done)) {
p->done = -1;
spin_unlock_irq(&p->wait.lock);
rcu_read_unlock();
p->kill(p);
return;
}
if (p->done > 0) {
spin_unlock_irq(&p->wait.lock);
rcu_read_unlock();
return;
}
__add_wait_queue(&p->wait, &wait);
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&p->wait.lock);
rcu_read_unlock();
schedule();
rcu_read_lock();
if (likely(list_empty(&wait.entry)))
break;
/* OK, we know p couldn't have been freed yet */
spin_lock_irq(&p->wait.lock);
if (p->done > 0) {
spin_unlock_irq(&p->wait.lock);
break;
}
}
rcu_read_unlock();
}
void mnt_pin_kill(struct mount *m)
{
while (1) {
struct hlist_node *p;
rcu_read_lock();
p = READ_ONCE(m->mnt_pins.first);
if (!p) {
rcu_read_unlock();
break;
}
pin_kill(hlist_entry(p, struct fs_pin, m_list));
}
}
void group_pin_kill(struct hlist_head *p)
{
while (1) {
struct hlist_node *q;
rcu_read_lock();
q = READ_ONCE(p->first);
if (!q) {
rcu_read_unlock();
break;
}
pin_kill(hlist_entry(q, struct fs_pin, s_list));
}
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...