All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bryan Schumaker <bjschuma@netapp.com>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH 1/2] NFSD: added FREE_STATEID operation
Date: Wed, 11 May 2011 10:41:01 -0400	[thread overview]
Message-ID: <4DCA9FFD.5070707@netapp.com> (raw)
In-Reply-To: <20110510003624.GB3600@fieldses.org>

On 05/09/2011 08:36 PM, J. Bruce Fields wrote:
> On Fri, May 06, 2011 at 02:57:34PM -0400, bjschuma@netapp.com wrote:
>> From: Bryan Schumaker <bjschuma@netapp.com>
>>
>> This operation is used by the client to tell the server to free a
>> stateid.
>>
>> Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
>> ---
>>  fs/nfsd/nfs4proc.c  |    5 ++++
>>  fs/nfsd/nfs4state.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  fs/nfsd/nfs4xdr.c   |   32 +++++++++++++++++++++++++++-
>>  fs/nfsd/xdr4.h      |    8 +++++++
>>  4 files changed, 99 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
>> index 3a6dbd7..7e00116 100644
>> --- a/fs/nfsd/nfs4proc.c
>> +++ b/fs/nfsd/nfs4proc.c
>> @@ -1412,6 +1412,11 @@ static struct nfsd4_operation nfsd4_ops[] = {
>>  		.op_flags = OP_HANDLES_WRONGSEC,
>>  		.op_name = "OP_SECINFO_NO_NAME",
>>  	},
>> +	[OP_FREE_STATEID] = {
>> +		.op_func = (nfsd4op_func)nfsd4_free_stateid,
>> +		.op_flags = ALLOWED_WITHOUT_FH,
>> +		.op_name = "OP_FREE_STATEID",
>> +	},
>>  };
>>  
>>  static const char *nfsd4_op_name(unsigned opnum)
>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
>> index a2ea14f..6beec13 100644
>> --- a/fs/nfsd/nfs4state.c
>> +++ b/fs/nfsd/nfs4state.c
>> @@ -60,6 +60,7 @@ static u64 current_sessionid = 1;
>>  
>>  /* forward declarations */
>>  static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
>> +static struct nfs4_stateid * search_for_stateid(stateid_t *stid);
>>  static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
>>  static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
>>  static void nfs4_set_recdir(char *recdir);
>> @@ -316,6 +317,12 @@ static struct list_head	unconf_id_hashtbl[CLIENT_HASH_SIZE];
>>  static struct list_head client_lru;
>>  static struct list_head close_lru;
>>  
>> +static int
>> +stateid_has_locks(struct nfs4_stateid *stp)
>> +{
>> +	return list_empty(&stp->st_lockowners);
>> +}
> 
> There may be lockowners that aren't associated with any current locks.
> 
> The only way we have to check this currently is to walk through the
> i_flock list for the given inode, like check_for_locks() does.  That may
> be the expedient thing to do for now.

Ok, I'll change it to use check_for_locks() for now.

