diff mbox series

[11/13] nfsd: allow open state ids to be revoked and then freed

Message ID 20240129033637.2133-12-neilb@suse.de (mailing list archive)
State New
Headers show
Series nfsd: support admin-revocation of v4 state | expand

Commit Message

NeilBrown Jan. 29, 2024, 3:29 a.m. UTC
Revoking state through 'unlock_filesystem' now revokes any open states
found.  When the stateids are then freed by the client, the revoked
stateids will be cleaned up correctly.

Possibly the related lock states should be revoked too, but a
subsequent patch will do that for all lock state on the superblock.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

Comments

Jeffrey Layton Jan. 29, 2024, 12:31 p.m. UTC | #1
On Mon, 2024-01-29 at 14:29 +1100, NeilBrown wrote:
> Revoking state through 'unlock_filesystem' now revokes any open states
> found.  When the stateids are then freed by the client, the revoked
> stateids will be cleaned up correctly.
> 
> Possibly the related lock states should be revoked too, but a
> subsequent patch will do that for all lock state on the superblock.
> 
> Signed-off-by: NeilBrown <neilb@suse.de>
> ---
>  fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index a5c17dab8bdb..5dc8f60e18dc 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
>  	unsigned int idhashval;
>  	unsigned int sc_types;
>  
> -	sc_types = SC_TYPE_LOCK;
> +	sc_types = SC_TYPE_OPEN | SC_TYPE_LOCK;
>  
>  	spin_lock(&nn->client_lock);
>  	for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
> @@ -1732,6 +1732,22 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
>  
>  				spin_unlock(&nn->client_lock);
>  				switch (stid->sc_type) {
> +				case SC_TYPE_OPEN:
> +					stp = openlockstateid(stid);
> +					mutex_lock_nested(&stp->st_mutex,
> +							  OPEN_STATEID_MUTEX);
> +
> +					spin_lock(&clp->cl_lock);
> +					if (stid->sc_status == 0) {
> +						stid->sc_status |=
> +							SC_STATUS_ADMIN_REVOKED;
> +						atomic_inc(&clp->cl_admin_revoked);
> +						spin_unlock(&clp->cl_lock);
> +						release_all_access(stp);
> +					} else
> +						spin_unlock(&clp->cl_lock);
> +					mutex_unlock(&stp->st_mutex);
> +					break;
>  				case SC_TYPE_LOCK:
>  					stp = openlockstateid(stid);
>  					mutex_lock_nested(&stp->st_mutex,
> @@ -4662,6 +4678,13 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
>  	bool unhashed;
>  
>  	switch (s->sc_type) {
> +	case SC_TYPE_OPEN:
> +		stp = openlockstateid(s);
> +		if (unhash_open_stateid(stp, &reaplist))
> +			put_ol_stateid_locked(stp, &reaplist);
> +		spin_unlock(&cl->cl_lock);
> +		free_ol_stateid_reaplist(&reaplist);
> +		break;
>  	case SC_TYPE_LOCK:
>  		stp = openlockstateid(s);
>  		unhashed = unhash_lock_stateid(stp);

Reviewed-by: Jeff Layton <jlayton@kernel.org>
diff mbox series

Patch

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a5c17dab8bdb..5dc8f60e18dc 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1717,7 +1717,7 @@  void nfsd4_revoke_states(struct net *net, struct super_block *sb)
 	unsigned int idhashval;
 	unsigned int sc_types;
 
-	sc_types = SC_TYPE_LOCK;
+	sc_types = SC_TYPE_OPEN | SC_TYPE_LOCK;
 
 	spin_lock(&nn->client_lock);
 	for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
@@ -1732,6 +1732,22 @@  void nfsd4_revoke_states(struct net *net, struct super_block *sb)
 
 				spin_unlock(&nn->client_lock);
 				switch (stid->sc_type) {
+				case SC_TYPE_OPEN:
+					stp = openlockstateid(stid);
+					mutex_lock_nested(&stp->st_mutex,
+							  OPEN_STATEID_MUTEX);
+
+					spin_lock(&clp->cl_lock);
+					if (stid->sc_status == 0) {
+						stid->sc_status |=
+							SC_STATUS_ADMIN_REVOKED;
+						atomic_inc(&clp->cl_admin_revoked);
+						spin_unlock(&clp->cl_lock);
+						release_all_access(stp);
+					} else
+						spin_unlock(&clp->cl_lock);
+					mutex_unlock(&stp->st_mutex);
+					break;
 				case SC_TYPE_LOCK:
 					stp = openlockstateid(stid);
 					mutex_lock_nested(&stp->st_mutex,
@@ -4662,6 +4678,13 @@  static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
 	bool unhashed;
 
 	switch (s->sc_type) {
+	case SC_TYPE_OPEN:
+		stp = openlockstateid(s);
+		if (unhash_open_stateid(stp, &reaplist))
+			put_ol_stateid_locked(stp, &reaplist);
+		spin_unlock(&cl->cl_lock);
+		free_ol_stateid_reaplist(&reaplist);
+		break;
 	case SC_TYPE_LOCK:
 		stp = openlockstateid(s);
 		unhashed = unhash_lock_stateid(stp);