[PATCH] nfsd: allow setting SEQ4_STATUS_RECALLABLE_STATE_REVOKED

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

 



This patch sets the SEQ4_STATUS_RECALLABLE_STATE_REVOKED bit for a single
SEQUENCE response after writing "revoke" to the client's ctl file in procfs.
It has been generally useful to test various NFS client implementations, so
I'm sending it along for others to find and use.

Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
---
 fs/nfsd/nfs4state.c | 19 +++++++++++++++----
 fs/nfsd/state.h     |  1 +
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index daf305daa751..f91e2857df65 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2830,18 +2830,28 @@ static ssize_t client_ctl_write(struct file *file, const char __user *buf,
 {
 	char *data;
 	struct nfs4_client *clp;
+	ssize_t rc = size;
 
 	data = simple_transaction_get(file, buf, size);
 	if (IS_ERR(data))
 		return PTR_ERR(data);
-	if (size != 7 || 0 != memcmp(data, "expire\n", 7))
+
+	if (size != 7)
 		return -EINVAL;
+
 	clp = get_nfsdfs_clp(file_inode(file));
 	if (!clp)
 		return -ENXIO;
-	force_expire_client(clp);
+
+	if (!memcmp(data, "revoke\n", 7))
+		set_bit(NFSD4_CLIENT_CL_REVOKED, &clp->cl_flags);
+	else if (!memcmp(data, "expire\n", 7))
+		force_expire_client(clp);
+	else
+		rc = -EINVAL;
+
 	drop_client(clp);
-	return 7;
+	return rc;
 }
 
 static const struct file_operations client_ctl_fops = {
@@ -4042,7 +4052,8 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	default:
 		seq->status_flags = 0;
 	}
-	if (!list_empty(&clp->cl_revoked))
+	if (!list_empty(&clp->cl_revoked) ||
+			test_and_clear_bit(NFSD4_CLIENT_CL_REVOKED, &clp->cl_flags))
 		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
 out_no_session:
 	if (conn)
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index d49d3060ed4f..a9154b7da022 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -369,6 +369,7 @@ struct nfs4_client {
 #define NFSD4_CLIENT_CB_FLAG_MASK	(1 << NFSD4_CLIENT_CB_UPDATE | \
 					 1 << NFSD4_CLIENT_CB_KILL)
 #define NFSD4_CLIENT_CB_RECALL_ANY	(6)
+#define NFSD4_CLIENT_CL_REVOKED (7)
 	unsigned long		cl_flags;
 	const struct cred	*cl_cb_cred;
 	struct rpc_clnt		*cl_cb_client;
-- 
2.40.1




[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