linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] NFSD: Clean up the test_stateid function
@ 2012-01-27 15:22 bjschuma
  2012-03-06 22:12 ` J. Bruce Fields
  0 siblings, 1 reply; 2+ messages in thread
From: bjschuma @ 2012-01-27 15:22 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Bryan Schumaker

From: Bryan Schumaker <bjschuma@netapp.com>

When I initially wrote it, I didn't understand how lists worked so I
wrote something that didn't use them.  I think making a list of stateids
to test is a more straightforward implementation, especially compared to
especially compared to decoding stateids while simultaneously encoding
a reply to the client.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
---
v2: Use defer_free() to free kmalloc()ed memory.

 fs/nfsd/nfs4state.c |    9 ++++++-
 fs/nfsd/nfs4xdr.c   |   66 +++++++++++++++-----------------------------------
 fs/nfsd/xdr4.h      |    9 +++++-
 3 files changed, 35 insertions(+), 49 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e8c98f0..c59a3f6 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3400,7 +3400,14 @@ __be32
 nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		   struct nfsd4_test_stateid *test_stateid)
 {
-	/* real work is done during encoding */
+	struct nfsd4_test_stateid_id *stateid;
+	struct nfs4_client *cl = cstate->session->se_client;
+
+	nfs4_lock_state();
+	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
+		stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid);
+	nfs4_unlock_state();
+
 	return nfs_ok;
 }
 
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0ec5a1b..5785a98 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -133,22 +133,6 @@ xdr_error:					\
 	}					\
 } while (0)
 
-static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
-{
-	savep->p        = argp->p;
-	savep->end      = argp->end;
-	savep->pagelen  = argp->pagelen;
-	savep->pagelist = argp->pagelist;
-}
-
-static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
-{
-	argp->p        = savep->p;
-	argp->end      = savep->end;
-	argp->pagelen  = savep->pagelen;
-	argp->pagelist = savep->pagelist;
-}
-
 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
 {
 	/* We want more bytes than seem to be available.
@@ -1385,26 +1369,29 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
 {
-	unsigned int nbytes;
-	stateid_t si;
 	int i;
-	__be32 *p;
-	__be32 status;
+	__be32 *p, status;
+	struct nfsd4_test_stateid_id *stateid;
 
 	READ_BUF(4);
 	test_stateid->ts_num_ids = ntohl(*p++);
 
-	nbytes = test_stateid->ts_num_ids * sizeof(stateid_t);
-	if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
-		goto xdr_error;
-
-	test_stateid->ts_saved_args = argp;
-	save_buf(argp, &test_stateid->ts_savedp);
+	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
 
 	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		status = nfsd4_decode_stateid(argp, &si);
+		stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
+		if (!stateid) {
+			status = PTR_ERR(stateid);
+			goto out;
+		}
+
+		defer_free(argp, kfree, stateid);
+		INIT_LIST_HEAD(&stateid->ts_id_list);
+		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
+
+		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
 		if (status)
-			return status;
+			goto out;
 	}
 
 	status = 0;
@@ -3391,30 +3378,17 @@ __be32
 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
 			  struct nfsd4_test_stateid *test_stateid)
 {
-	struct nfsd4_compoundargs *argp;
-	struct nfs4_client *cl = resp->cstate.session->se_client;
-	stateid_t si;
+	struct nfsd4_test_stateid_id *stateid, *next;
 	__be32 *p;
-	int i;
-	int valid;
 
-	restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
-	argp = test_stateid->ts_saved_args;
-
-	RESERVE_SPACE(4);
+	RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
 	*p++ = htonl(test_stateid->ts_num_ids);
-	resp->p = p;
 
-	nfs4_lock_state();
-	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		nfsd4_decode_stateid(argp, &si);
-		valid = nfs4_validate_stateid(cl, &si);
-		RESERVE_SPACE(4);
-		*p++ = htonl(valid);
-		resp->p = p;
+	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
+		*p++ = htonl(stateid->ts_id_status);
 	}
-	nfs4_unlock_state();
 
+	ADJUST_ARGS();
 	return nfserr;
 }
 
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 2364747..0a667e9 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -343,10 +343,15 @@ struct nfsd4_saved_compoundargs {
 	struct page **pagelist;
 };
 
+struct nfsd4_test_stateid_id {
+	__be32			ts_id_status;
+	stateid_t		ts_id_stateid;
+	struct list_head	ts_id_list;
+};
+
 struct nfsd4_test_stateid {
 	__be32		ts_num_ids;
-	struct nfsd4_compoundargs *ts_saved_args;
-	struct nfsd4_saved_compoundargs ts_savedp;
+	struct list_head ts_stateid_list;
 };
 
 struct nfsd4_free_stateid {
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] NFSD: Clean up the test_stateid function
  2012-01-27 15:22 [PATCH v2] NFSD: Clean up the test_stateid function bjschuma
@ 2012-03-06 22:12 ` J. Bruce Fields
  0 siblings, 0 replies; 2+ messages in thread
From: J. Bruce Fields @ 2012-03-06 22:12 UTC (permalink / raw)
  To: bjschuma; +Cc: linux-nfs

