Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 189528
b: refs/heads/master
c: b914f3a
h: refs/heads/master
v: v3
  • Loading branch information
Paul Moore authored and David S. Miller committed Apr 2, 2010
1 parent aec1aaf commit 881cc9a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e2e61fbf8ad016d24e4af0afff13505f3dd2a2a
refs/heads/master: b914f3a2a35812545f773645f340d7c075e5b64d
28 changes: 18 additions & 10 deletions trunk/net/netlabel/netlabel_domainhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ struct netlbl_domhsh_tbl {
};

/* Domain hash table */
/* XXX - updates should be so rare that having one spinlock for the entire
* hash table should be okay */
/* updates should be so rare that having one spinlock for the entire hash table
* should be okay */
static DEFINE_SPINLOCK(netlbl_domhsh_lock);
#define netlbl_domhsh_rcu_deref(p) \
rcu_dereference_check(p, rcu_read_lock_held() || \
lockdep_is_held(&netlbl_domhsh_lock))
static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
static struct netlbl_dom_map *netlbl_domhsh_def = NULL;

Expand Down Expand Up @@ -106,7 +109,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
* Description:
* This is the hashing function for the domain hash table, it returns the
* correct bucket number for the domain. The caller is responsibile for
* calling the rcu_read_[un]lock() functions.
* ensuring that the hash table is protected with either a RCU read lock or the
* hash table lock.
*
*/
static u32 netlbl_domhsh_hash(const char *key)
Expand All @@ -120,7 +124,7 @@ static u32 netlbl_domhsh_hash(const char *key)

for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
return val & (rcu_dereference(netlbl_domhsh)->size - 1);
return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
}

/**
Expand All @@ -130,7 +134,8 @@ static u32 netlbl_domhsh_hash(const char *key)
* Description:
* Searches the domain hash table and returns a pointer to the hash table
* entry if found, otherwise NULL is returned. The caller is responsibile for
* the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
* ensuring that the hash table is protected with either a RCU read lock or the
* hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
Expand All @@ -141,7 +146,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)

if (domain != NULL) {
bkt = netlbl_domhsh_hash(domain);
bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && strcmp(iter->domain, domain) == 0)
return iter;
Expand All @@ -159,8 +164,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
* Searches the domain hash table and returns a pointer to the hash table
* entry if an exact match is found, if an exact match is not present in the
* hash table then the default entry is returned if valid otherwise NULL is
* returned. The caller is responsibile for the rcu hash table locks
* (i.e. the caller much call rcu_read_[un]lock()).
* returned. The caller is responsibile ensuring that the hash table is
* protected with either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
Expand All @@ -169,7 +174,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)

entry = netlbl_domhsh_search(domain);
if (entry == NULL) {
entry = rcu_dereference(netlbl_domhsh_def);
entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def);
if (entry != NULL && !entry->valid)
entry = NULL;
}
Expand Down Expand Up @@ -306,8 +311,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
struct netlbl_af6list *tmp6;
#endif /* IPv6 */

/* XXX - we can remove this RCU read lock as the spinlock protects the
* entire function, but before we do we need to fixup the
* netlbl_af[4,6]list RCU functions to do "the right thing" with
* respect to rcu_dereference() when only a spinlock is held. */
rcu_read_lock();

spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL)
entry_old = netlbl_domhsh_search(entry->domain);
Expand Down
66 changes: 19 additions & 47 deletions trunk/net/netlabel/netlabel_unlabeled.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ struct netlbl_unlhsh_walk_arg {
/* updates should be so rare that having one spinlock for the entire
* hash table should be okay */
static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
#define netlbl_unlhsh_rcu_deref(p) \
rcu_dereference_check(p, rcu_read_lock_held() || \
lockdep_is_held(&netlbl_unlhsh_lock))
static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL;
static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL;

Expand Down Expand Up @@ -235,15 +238,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
* Description:
* This is the hashing function for the unlabeled hash table, it returns the
* bucket number for the given device/interface. The caller is responsible for
* calling the rcu_read_[un]lock() functions.
* ensuring that the hash table is protected with either a RCU read lock or
* the hash table lock.
*
*/
static u32 netlbl_unlhsh_hash(int ifindex)
{
/* this is taken _almost_ directly from
* security/selinux/netif.c:sel_netif_hasfn() as they do pretty much
* the same thing */
return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1);
return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
}

/**
Expand All @@ -253,7 +254,8 @@ static u32 netlbl_unlhsh_hash(int ifindex)
* Description:
* Searches the unlabeled connection hash table and returns a pointer to the
* interface entry which matches @ifindex, otherwise NULL is returned. The
* caller is responsible for calling the rcu_read_[un]lock() functions.
* caller is responsible for ensuring that the hash table is protected with
* either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
Expand All @@ -263,41 +265,14 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
struct netlbl_unlhsh_iface *iter;

bkt = netlbl_unlhsh_hash(ifindex);
bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && iter->ifindex == ifindex)
return iter;

return NULL;
}

/**
* netlbl_unlhsh_search_iface_def - Search for a matching interface entry
* @ifindex: the network interface
*
* Description:
* Searches the unlabeled connection hash table and returns a pointer to the
* interface entry which matches @ifindex. If an exact match can not be found
* and there is a valid default entry, the default entry is returned, otherwise
* NULL is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
{
struct netlbl_unlhsh_iface *entry;

entry = netlbl_unlhsh_search_iface(ifindex);
if (entry != NULL)
return entry;

entry = rcu_dereference(netlbl_unlhsh_def);
if (entry != NULL && entry->valid)
return entry;

return NULL;
}

/**
* netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
* @iface: the associated interface entry
Expand All @@ -308,8 +283,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
* a negative value is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
* a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
Expand Down Expand Up @@ -349,8 +323,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
* a negative value is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
* a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
Expand Down Expand Up @@ -391,8 +364,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new, empty, interface entry into the unlabeled connection hash table.
* On success a pointer to the new interface entry is returned, on failure NULL
* is returned. The caller is responsible for calling the rcu_read_[un]lock()
* functions.
* is returned.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
Expand All @@ -415,10 +387,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
if (netlbl_unlhsh_search_iface(ifindex) != NULL)
goto add_iface_failure;
list_add_tail_rcu(&iface->list,
&rcu_dereference(netlbl_unlhsh)->tbl[bkt]);
&netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
} else {
INIT_LIST_HEAD(&iface->list);
if (rcu_dereference(netlbl_unlhsh_def) != NULL)
if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
goto add_iface_failure;
rcu_assign_pointer(netlbl_unlhsh_def, iface);
}
Expand Down Expand Up @@ -548,8 +520,7 @@ int netlbl_unlhsh_add(struct net *net,
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
* Returns zero on success, negative values on failure. The caller is
* responsible for calling the rcu_read_[un]lock() functions.
* Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr4(struct net *net,
Expand Down Expand Up @@ -611,8 +582,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
* Returns zero on success, negative values on failure. The caller is
* responsible for calling the rcu_read_[un]lock() functions.
* Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr6(struct net *net,
Expand Down Expand Up @@ -1547,8 +1517,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
struct netlbl_unlhsh_iface *iface;

rcu_read_lock();
iface = netlbl_unlhsh_search_iface_def(skb->skb_iif);
iface = netlbl_unlhsh_search_iface(skb->skb_iif);
if (iface == NULL)
iface = rcu_dereference(netlbl_unlhsh_def);
if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel;
switch (family) {
case PF_INET: {
Expand Down

0 comments on commit 881cc9a

Please sign in to comment.