On Thu, 13 Aug 2015 11:45:49 -0400 Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> wrote: > - Switch back to using list_for_each_entry(). To fix 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@xxxxxxxxxxxxxxx # 4.0+ > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > --- > fs/nfs/pnfs_nfs.c | 33 +++++++++++++++++++-------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c > index cd3c0403101b..bbd407b6bc1f 100644 > --- a/fs/nfs/pnfs_nfs.c > +++ b/fs/nfs/pnfs_nfs.c > @@ -373,26 +373,31 @@ same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2) > return false; > } > > +/* > + * Checks if 'dsaddrs1' contains a subset of 'dsaddrs2'. If it does, > + * declare a match. > + */ > static bool > _same_data_server_addrs_locked(const struct list_head *dsaddrs1, > const struct list_head *dsaddrs2) > { > struct nfs4_pnfs_ds_addr *da1, *da2; > - > - /* step through both lists, comparing as we go */ > - for (da1 = list_first_entry(dsaddrs1, typeof(*da1), da_node), > - da2 = list_first_entry(dsaddrs2, typeof(*da2), da_node); > - da1 != NULL && da2 != NULL; > - da1 = list_entry(da1->da_node.next, typeof(*da1), da_node), > - da2 = list_entry(da2->da_node.next, typeof(*da2), da_node)) { > - if (!same_sockaddr((struct sockaddr *)&da1->da_addr, > - (struct sockaddr *)&da2->da_addr)) > - return false; > + struct sockaddr *sa1, *sa2; > + bool match = false; > + > + list_for_each_entry(da1, dsaddrs1, da_node) { > + sa1 = (struct sockaddr *)&da1->da_addr; > + match = false; > + list_for_each_entry(da2, dsaddrs2, da_node) { > + sa2 = (struct sockaddr *)&da2->da_addr; > + match = same_sockaddr(sa1, sa2); > + if (match) > + break; Sure would be nice to consolidate some of these "same_sockaddr" functions at some point. We also have nfs_sockaddr_cmp which does the exact same thing, and probably some similar ones in the RPC layer. > + } > + if (!match) > + break; > } > - if (da1 == NULL && da2 == NULL) > - return true; > - > - return false; > + return match; > } > > /* Nice catch: Reviewed-by: Jeff Layton <jeff.layton@xxxxxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html