@@ -16,6 +16,7 @@
#include "filecache.h"
#include "cache.h"
#include "xdr3.h"
+#include "xdr4.h"
#define NFSDDBG_FACILITY NFSDDBG_FH
@@ -267,3 +268,72 @@ const struct svc_version nfsd_localio_version3 = {
.vs_xdrsize = NFS3_SVC_XDRSIZE,
};
#endif /* CONFIG_NFSD_V3_LOCALIO */
+
+#if defined(CONFIG_NFSD_V4_LOCALIO)
+static bool nfs4svc_encode_getuuidres(struct svc_rqst *rqstp,
+ struct xdr_stream *xdr)
+{
+ struct nfsd_getuuidres *resp = rqstp->rq_resp;
+ __be32 *p;
+
+ p = xdr_reserve_space(xdr, 8);
+ if (!p)
+ return 0;
+ *p++ = cpu_to_be32(LOCALIOPROC_GETUUID);
+ *p++ = resp->status;
+
+ if (resp->status == nfs_ok) {
+ u8 uuid[UUID_SIZE];
+
+ export_uuid(uuid, &resp->uuid);
+ p = xdr_reserve_space(xdr, 4 + UUID_SIZE);
+ if (!p)
+ return 0;
+ xdr_encode_opaque(p, uuid, UUID_SIZE);
+ dprintk("%s: nfs_ok uuid=%pU uuid_len=%lu\n",
+ __func__, uuid, sizeof(uuid));
+ }
+
+ return 1;
+}
+
+#define ST 1 /* status */
+#define NFS4_filename_sz (1+(NFS4_MAXNAMLEN>>2))
+
+static const struct svc_procedure nfsd_localio_procedures4[2] = {
+ [LOCALIOPROC_NULL] = {
+ .pc_func = nfsd_proc_null,
+ .pc_decode = nfssvc_decode_voidarg,
+ .pc_encode = nfssvc_encode_voidres,
+ .pc_argsize = sizeof(struct nfsd_voidargs),
+ .pc_ressize = sizeof(struct nfsd_voidres),
+ .pc_cachetype = RC_NOCACHE,
+ .pc_xdrressize = ST,
+ .pc_name = "NULL",
+ },
+ [LOCALIOPROC_GETUUID] = {
+ .pc_func = nfsd_proc_getuuid,
+ .pc_decode = nfssvc_decode_voidarg,
+ .pc_encode = nfs4svc_encode_getuuidres,
+ .pc_argsize = sizeof(struct nfsd_voidargs),
+ .pc_ressize = sizeof(struct nfsd_getuuidres),
+ .pc_cachetype = RC_NOCACHE,
+ .pc_xdrressize = ST+NFS4_filename_sz,
+ .pc_name = "GETUUID",
+ },
+};
+
+static DEFINE_PER_CPU_ALIGNED(unsigned long,
+ nfsd_localio_count4[ARRAY_SIZE(nfsd_localio_procedures4)]);
+const struct svc_version nfsd_localio_version4 = {
+ .vs_vers = 4,
+ .vs_nproc = 2,
+ .vs_proc = nfsd_localio_procedures4,
+ .vs_dispatch = nfsd_dispatch,
+ .vs_count = nfsd_localio_count4,
+ .vs_xdrsize = NFS4_SVC_XDRSIZE,
+ .vs_rpcb_optnl = true,
+ .vs_need_cong_ctrl = true,
+
+};
+#endif /* CONFIG_NFSD_V4_LOCALIO */
@@ -147,6 +147,11 @@ extern const struct svc_version nfsd_localio_version3;
#else
#define nfsd_localio_version3 NULL
#endif
+#if defined(CONFIG_NFSD_V4_LOCALIO)
+extern const struct svc_version nfsd_localio_version4;
+#else
+#define nfsd_localio_version4 NULL
+#endif
struct nfsd_net;
@@ -38,7 +38,7 @@
atomic_t nfsd_th_cnt = ATOMIC_INIT(0);
extern struct svc_program nfsd_program;
static int nfsd(void *vrqstp);
-#if defined(CONFIG_NFSD_V3_LOCALIO)
+#if defined(CONFIG_NFSD_V3_LOCALIO) || defined(CONFIG_NFSD_V4_LOCALIO)
static int nfsd_localio_rpcbind_set(struct net *,
const struct svc_program *,
u32, int,
@@ -47,7 +47,7 @@ static int nfsd_localio_rpcbind_set(struct net *,
static __be32 nfsd_localio_init_request(struct svc_rqst *,
const struct svc_program *,
struct svc_process_info *);
-#endif /* CONFIG_NFSD_V3_LOCALIO */
+#endif /* CONFIG_NFSD_V3_LOCALIO || CONFIG_NFSD_V4_LOCALIO */
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
static int nfsd_acl_rpcbind_set(struct net *,
const struct svc_program *,
@@ -91,9 +91,14 @@ DEFINE_SPINLOCK(nfsd_drc_lock);
unsigned long nfsd_drc_max_mem;
unsigned long nfsd_drc_mem_used;
-#if defined(CONFIG_NFSD_V3_LOCALIO)
+#if defined(CONFIG_NFSD_V3_LOCALIO) || defined(CONFIG_NFSD_V4_LOCALIO)
static const struct svc_version *nfsd_localio_version[] = {
+#if defined(CONFIG_NFSD_V3_LOCALIO)
[3] = &nfsd_localio_version3,
+#endif
+#if defined(CONFIG_NFSD_V4_LOCALIO)
+ [4] = &nfsd_localio_version4,
+#endif
};
#define NFSD_LOCALIO_MINVERS 3
@@ -109,7 +114,7 @@ static struct svc_program nfsd_localio_program = {
.pg_init_request = nfsd_localio_init_request,
.pg_rpcbind_set = nfsd_localio_rpcbind_set,
};
-#endif /* CONFIG_NFSD_V3_LOCALIO */
+#endif /* CONFIG_NFSD_V3_LOCALIO || CONFIG_NFSD_V4_LOCALIO */
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
static const struct svc_version *nfsd_acl_version[] = {
@@ -125,9 +130,9 @@ static const struct svc_version *nfsd_acl_version[] = {
#define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version)
static struct svc_program nfsd_acl_program = {
-#if defined(CONFIG_NFSD_V3_LOCALIO)
+#if defined(CONFIG_NFSD_V3_LOCALIO) || defined(CONFIG_NFSD_V4_LOCALIO)
.pg_next = &nfsd_localio_program,
-#endif /* CONFIG_NFSD_V3_LOCALIO */
+#endif /* CONFIG_NFSD_V3_LOCALIO || CONFIG_NFSD_V4_LOCALIO */
.pg_prog = NFS_ACL_PROGRAM,
.pg_nvers = NFSD_ACL_NRVERS,
.pg_vers = nfsd_acl_version,
@@ -157,9 +162,9 @@ struct svc_program nfsd_program = {
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
.pg_next = &nfsd_acl_program,
#else
-#if defined(CONFIG_NFSD_V3_LOCALIO)
+#if defined(CONFIG_NFSD_V3_LOCALIO) || defined(CONFIG_NFSD_V4_LOCALIO)
.pg_next = &nfsd_localio_program,
-#endif /* CONFIG_NFSD_V3_LOCALIO */
+#endif /* CONFIG_NFSD_V3_LOCALIO || CONFIG_NFSD_V4_LOCALIO */
#endif
.pg_prog = NFS_PROGRAM, /* program number */
.pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
@@ -855,7 +860,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred, const char *scop
return error;
}
-#if defined(CONFIG_NFSD_V3_LOCALIO)
+#if defined(CONFIG_NFSD_V3_LOCALIO) || defined(CONFIG_NFSD_V4_LOCALIO)
static bool
nfsd_support_localio_version(int vers)
{
@@ -889,7 +894,7 @@ nfsd_localio_init_request(struct svc_rqst *rqstp,
return rpc_prog_unavail;
}
-#endif /* CONFIG_NFSD_V3_LOCALIO */
+#endif /* CONFIG_NFSD_V3_LOCALIO || CONFIG_NFSD_V4_LOCALIO */
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
static bool
Signed-off-by: Mike Snitzer <snitzer@kernel.org> --- fs/nfsd/localio.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/nfsd.h | 5 ++++ fs/nfsd/nfssvc.c | 25 ++++++++++------- 3 files changed, 90 insertions(+), 10 deletions(-)