Re: [PATCH v2] NFSD: Clean up the test_stateid function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 27, 2012 at 10:22:49AM -0500, bjschuma@xxxxxxxxxx wrote:
> From: Bryan Schumaker <bjschuma@xxxxxxxxxx>
> 
> 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@xxxxxxxxxx>
> ---
> 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
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux