Commit 7c6c4ed8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull vfs fixes from Christian Brauner:
 "The kernfs rbtree is keyed by (hash, ns, name) where the hash
  is seeded with the raw namespace pointer via init_name_hash(ns).

  The resulting hash values are exposed to userspace through
  readdir seek positions, and the pointer-based ordering in
  kernfs_name_compare() is observable through entry order.

  Switch from raw pointers to ns_common::ns_id for both hashing
  and comparison.

  A preparatory commit first replaces all const void * namespace
  parameters with const struct ns_common * throughout kernfs, sysfs,
  and kobject so the code can access ns->ns_id. Also compare the
  ns_id when hashes match in the rbtree to handle crafted collisions.

  Also fix eventpoll RCU grace period issue and a cachefiles refcount
  problem"

* tag 'vfs-7.0-rc8.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  kernfs: make directory seek namespace-aware
  kernfs: use namespace id instead of pointer for hashing and comparison
  kernfs: pass struct ns_common instead of const void * for namespace tags
  eventpoll: defer struct eventpoll free to RCU grace period
  cachefiles: fix incorrect dentry refcount in cachefiles_cull()
parents 96463e4e cb76a81c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ static const struct kobj_type class_ktype = {
};

int class_create_file_ns(const struct class *cls, const struct class_attribute *attr,
			 const void *ns)
			 const struct ns_common *ns)
{
	struct subsys_private *sp = class_to_subsys(cls);
	int error;
@@ -143,7 +143,7 @@ int class_create_file_ns(const struct class *cls, const struct class_attribute *
EXPORT_SYMBOL_GPL(class_create_file_ns);

void class_remove_file_ns(const struct class *cls, const struct class_attribute *attr,
			  const void *ns)
			  const struct ns_common *ns)
{
	struct subsys_private *sp = class_to_subsys(cls);

+3 −4
Original line number Diff line number Diff line
@@ -2570,15 +2570,14 @@ static void device_release(struct kobject *kobj)
	kfree(p);
}

static const void *device_namespace(const struct kobject *kobj)
static const struct ns_common *device_namespace(const struct kobject *kobj)
{
	const struct device *dev = kobj_to_dev(kobj);
	const void *ns = NULL;

	if (dev->class && dev->class->namespace)
		ns = dev->class->namespace(dev);
		return dev->class->namespace(dev);

	return ns;
	return NULL;
}

static void device_get_ownership(const struct kobject *kobj, kuid_t *uid, kgid_t *gid)
+3 −2
Original line number Diff line number Diff line
@@ -509,12 +509,13 @@ static int ib_device_uevent(const struct device *device,
	return 0;
}

static const void *net_namespace(const struct device *d)
static const struct ns_common *net_namespace(const struct device *d)
{
	const struct ib_core_device *coredev =
			container_of(d, struct ib_core_device, dev);
	struct net *net = read_pnet(&coredev->rdma_net);

	return read_pnet(&coredev->rdma_net);
	return net ? to_ns_common(net) : NULL;
}

static struct class ib_class = {
+4 −3
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <linux/jiffies.h>
#include <linux/lockdep.h>
#include <linux/inet.h>
#include <net/net_namespace.h>
#include <rdma/ib_cache.h>

#include <linux/atomic.h>
@@ -1048,7 +1049,7 @@ static void srp_remove_target(struct srp_target_port *target)
	scsi_remove_host(target->scsi_host);
	srp_stop_rport_timers(target->rport);
	srp_disconnect_target(target);
	kobj_ns_drop(KOBJ_NS_TYPE_NET, target->net);
	kobj_ns_drop(KOBJ_NS_TYPE_NET, to_ns_common(target->net));
	for (i = 0; i < target->ch_count; i++) {
		ch = &target->ch[i];
		srp_free_ch_ib(target, ch);
@@ -3713,7 +3714,7 @@ static ssize_t add_target_store(struct device *dev,

	target = host_to_target(target_host);

	target->net		= kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
	target->net		= to_net_ns(kobj_ns_grab_current(KOBJ_NS_TYPE_NET));
	target->io_class	= SRP_REV16A_IB_IO_CLASS;
	target->scsi_host	= target_host;
	target->srp_host	= host;
@@ -3905,7 +3906,7 @@ static ssize_t add_target_store(struct device *dev,
		 * earlier in this function.
		 */
		if (target->state != SRP_TARGET_REMOVED)
			kobj_ns_drop(KOBJ_NS_TYPE_NET, target->net);
			kobj_ns_drop(KOBJ_NS_TYPE_NET, to_ns_common(target->net));
		scsi_host_put(target->scsi_host);
	}

+2 −2
Original line number Diff line number Diff line
@@ -808,7 +808,7 @@ int __net_init bond_create_sysfs(struct bond_net *bn)
	sysfs_attr_init(&bn->class_attr_bonding_masters.attr);

	ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
					  bn->net);
					  to_ns_common(bn->net));
	/* Permit multiple loads of the module by ignoring failures to
	 * create the bonding_masters sysfs file.  Bonding devices
	 * created by second or subsequent loads of the module will
@@ -835,7 +835,7 @@ int __net_init bond_create_sysfs(struct bond_net *bn)
/* Remove /sys/class/net/bonding_masters. */
void __net_exit bond_destroy_sysfs(struct bond_net *bn)
{
	netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
	netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, to_ns_common(bn->net));
}

/* Initialize sysfs for each bond.  This sets up and registers
Loading