> 
> (It would be simpler if we could, say, keep a count of the locks
> associated with each lock stateid.  That's not as easy as it sounds,
> thanks to merging and splitting of byte-range locks.  But we could use
> callbacks from locks.c to do it.  I think that's what I'd really like to
> do.)
> 
>> +
>>  /*
>>   * We store the NONE, READ, WRITE, and BOTH bits separately in the
>>   * st_{access,deny}_bmap field of the stateid, in order to track not
>> @@ -3212,6 +3219,33 @@ out:
>>  	return status;
>>  }
>>  
>> +/*
>> + * Free a state id
>> + */
>> +__be32
>> +nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>> +		   struct nfsd4_free_stateid *free_stateid)
>> +{
>> +	struct nfs4_stateid *stp = NULL;
>> +	stateid_t *stateid = &free_stateid->fr_stateid;
>> +
>> +	stp = search_for_stateid(stateid);
>> +	if (!stp)
>> +		return nfserr_bad_stateid;
>> +	if (stateid->si_generation != 0) {
>> +		if (stateid->si_generation < stp->st_stateid.si_generation)
>> +			return nfserr_old_stateid;
>> +		if (stateid->si_generation > stp->st_stateid.si_generation)
>> +			return nfserr_bad_stateid;
>> +	}
>> +
>> +	if (stateid_has_locks(stp))
>> +		return nfserr_locks_held;
>> +	if (stp)
> 
> Already checked this above.

Good catch, I'll remove the extra check.

> 
>> +		release_open_stateid(stp);
> 
> OK, but it might not be a lock stateid.  (I assume free_stateid can be
> called on *any* kind of stateid?)

I thought release_open_stateid() freed all stateids, not just the lock stateid...

> 
> --b.
> 
>> +	return nfs_ok;
>> +}
>> +
>>  static inline int
>>  setlkflg (int type)
>>  {
>> @@ -3619,6 +3653,28 @@ find_stateid(stateid_t *stid, int flags)
>>  	return NULL;
>>  }
>>  
>> +static struct nfs4_stateid *
>> +search_for_stateid(stateid_t *stid)
>> +{
>> +	struct nfs4_stateid *local;
>> +	u32 st_id = stid->si_stateownerid;
>> +	u32 f_id  = stid->si_fileid;
>> +	unsigned int hashval = stateid_hashval(st_id, f_id);
>> +
>> +	list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) {
>> +		if ((local->st_stateid.si_stateownerid == st_id) &&
>> +		    (local->st_stateid.si_fileid == f_id))
>> +			return local;
>> +	}
>> +
>> +	list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) {
>> +		if ((local->st_stateid.si_stateownerid == st_id) &&
>> +		    (local->st_stateid.si_fileid == f_id))
>> +			return local;
>> +	}
>> +	return NULL;
>> +}
>> +
>>  static struct nfs4_delegation *
>>  find_delegation_stateid(struct inode *ino, stateid_t *stid)
>>  {
>> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
>> index 195a91d..5da6874 100644
>> --- a/fs/nfsd/nfs4xdr.c
>> +++ b/fs/nfsd/nfs4xdr.c
>> @@ -1246,6 +1246,19 @@ nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
>>  }
>>  
>>  static __be32
>> +nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
>> +			  struct nfsd4_free_stateid *free_stateid)
>> +{
>> +	DECODE_HEAD;
>> +
>> +	READ_BUF(sizeof(stateid_t));
>> +	READ32(free_stateid->fr_stateid.si_generation);
>> +	COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
>> +
>> +	DECODE_TAIL;
>> +}
>> +
>> +static __be32
>>  nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
>>  		      struct nfsd4_sequence *seq)
>>  {
>> @@ -1370,7 +1383,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
>>  	[OP_EXCHANGE_ID]	= (nfsd4_dec)nfsd4_decode_exchange_id,
>>  	[OP_CREATE_SESSION]	= (nfsd4_dec)nfsd4_decode_create_session,
>>  	[OP_DESTROY_SESSION]	= (nfsd4_dec)nfsd4_decode_destroy_session,
>> -	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_notsupp,
>> +	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_free_stateid,
>>  	[OP_GET_DIR_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
>>  	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
>>  	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
>> @@ -3115,6 +3128,21 @@ nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
>>  	return nfserr;
>>  }
>>  
>> +static __be32
>> +nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
>> +			  struct nfsd4_free_stateid *free_stateid)
>> +{
>> +	__be32 *p;
>> +
>> +	if (nfserr)
>> +		return nfserr;
>> +
>> +	RESERVE_SPACE(4);
>> +	WRITE32(nfserr);
>> +	ADJUST_ARGS();
>> +	return nfserr;
>> +}
>> +
>>  __be32
>>  nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
>>  		      struct nfsd4_sequence *seq)
>> @@ -3196,7 +3224,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
>>  	[OP_EXCHANGE_ID]	= (nfsd4_enc)nfsd4_encode_exchange_id,
>>  	[OP_CREATE_SESSION]	= (nfsd4_enc)nfsd4_encode_create_session,
>>  	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_destroy_session,
>> -	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_noop,
>> +	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_free_stateid,
>>  	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
>>  	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
>>  	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
>> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
>> index 366401e..ed1784d 100644
>> --- a/fs/nfsd/xdr4.h
>> +++ b/fs/nfsd/xdr4.h
>> @@ -342,6 +342,11 @@ struct nfsd4_setclientid_confirm {
>>  	nfs4_verifier	sc_confirm;
>>  };
>>  
>> +struct nfsd4_free_stateid {
>> +	stateid_t	fr_stateid;         /* request */
>> +	__be32		fr_status;          /* response */
>> +};
>> +
>>  /* also used for NVERIFY */
>>  struct nfsd4_verify {
>>  	u32		ve_bmval[3];        /* request */
>> @@ -432,6 +437,7 @@ struct nfsd4_op {
>>  		struct nfsd4_destroy_session	destroy_session;
>>  		struct nfsd4_sequence		sequence;
>>  		struct nfsd4_reclaim_complete	reclaim_complete;
>> +		struct nfsd4_free_stateid	free_stateid;
>>  	} u;
>>  	struct nfs4_replay *			replay;
>>  };
>> @@ -564,6 +570,8 @@ extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
>>  		struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
>>  extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
>>  			  struct nfsd4_compound_state *, clientid_t *clid);
>> +extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
>> +		struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid);
>>  #endif
>>  
>>  /*
>> -- 
>> 1.7.5.1
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


  reply	other threads:[~2011-05-11 15:39 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-06 18:57 [PATCH 0/2] NFSD: add FREE_STATEID and TEST_STATEID operations bjschuma
2011-05-06 18:57 ` [PATCH 1/2] NFSD: added FREE_STATEID operation bjschuma
2011-05-10  0:36   ` J. Bruce Fields
2011-05-11 14:41     ` Bryan Schumaker [this message]
2011-05-13 21:36       ` J. Bruce Fields
2011-05-06 18:57 ` [PATCH 2/2] NFSD: Added TEST_STATEID opreation bjschuma
2011-05-10  0:49   ` J. Bruce Fields
2011-05-11 16:20     ` Bryan Schumaker
2011-05-13 21:39       ` J. Bruce Fields
2011-05-20 20:12 [PATCH v2 0/2] NFSD: add FREE_STATEID and TEST_STATEID operations bjschuma
2011-05-20 20:12 ` [PATCH 1/2] NFSD: added FREE_STATEID operation bjschuma
2011-05-20 20:16   ` Bryan Schumaker
2011-05-25 15:05     ` J. Bruce Fields
2011-05-31 14:52       ` Bryan Schumaker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DCA9FFD.5070707@netapp.com \
    --to=bjschuma@netapp.com \
    --cc=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.