On Fri, Jan 27, 2012 at 10:22:49AM -0500, bjschuma@netapp.com wrote:
> From: Bryan Schumaker <bjschuma@netapp.com>
> 
> When I initially wrote it, I didn't understand how lists worked so I
> wrote something that didn't use them.  I think making a list of stateids
> to test is a more straightforward implementation, especially compared to
> especially compared to decoding stateids while simultaneously encoding
> a reply to the client.

I've applied this and pushed it out.  Sorry, can't remember if I replied
before, just noticed this still in my inbox....--b.

> 
> Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
> ---
> v2: Use defer_free() to free kmalloc()ed memory.
> 
>  fs/nfsd/nfs4state.c |    9 ++++++-
>  fs/nfsd/nfs4xdr.c   |   66 +++++++++++++++-----------------------------------
>  fs/nfsd/xdr4.h      |    9 +++++-
>  3 files changed, 35 insertions(+), 49 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index e8c98f0..c59a3f6 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -3400,7 +3400,14 @@ __be32
>  nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>  		   struct nfsd4_test_stateid *test_stateid)
>  {
> -	/* real work is done during encoding */
> +	struct nfsd4_test_stateid_id *stateid;
> +	struct nfs4_client *cl = cstate->session->se_client;
> +
> +	nfs4_lock_state();
> +	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
> +		stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid);
> +	nfs4_unlock_state();
> +
>  	return nfs_ok;
>  }
>  
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 0ec5a1b..5785a98 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -133,22 +133,6 @@ xdr_error:					\
>  	}					\
>  } while (0)
>  
> -static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
> -{
> -	savep->p        = argp->p;
> -	savep->end      = argp->end;
> -	savep->pagelen  = argp->pagelen;
> -	savep->pagelist = argp->pagelist;
> -}
> -
> -static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
> -{
> -	argp->p        = savep->p;
> -	argp->end      = savep->end;
> -	argp->pagelen  = savep->pagelen;
> -	argp->pagelist = savep->pagelist;
> -}
> -
>  static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
>  {
>  	/* We want more bytes than seem to be available.
> @@ -1385,26 +1369,29 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
>  static __be32
>  nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
>  {
> -	unsigned int nbytes;
> -	stateid_t si;
>  	int i;
> -	__be32 *p;
> -	__be32 status;
> +	__be32 *p, status;
> +	struct nfsd4_test_stateid_id *stateid;
>  
>  	READ_BUF(4);
>  	test_stateid->ts_num_ids = ntohl(*p++);
>  
> -	nbytes = test_stateid->ts_num_ids * sizeof(stateid_t);
> -	if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
> -		goto xdr_error;
> -
> -	test_stateid->ts_saved_args = argp;
> -	save_buf(argp, &test_stateid->ts_savedp);
> +	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
>  
>  	for (i = 0; i < test_stateid->ts_num_ids; i++) {
> -		status = nfsd4_decode_stateid(argp, &si);
> +		stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
> +		if (!stateid) {
> +			status = PTR_ERR(stateid);
> +			goto out;
> +		}
> +
> +		defer_free(argp, kfree, stateid);
> +		INIT_LIST_HEAD(&stateid->ts_id_list);
> +		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
> +
> +		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
>  		if (status)
> -			return status;
> +			goto out;
>  	}
>  
>  	status = 0;
> @@ -3391,30 +3378,17 @@ __be32
>  nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
>  			  struct nfsd4_test_stateid *test_stateid)
>  {
> -	struct nfsd4_compoundargs *argp;
> -	struct nfs4_client *cl = resp->cstate.session->se_client;
> -	stateid_t si;
> +	struct nfsd4_test_stateid_id *stateid, *next;
>  	__be32 *p;
> -	int i;
> -	int valid;
>  
> -	restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
> -	argp = test_stateid->ts_saved_args;
> -
> -	RESERVE_SPACE(4);
> +	RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
>  	*p++ = htonl(test_stateid->ts_num_ids);
> -	resp->p = p;
>  
> -	nfs4_lock_state();
> -	for (i = 0; i < test_stateid->ts_num_ids; i++) {
> -		nfsd4_decode_stateid(argp, &si);
> -		valid = nfs4_validate_stateid(cl, &si);
> -		RESERVE_SPACE(4);
> -		*p++ = htonl(valid);
> -		resp->p = p;
> +	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
> +		*p++ = htonl(stateid->ts_id_status);
>  	}
> -	nfs4_unlock_state();
>  
> +	ADJUST_ARGS();
>  	return nfserr;
>  }
>  
> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
> index 2364747..0a667e9 100644
> --- a/fs/nfsd/xdr4.h
> +++ b/fs/nfsd/xdr4.h
> @@ -343,10 +343,15 @@ struct nfsd4_saved_compoundargs {
>  	struct page **pagelist;
>  };
>  
> +struct nfsd4_test_stateid_id {
> +	__be32			ts_id_status;
> +	stateid_t		ts_id_stateid;
> +	struct list_head	ts_id_list;
> +};
> +
>  struct nfsd4_test_stateid {
>  	__be32		ts_num_ids;
> -	struct nfsd4_compoundargs *ts_saved_args;
> -	struct nfsd4_saved_compoundargs ts_savedp;
> +	struct list_head ts_stateid_list;
>  };
>  
>  struct nfsd4_free_stateid {
> -- 
> 1.7.8.4
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-03-06 22:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-27 15:22 [PATCH v2] NFSD: Clean up the test_stateid function bjschuma
2012-03-06 22:12 ` J. Bruce Fields

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).