示例#1
0
int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
		     union ib_gid *gid, struct ib_gid_attr *attr)
{
	struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
	struct ib_gid_table *table;
	int ix;
	int ret = 0;
	struct net_device *idev;

	table = ports_table[port - rdma_start_port(ib_dev)];

	if (!memcmp(gid, &zgid, sizeof(*gid)))
		return -EINVAL;

	if (ib_dev->get_netdev) {
		idev = ib_dev->get_netdev(ib_dev, port);
		if (idev && attr->ndev != idev) {
			union ib_gid default_gid;

			/* Adding default GIDs in not permitted */
			make_default_gid(idev, &default_gid);
			if (!memcmp(gid, &default_gid, sizeof(*gid))) {
				dev_put(idev);
				return -EPERM;
			}
		}
		if (idev)
			dev_put(idev);
	}

	mutex_lock(&table->lock);

	ix = find_gid(table, gid, attr, false, GID_ATTR_FIND_MASK_GID |
		      GID_ATTR_FIND_MASK_NETDEV);
	if (ix >= 0)
		goto out_unlock;

	ix = find_gid(table, &zgid, NULL, false, GID_ATTR_FIND_MASK_GID |
		      GID_ATTR_FIND_MASK_DEFAULT);
	if (ix < 0) {
		ret = -ENOSPC;
		goto out_unlock;
	}

	add_gid(ib_dev, port, table, ix, gid, attr, false);

out_unlock:
	mutex_unlock(&table->lock);
	return ret;
}
示例#2
0
void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
				  struct net_device *ndev,
				  enum ib_cache_gid_default_mode mode)
{
	struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
	union ib_gid gid;
	struct ib_gid_attr gid_attr;
	struct ib_gid_table *table;
	int ix;
	union ib_gid current_gid;
	struct ib_gid_attr current_gid_attr = {};

	table  = ports_table[port - rdma_start_port(ib_dev)];

	make_default_gid(ndev, &gid);
	memset(&gid_attr, 0, sizeof(gid_attr));
	gid_attr.ndev = ndev;

	mutex_lock(&table->lock);
	ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT);

	/* Coudn't find default GID location */
	WARN_ON(ix < 0);

	if (!__ib_cache_gid_get(ib_dev, port, ix,
				&current_gid, &current_gid_attr) &&
	    mode == IB_CACHE_GID_DEFAULT_MODE_SET &&
	    !memcmp(&gid, &current_gid, sizeof(gid)) &&
	    !memcmp(&gid_attr, &current_gid_attr, sizeof(gid_attr)))
		goto unlock;

	if ((memcmp(&current_gid, &zgid, sizeof(current_gid)) ||
	     memcmp(&current_gid_attr, &zattr,
		    sizeof(current_gid_attr))) &&
	    del_gid(ib_dev, port, table, ix, true)) {
		pr_warn("ib_cache_gid: can't delete index %d for default gid %pI6\n",
			ix, gid.raw);
		goto unlock;
	}

	if (mode == IB_CACHE_GID_DEFAULT_MODE_SET)
		if (add_gid(ib_dev, port, table, ix, &gid, &gid_attr, true))
			pr_warn("ib_cache_gid: unable to add default gid %pI6\n",
				gid.raw);

unlock:
	if (current_gid_attr.ndev)
		dev_put(current_gid_attr.ndev);
	mutex_unlock(&table->lock);
}
示例#3
0
static struct namei *
new_namei(struct namei *parent, const char *path, const char *fname, int lev)
{
	struct namei *nm;

	if (!fname)
		return NULL;
	nm = calloc(1, sizeof(*nm));
	if (!nm)
		err(EXIT_FAILURE, _("out of memory?"));
	if (parent)
		parent->next = nm;

	nm->level = lev;
	nm->name = strdup(fname);
	if (!nm->name)
		err(EXIT_FAILURE, _("out of memory?"));
	if (lstat(path, &nm->st) == -1)
		err(EXIT_FAILURE, _("could not stat '%s'"), path);

	if (S_ISLNK(nm->st.st_mode))
		readlink_to_namei(nm, path);
	if (flags & NAMEI_OWNERS) {
		add_uid(nm->st.st_uid);
		add_gid(nm->st.st_gid);
	}

	if ((flags & NAMEI_MNTS) && S_ISDIR(nm->st.st_mode)) {
		struct stat stbuf, *sb = NULL;

		if (parent && S_ISDIR(parent->st.st_mode))
			sb = &parent->st;
		else if (!parent || S_ISLNK(parent->st.st_mode))
			sb = dotdot_stat(path, &stbuf);

		if (sb && (sb->st_dev != nm->st.st_dev ||   /* different device */
		           sb->st_ino == nm->st.st_ino))    /* root directory */
			nm->mountpoint = 1;
	}

	return nm;
}