Commit 7af7a596 authored by Trond Myklebust's avatar Trond Myklebust

Merge branch 'bugfixes'

parents b7561e51 53a75f22
...@@ -303,6 +303,17 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, ...@@ -303,6 +303,17 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
struct rpc_cred *newcred = NULL; struct rpc_cred *newcred = NULL;
rpc_authflavor_t flavor; rpc_authflavor_t flavor;
if (sp4_mode == NFS_SP4_MACH_CRED_CLEANUP ||
sp4_mode == NFS_SP4_MACH_CRED_PNFS_CLEANUP) {
/* Using machine creds for cleanup operations
* is only relevent if the client credentials
* might expire. So don't bother for
* RPC_AUTH_UNIX. If file was only exported to
* sec=sys, the PUTFH would fail anyway.
*/
if ((*clntp)->cl_auth->au_flavor == RPC_AUTH_UNIX)
return false;
}
if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
if (clp->cl_machine_cred != NULL) if (clp->cl_machine_cred != NULL)
......
...@@ -682,12 +682,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, ...@@ -682,12 +682,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
const struct nfs_pgio_completion_ops *compl_ops, const struct nfs_pgio_completion_ops *compl_ops,
const struct nfs_rw_ops *rw_ops, const struct nfs_rw_ops *rw_ops,
size_t bsize, size_t bsize,
int io_flags, int io_flags)
gfp_t gfp_flags)
{ {
struct nfs_pgio_mirror *new;
int i;
desc->pg_moreio = 0; desc->pg_moreio = 0;
desc->pg_inode = inode; desc->pg_inode = inode;
desc->pg_ops = pg_ops; desc->pg_ops = pg_ops;
...@@ -703,23 +699,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, ...@@ -703,23 +699,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
desc->pg_mirror_count = 1; desc->pg_mirror_count = 1;
desc->pg_mirror_idx = 0; desc->pg_mirror_idx = 0;
if (pg_ops->pg_get_mirror_count) {
/* until we have a request, we don't have an lseg and no
* idea how many mirrors there will be */
new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX,
sizeof(struct nfs_pgio_mirror), gfp_flags);
desc->pg_mirrors_dynamic = new;
desc->pg_mirrors = new;
for (i = 0; i < NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX; i++)
nfs_pageio_mirror_init(&desc->pg_mirrors[i], bsize);
} else {
desc->pg_mirrors_dynamic = NULL; desc->pg_mirrors_dynamic = NULL;
desc->pg_mirrors = desc->pg_mirrors_static; desc->pg_mirrors = desc->pg_mirrors_static;
nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize); nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize);
}
} }
EXPORT_SYMBOL_GPL(nfs_pageio_init);
/** /**
* nfs_pgio_result - Basic pageio error handling * nfs_pgio_result - Basic pageio error handling
...@@ -836,32 +819,52 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) ...@@ -836,32 +819,52 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc)
return ret; return ret;
} }
static struct nfs_pgio_mirror *
nfs_pageio_alloc_mirrors(struct nfs_pageio_descriptor *desc,
unsigned int mirror_count)
{
struct nfs_pgio_mirror *ret;
unsigned int i;
kfree(desc->pg_mirrors_dynamic);
desc->pg_mirrors_dynamic = NULL;
if (mirror_count == 1)
return desc->pg_mirrors_static;
ret = kmalloc_array(mirror_count, sizeof(*ret), GFP_NOFS);
if (ret != NULL) {
for (i = 0; i < mirror_count; i++)
nfs_pageio_mirror_init(&ret[i], desc->pg_bsize);
desc->pg_mirrors_dynamic = ret;
}
return ret;
}
/* /*
* nfs_pageio_setup_mirroring - determine if mirroring is to be used * nfs_pageio_setup_mirroring - determine if mirroring is to be used
* by calling the pg_get_mirror_count op * by calling the pg_get_mirror_count op
*/ */
static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, static void nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req) struct nfs_page *req)
{ {
int mirror_count = 1; unsigned int mirror_count = 1;
if (!pgio->pg_ops->pg_get_mirror_count)
return 0;
if (pgio->pg_ops->pg_get_mirror_count)
mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
if (mirror_count == pgio->pg_mirror_count || pgio->pg_error < 0)
return;
if (pgio->pg_error < 0) if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) {
return pgio->pg_error; pgio->pg_error = -EINVAL;
return;
if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) }
return -EINVAL;
if (WARN_ON_ONCE(!pgio->pg_mirrors_dynamic))
return -EINVAL;
pgio->pg_mirrors = nfs_pageio_alloc_mirrors(pgio, mirror_count);
if (pgio->pg_mirrors == NULL) {
pgio->pg_error = -ENOMEM;
pgio->pg_mirrors = pgio->pg_mirrors_static;
mirror_count = 1;
}
pgio->pg_mirror_count = mirror_count; pgio->pg_mirror_count = mirror_count;
return 0;
} }
/* /*
......
...@@ -68,7 +68,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, ...@@ -68,7 +68,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
pg_ops = server->pnfs_curr_ld->pg_read_ops; pg_ops = server->pnfs_curr_ld->pg_read_ops;
#endif #endif
nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_read_ops, nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_read_ops,
server->rsize, 0, GFP_KERNEL); server->rsize, 0);
} }
EXPORT_SYMBOL_GPL(nfs_pageio_init_read); EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
......
...@@ -1691,8 +1691,8 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, ...@@ -1691,8 +1691,8 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args,
rpc_authflavor_t *server_authlist, unsigned int count) rpc_authflavor_t *server_authlist, unsigned int count)
{ {
rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR; rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
bool found_auth_null = false;
unsigned int i; unsigned int i;
int use_auth_null = false;
/* /*
* If the sec= mount option is used, the specified flavor or AUTH_NULL * If the sec= mount option is used, the specified flavor or AUTH_NULL
...@@ -1701,6 +1701,10 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, ...@@ -1701,6 +1701,10 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args,
* AUTH_NULL has a special meaning when it's in the server list - it * AUTH_NULL has a special meaning when it's in the server list - it
* means that the server will ignore the rpc creds, so any flavor * means that the server will ignore the rpc creds, so any flavor
* can be used but still use the sec= that was specified. * can be used but still use the sec= that was specified.
*
* Note also that the MNT procedure in MNTv1 does not return a list
* of supported security flavors. In this case, nfs_mount() fabricates
* a security flavor list containing just AUTH_NULL.
*/ */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
flavor = server_authlist[i]; flavor = server_authlist[i];
...@@ -1709,11 +1713,11 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args, ...@@ -1709,11 +1713,11 @@ static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args,
goto out; goto out;
if (flavor == RPC_AUTH_NULL) if (flavor == RPC_AUTH_NULL)
use_auth_null = true; found_auth_null = true;
} }
if (use_auth_null) { if (found_auth_null) {
flavor = RPC_AUTH_NULL; flavor = args->auth_info.flavors[0];
goto out; goto out;
} }
......
...@@ -1424,7 +1424,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, ...@@ -1424,7 +1424,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
pg_ops = server->pnfs_curr_ld->pg_write_ops; pg_ops = server->pnfs_curr_ld->pg_write_ops;
#endif #endif
nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_write_ops, nfs_pageio_init(pgio, inode, pg_ops, compl_ops, &nfs_rw_write_ops,
server->wsize, ioflags, GFP_NOIO); server->wsize, ioflags);
} }
EXPORT_SYMBOL_GPL(nfs_pageio_init_write); EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
......
...@@ -125,8 +125,7 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, ...@@ -125,8 +125,7 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
const struct nfs_pgio_completion_ops *compl_ops, const struct nfs_pgio_completion_ops *compl_ops,
const struct nfs_rw_ops *rw_ops, const struct nfs_rw_ops *rw_ops,
size_t bsize, size_t bsize,
int how, int how);
gfp_t gfp_flags);
extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
struct nfs_page *); struct nfs_page *);
extern int nfs_pageio_resend(struct nfs_pageio_descriptor *, extern int nfs_pageio_resend(struct nfs_pageio_descriptor *,
......
...@@ -1903,6 +1903,14 @@ call_connect_status(struct rpc_task *task) ...@@ -1903,6 +1903,14 @@ call_connect_status(struct rpc_task *task)
task->tk_status = 0; task->tk_status = 0;
switch (status) { switch (status) {
case -ECONNREFUSED: case -ECONNREFUSED:
/* A positive refusal suggests a rebind is needed. */
if (RPC_IS_SOFTCONN(task))
break;
if (clnt->cl_autobind) {
rpc_force_rebind(clnt);
task->tk_action = call_bind;
return;
}
case -ECONNRESET: case -ECONNRESET:
case -ECONNABORTED: case -ECONNABORTED:
case -ENETUNREACH: case -ENETUNREACH:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment