summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /fs/nfs/nfs4state.c
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c273
1 files changed, 21 insertions, 252 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 059c01b..cc14cbb 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -239,12 +239,14 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
}
}
+#if defined(CONFIG_NFS_V4_1)
+
static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
{
set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
spin_lock(&tbl->slot_tbl_lock);
if (tbl->highest_used_slotid != NFS4_NO_SLOT) {
- reinit_completion(&tbl->complete);
+ INIT_COMPLETION(tbl->complete);
spin_unlock(&tbl->slot_tbl_lock);
return wait_for_completion_interruptible(&tbl->complete);
}
@@ -268,8 +270,6 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
return nfs4_drain_slot_tbl(&ses->fc_slot_table);
}
-#if defined(CONFIG_NFS_V4_1)
-
static int nfs41_setup_state_renewal(struct nfs_client *clp)
{
int status;
@@ -1197,74 +1197,20 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
}
EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery);
-/**
- * nfs4_schedule_migration_recovery - trigger migration recovery
- *
- * @server: FSID that is migrating
- *
- * Returns zero if recovery has started, otherwise a negative NFS4ERR
- * value is returned.
- */
-int nfs4_schedule_migration_recovery(const struct nfs_server *server)
-{
- struct nfs_client *clp = server->nfs_client;
-
- if (server->fh_expire_type != NFS4_FH_PERSISTENT) {
- pr_err("NFS: volatile file handles not supported (server %s)\n",
- clp->cl_hostname);
- return -NFS4ERR_IO;
- }
-
- if (test_bit(NFS_MIG_FAILED, &server->mig_status))
- return -NFS4ERR_IO;
-
- dprintk("%s: scheduling migration recovery for (%llx:%llx) on %s\n",
- __func__,
- (unsigned long long)server->fsid.major,
- (unsigned long long)server->fsid.minor,
- clp->cl_hostname);
-
- set_bit(NFS_MIG_IN_TRANSITION,
- &((struct nfs_server *)server)->mig_status);
- set_bit(NFS4CLNT_MOVED, &clp->cl_state);
-
- nfs4_schedule_state_manager(clp);
- return 0;
-}
-EXPORT_SYMBOL_GPL(nfs4_schedule_migration_recovery);
-
-/**
- * nfs4_schedule_lease_moved_recovery - start lease-moved recovery
- *
- * @clp: server to check for moved leases
- *
- */
-void nfs4_schedule_lease_moved_recovery(struct nfs_client *clp)
-{
- dprintk("%s: scheduling lease-moved recovery for client ID %llx on %s\n",
- __func__, clp->cl_clientid, clp->cl_hostname);
-
- set_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state);
- nfs4_schedule_state_manager(clp);
-}
-EXPORT_SYMBOL_GPL(nfs4_schedule_lease_moved_recovery);
-
int nfs4_wait_clnt_recover(struct nfs_client *clp)
{
int res;
might_sleep();
- atomic_inc(&clp->cl_count);
res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
nfs_wait_bit_killable, TASK_KILLABLE);
if (res)
- goto out;
+ return res;
+
if (clp->cl_cons_state < 0)
- res = clp->cl_cons_state;
-out:
- nfs_put_client(clp);
- return res;
+ return clp->cl_cons_state;
+ return 0;
}
int nfs4_client_recover_expired_lease(struct nfs_client *clp)
@@ -1429,8 +1375,8 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
goto out;
default:
- printk(KERN_ERR "NFS: %s: unhandled error %d\n",
- __func__, status);
+ printk(KERN_ERR "NFS: %s: unhandled error %d. "
+ "Zeroing state\n", __func__, status);
case -ENOMEM:
case -NFS4ERR_DENIED:
case -NFS4ERR_RECLAIM_BAD:
@@ -1476,7 +1422,7 @@ restart:
if (status >= 0) {
status = nfs4_reclaim_locks(state, ops);
if (status >= 0) {
- if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) {
+ if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) {
spin_lock(&state->state_lock);
list_for_each_entry(lock, &state->lock_states, ls_locks) {
if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
@@ -1493,12 +1439,15 @@ restart:
}
switch (status) {
default:
- printk(KERN_ERR "NFS: %s: unhandled error %d\n",
- __func__, status);
+ printk(KERN_ERR "NFS: %s: unhandled error %d. "
+ "Zeroing state\n", __func__, status);
case -ENOENT:
case -ENOMEM:
case -ESTALE:
- /* Open state on this file cannot be recovered */
+ /*
+ * Open state on this file cannot be recovered
+ * All we can do is revert to using the zero stateid.
+ */
nfs4_state_mark_recovery_failed(state, status);
break;
case -EAGAIN:
@@ -1679,6 +1628,7 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
nfs4_state_end_reclaim_reboot(clp);
break;
case -NFS4ERR_STALE_CLIENTID:
+ case -NFS4ERR_LEASE_MOVED:
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
nfs4_state_clear_reclaim_reboot(clp);
nfs4_state_start_reclaim_reboot(clp);
@@ -1879,168 +1829,6 @@ static int nfs4_purge_lease(struct nfs_client *clp)
return 0;
}
-/*
- * Try remote migration of one FSID from a source server to a
- * destination server. The source server provides a list of
- * potential destinations.
- *
- * Returns zero or a negative NFS4ERR status code.
- */
-static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
-{
- struct nfs_client *clp = server->nfs_client;
- struct nfs4_fs_locations *locations = NULL;
- struct inode *inode;
- struct page *page;
- int status, result;
-
- dprintk("--> %s: FSID %llx:%llx on \"%s\"\n", __func__,
- (unsigned long long)server->fsid.major,
- (unsigned long long)server->fsid.minor,
- clp->cl_hostname);
-
- result = 0;
- page = alloc_page(GFP_KERNEL);
- locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
- if (page == NULL || locations == NULL) {
- dprintk("<-- %s: no memory\n", __func__);
- goto out;
- }
-
- inode = server->super->s_root->d_inode;
- result = nfs4_proc_get_locations(inode, locations, page, cred);
- if (result) {
- dprintk("<-- %s: failed to retrieve fs_locations: %d\n",
- __func__, result);
- goto out;
- }
-
- result = -NFS4ERR_NXIO;
- if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) {
- dprintk("<-- %s: No fs_locations data, migration skipped\n",
- __func__);
- goto out;
- }
-
- nfs4_begin_drain_session(clp);
-
- status = nfs4_replace_transport(server, locations);
- if (status != 0) {
- dprintk("<-- %s: failed to replace transport: %d\n",
- __func__, status);
- goto out;
- }
-
- result = 0;
- dprintk("<-- %s: migration succeeded\n", __func__);
-
-out:
- if (page != NULL)
- __free_page(page);
- kfree(locations);
- if (result) {
- pr_err("NFS: migration recovery failed (server %s)\n",
- clp->cl_hostname);
- set_bit(NFS_MIG_FAILED, &server->mig_status);
- }
- return result;
-}
-
-/*
- * Returns zero or a negative NFS4ERR status code.
- */
-static int nfs4_handle_migration(struct nfs_client *clp)
-{
- const struct nfs4_state_maintenance_ops *ops =
- clp->cl_mvops->state_renewal_ops;
- struct nfs_server *server;
- struct rpc_cred *cred;
-
- dprintk("%s: migration reported on \"%s\"\n", __func__,
- clp->cl_hostname);
-
- spin_lock(&clp->cl_lock);
- cred = ops->get_state_renewal_cred_locked(clp);
- spin_unlock(&clp->cl_lock);
- if (cred == NULL)
- return -NFS4ERR_NOENT;
-
- clp->cl_mig_gen++;
-restart:
- rcu_read_lock();
- list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
- int status;
-
- if (server->mig_gen == clp->cl_mig_gen)
- continue;
- server->mig_gen = clp->cl_mig_gen;
-
- if (!test_and_clear_bit(NFS_MIG_IN_TRANSITION,
- &server->mig_status))
- continue;
-
- rcu_read_unlock();
- status = nfs4_try_migration(server, cred);
- if (status < 0) {
- put_rpccred(cred);
- return status;
- }
- goto restart;
- }
- rcu_read_unlock();
- put_rpccred(cred);
- return 0;
-}
-
-/*
- * Test each nfs_server on the clp's cl_superblocks list to see
- * if it's moved to another server. Stop when the server no longer
- * returns NFS4ERR_LEASE_MOVED.
- */
-static int nfs4_handle_lease_moved(struct nfs_client *clp)
-{
- const struct nfs4_state_maintenance_ops *ops =
- clp->cl_mvops->state_renewal_ops;
- struct nfs_server *server;
- struct rpc_cred *cred;
-
- dprintk("%s: lease moved reported on \"%s\"\n", __func__,
- clp->cl_hostname);
-
- spin_lock(&clp->cl_lock);
- cred = ops->get_state_renewal_cred_locked(clp);
- spin_unlock(&clp->cl_lock);
- if (cred == NULL)
- return -NFS4ERR_NOENT;
-
- clp->cl_mig_gen++;
-restart:
- rcu_read_lock();
- list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
- struct inode *inode;
- int status;
-
- if (server->mig_gen == clp->cl_mig_gen)
- continue;
- server->mig_gen = clp->cl_mig_gen;
-
- rcu_read_unlock();
-
- inode = server->super->s_root->d_inode;
- status = nfs4_proc_fsid_present(inode, cred);
- if (status != -NFS4ERR_MOVED)
- goto restart; /* wasn't this one */
- if (nfs4_try_migration(server, cred) == -NFS4ERR_LEASE_MOVED)
- goto restart; /* there are more */
- goto out;
- }
- rcu_read_unlock();
-
-out:
- put_rpccred(cred);
- return 0;
-}
-
/**
* nfs4_discover_server_trunking - Detect server IP address trunking
*
@@ -2093,15 +1881,10 @@ again:
nfs4_root_machine_cred(clp);
goto again;
}
- if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX)
+ if (i > 2)
break;
case -NFS4ERR_CLID_INUSE:
case -NFS4ERR_WRONGSEC:
- /* No point in retrying if we already used RPC_AUTH_UNIX */
- if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX) {
- status = -EPERM;
- break;
- }
clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_UNIX);
if (IS_ERR(clnt)) {
status = PTR_ERR(clnt);
@@ -2234,10 +2017,9 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
nfs41_handle_server_reboot(clp);
if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
- SEQ4_STATUS_ADMIN_STATE_REVOKED))
+ SEQ4_STATUS_ADMIN_STATE_REVOKED |
+ SEQ4_STATUS_LEASE_MOVED))
nfs41_handle_state_revoked(clp);
- if (flags & SEQ4_STATUS_LEASE_MOVED)
- nfs4_schedule_lease_moved_recovery(clp);
if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
nfs41_handle_recallable_state_revoked(clp);
if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT)
@@ -2375,20 +2157,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
status = nfs4_check_lease(clp);
if (status < 0)
goto out_error;
- }
-
- if (test_and_clear_bit(NFS4CLNT_MOVED, &clp->cl_state)) {
- section = "migration";
- status = nfs4_handle_migration(clp);
- if (status < 0)
- goto out_error;
- }
-
- if (test_and_clear_bit(NFS4CLNT_LEASE_MOVED, &clp->cl_state)) {
- section = "lease moved";
- status = nfs4_handle_lease_moved(clp);
- if (status < 0)
- goto out_error;
+ continue;
}
/* First recover reboot state... */