diff mbox

[1/2] NFS: Remove bad delegations during open recovery

Message ID 1348679579-7888-1-git-send-email-bjschuma@netapp.com (mailing list archive)
State New, archived
Headers show

Commit Message

Bryan Schumaker Sept. 26, 2012, 5:12 p.m. UTC
From: Bryan Schumaker <bjschuma@netapp.com>

I put the client into an open recovery loop by:
	Client: Open file
		read half
	Server: Expire client (echo 0 > /sys/kernel/debug/nfsd/forget_clients)
	Client: Drop vm cache (echo 3 > /proc/sys/vm/drop_caches)
		finish reading file

This causes a loop because the client never updates the nfs4_state after
discovering that the delegation is invalid.  This means it will keep
trying to read using the bad delegation rather than attempting to re-open
the file.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
---
 fs/nfs/nfs4proc.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Trond Myklebust Sept. 26, 2012, 7:07 p.m. UTC | #1
On Wed, 2012-09-26 at 13:12 -0400, bjschuma@netapp.com wrote:
> From: Bryan Schumaker <bjschuma@netapp.com>

> 

> I put the client into an open recovery loop by:

> 	Client: Open file

> 		read half

> 	Server: Expire client (echo 0 > /sys/kernel/debug/nfsd/forget_clients)

> 	Client: Drop vm cache (echo 3 > /proc/sys/vm/drop_caches)

> 		finish reading file

> 

> This causes a loop because the client never updates the nfs4_state after

> discovering that the delegation is invalid.  This means it will keep

> trying to read using the bad delegation rather than attempting to re-open

> the file.

> 

> Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>

> ---

>  fs/nfs/nfs4proc.c | 2 ++

>  1 file changed, 2 insertions(+)

> 

> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c

> index 1e50326..e47ec55 100644

> --- a/fs/nfs/nfs4proc.c

> +++ b/fs/nfs/nfs4proc.c

> @@ -1774,7 +1774,9 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)

>  		 * informs us the stateid is unrecognized. */

>  		if (status != -NFS4ERR_BAD_STATEID)

>  			nfs41_free_stateid(server, stateid);

> +		nfs_remove_bad_delegation(state->inode);

>  

> +		nfs4_stateid_copy(&state->stateid, &state->open_stateid);


nfs4_stateid_copy needs to be write-protected by the state->seqlock
here.

>  		clear_bit(NFS_DELEGATED_STATE, &state->flags);

>  	}

>  }


-- 
Trond Myklebust
Linux NFS client maintainer

NetApp
Trond.Myklebust@netapp.com
www.netapp.com
diff mbox

Patch

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1e50326..e47ec55 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1774,7 +1774,9 @@  static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
 		 * informs us the stateid is unrecognized. */
 		if (status != -NFS4ERR_BAD_STATEID)
 			nfs41_free_stateid(server, stateid);
+		nfs_remove_bad_delegation(state->inode);
 
+		nfs4_stateid_copy(&state->stateid, &state->open_stateid);
 		clear_bit(NFS_DELEGATED_STATE, &state->flags);
 	}
 }