Browse Source

NFSv4.x/pnfs: Don't try to recover stateids twice in layoutget

If the current open or layout stateid doesn't match the stateid used
in the layoutget RPC call, then don't try to recover it.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Trond Myklebust 10 years ago
parent
commit
2259f960b3
1 changed files with 17 additions and 11 deletions
  1. 17 11
      fs/nfs/nfs4proc.c

+ 17 - 11
fs/nfs/nfs4proc.c

@@ -7813,20 +7813,23 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
 			dprintk("%s: NFS4ERR_RECALLCONFLICT waiting %lu\n",
 			dprintk("%s: NFS4ERR_RECALLCONFLICT waiting %lu\n",
 				__func__, delay);
 				__func__, delay);
 			rpc_delay(task, delay);
 			rpc_delay(task, delay);
-			task->tk_status = 0;
-			rpc_restart_call_prepare(task);
-			goto out; /* Do not call nfs4_async_handle_error() */
+			/* Do not call nfs4_async_handle_error() */
+			goto out_restart;
 		}
 		}
 		break;
 		break;
 	case -NFS4ERR_EXPIRED:
 	case -NFS4ERR_EXPIRED:
 	case -NFS4ERR_BAD_STATEID:
 	case -NFS4ERR_BAD_STATEID:
 		spin_lock(&inode->i_lock);
 		spin_lock(&inode->i_lock);
-		lo = NFS_I(inode)->layout;
-		if (!lo || list_empty(&lo->plh_segs)) {
+		if (nfs4_stateid_match(&lgp->args.stateid,
+					&lgp->args.ctx->state->stateid)) {
 			spin_unlock(&inode->i_lock);
 			spin_unlock(&inode->i_lock);
 			/* If the open stateid was bad, then recover it. */
 			/* If the open stateid was bad, then recover it. */
 			state = lgp->args.ctx->state;
 			state = lgp->args.ctx->state;
-		} else {
+			break;
+		}
+		lo = NFS_I(inode)->layout;
+		if (lo && nfs4_stateid_match(&lgp->args.stateid,
+					&lo->plh_stateid)) {
 			LIST_HEAD(head);
 			LIST_HEAD(head);
 
 
 			/*
 			/*
@@ -7837,16 +7840,19 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
 			pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
 			pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
 			spin_unlock(&inode->i_lock);
 			spin_unlock(&inode->i_lock);
 			pnfs_free_lseg_list(&head);
 			pnfs_free_lseg_list(&head);
-	
-			task->tk_status = 0;
-			rpc_restart_call_prepare(task);
-		}
+		} else
+			spin_unlock(&inode->i_lock);
+		goto out_restart;
 	}
 	}
 	if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN)
 	if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN)
-		rpc_restart_call_prepare(task);
+		goto out_restart;
 out:
 out:
 	dprintk("<-- %s\n", __func__);
 	dprintk("<-- %s\n", __func__);
 	return;
 	return;
+out_restart:
+	task->tk_status = 0;
+	rpc_restart_call_prepare(task);
+	return;
 out_overflow:
 out_overflow:
 	task->tk_status = -EOVERFLOW;
 	task->tk_status = -EOVERFLOW;
 	goto out;
 	goto out;