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; }
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, ¤t_gid, ¤t_gid_attr) && mode == IB_CACHE_GID_DEFAULT_MODE_SET && !memcmp(&gid, ¤t_gid, sizeof(gid)) && !memcmp(&gid_attr, ¤t_gid_attr, sizeof(gid_attr))) goto unlock; if ((memcmp(¤t_gid, &zgid, sizeof(current_gid)) || memcmp(¤t_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); }
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; }