mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 08:08:54 +00:00
NFSv4.1/pNFS: Fix borken function _same_data_server_addrs_locked()
- Switch back to using list_for_each_entry(). Fixes an incorrect test for list NULL termination. - Do not assume that lists are sorted. - Finally, consider an existing entry to match if it consists of a subset of the addresses in the new entry. Cc: stable@vger.kernel.org # 4.0+ Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
e9ae58aeee
commit
6f536936b7
1 changed files with 18 additions and 13 deletions
|
@ -359,26 +359,31 @@ same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if 'dsaddrs1' contains a subset of 'dsaddrs2'. If it does,
|
||||||
|
* declare a match.
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
_same_data_server_addrs_locked(const struct list_head *dsaddrs1,
|
_same_data_server_addrs_locked(const struct list_head *dsaddrs1,
|
||||||
const struct list_head *dsaddrs2)
|
const struct list_head *dsaddrs2)
|
||||||
{
|
{
|
||||||
struct nfs4_pnfs_ds_addr *da1, *da2;
|
struct nfs4_pnfs_ds_addr *da1, *da2;
|
||||||
|
struct sockaddr *sa1, *sa2;
|
||||||
|
bool match = false;
|
||||||
|
|
||||||
/* step through both lists, comparing as we go */
|
list_for_each_entry(da1, dsaddrs1, da_node) {
|
||||||
for (da1 = list_first_entry(dsaddrs1, typeof(*da1), da_node),
|
sa1 = (struct sockaddr *)&da1->da_addr;
|
||||||
da2 = list_first_entry(dsaddrs2, typeof(*da2), da_node);
|
match = false;
|
||||||
da1 != NULL && da2 != NULL;
|
list_for_each_entry(da2, dsaddrs2, da_node) {
|
||||||
da1 = list_entry(da1->da_node.next, typeof(*da1), da_node),
|
sa2 = (struct sockaddr *)&da2->da_addr;
|
||||||
da2 = list_entry(da2->da_node.next, typeof(*da2), da_node)) {
|
match = same_sockaddr(sa1, sa2);
|
||||||
if (!same_sockaddr((struct sockaddr *)&da1->da_addr,
|
if (match)
|
||||||
(struct sockaddr *)&da2->da_addr))
|
break;
|
||||||
return false;
|
}
|
||||||
|
if (!match)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (da1 == NULL && da2 == NULL)
|
return match;
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue