Merge branch 'bugfixes'
* bugfixes: SUNRPC: Fix a thinko in xs_connect() NFSv4.1/pNFS: Fix borken function _same_data_server_addrs_locked() NFS: nfs_set_pgio_error sometimes misses errors
This commit is contained in:
commit
37bfcc14b2
|
@ -77,8 +77,8 @@ EXPORT_SYMBOL_GPL(nfs_pgheader_init);
|
||||||
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
|
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
|
||||||
{
|
{
|
||||||
spin_lock(&hdr->lock);
|
spin_lock(&hdr->lock);
|
||||||
if (pos < hdr->io_start + hdr->good_bytes) {
|
if (!test_and_set_bit(NFS_IOHDR_ERROR, &hdr->flags)
|
||||||
set_bit(NFS_IOHDR_ERROR, &hdr->flags);
|
|| pos < hdr->io_start + hdr->good_bytes) {
|
||||||
clear_bit(NFS_IOHDR_EOF, &hdr->flags);
|
clear_bit(NFS_IOHDR_EOF, &hdr->flags);
|
||||||
hdr->good_bytes = pos - hdr->io_start;
|
hdr->good_bytes = pos - hdr->io_start;
|
||||||
hdr->error = error;
|
hdr->error = error;
|
||||||
|
|
|
@ -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 (da1 == NULL && da2 == NULL)
|
if (!match)
|
||||||
return true;
|
break;
|
||||||
|
}
|
||||||
return false;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2279,13 +2279,14 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
||||||
|
|
||||||
WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
|
WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
|
||||||
|
|
||||||
/* Start by resetting any existing state */
|
if (transport->sock != NULL) {
|
||||||
xs_reset_transport(transport);
|
|
||||||
|
|
||||||
if (transport->sock != NULL && !RPC_IS_SOFTCONN(task)) {
|
|
||||||
dprintk("RPC: xs_connect delayed xprt %p for %lu "
|
dprintk("RPC: xs_connect delayed xprt %p for %lu "
|
||||||
"seconds\n",
|
"seconds\n",
|
||||||
xprt, xprt->reestablish_timeout / HZ);
|
xprt, xprt->reestablish_timeout / HZ);
|
||||||
|
|
||||||
|
/* Start by resetting any existing state */
|
||||||
|
xs_reset_transport(transport);
|
||||||
|
|
||||||
queue_delayed_work(rpciod_workqueue,
|
queue_delayed_work(rpciod_workqueue,
|
||||||
&transport->connect_worker,
|
&transport->connect_worker,
|
||||||
xprt->reestablish_timeout);
|
xprt->reestablish_timeout);
|
||||||
|
|
Loading…
Reference in New Issue