2013-11-13 19:31:01

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 0/3] NFSD: Implement SEEK

These patches implement just the SEEK NFS v4.2 operation. WRITE_PLUS is
still under discussion with the IETF after my last series of patches, so I
am holding off on resubmitting until after spec discussion dies down.

Questions? Comments? Thoughts?
Anna

Anna Schumaker (3):
NFSD: Update error codes
NFSD: Create nfs v4.2 decode ops
NFSD: Implement SEEK

fs/nfsd/Kconfig | 12 +++++++++
fs/nfsd/nfs4proc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfs4xdr.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfsd.h | 2 +-
fs/nfsd/xdr4.h | 16 ++++++++++++
include/linux/nfs4.h | 23 ++++++++++++++---
6 files changed, 179 insertions(+), 4 deletions(-)

--
1.8.4.2



2013-11-13 20:01:31

by Weston Andros Adamson

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] NFSD: Implement SEEK


On Nov 13, 2013, at 2:30 PM, Anna Schumaker <[email protected]> wrote:

> This patch adds in the SEEK operation used by clients doing an llseek on
> a file to find either hole or data segments. I am making the assumption
> that allocated == true in the NFS4_CONTENT_DATA case and false for the
> NFS4_CONTENT_HOLE case.
>
> Signed-off-by: Anna Schumaker <[email protected]>
>
> ---
> Changed in V3:
> - SEEK is only compiled in when CONFIG_NFSD_V4_2_SEEK is enabled
>
> fs/nfsd/Kconfig | 12 +++++++++++
> fs/nfsd/nfs4proc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/nfsd/nfs4xdr.c | 48 +++++++++++++++++++++++++++++++++++++++++
> fs/nfsd/xdr4.h | 16 ++++++++++++++
> include/linux/nfs4.h | 6 ++++++
> 5 files changed, 142 insertions(+)
>
> diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
> index dc8f1ef..680e017 100644
> --- a/fs/nfsd/Kconfig
> +++ b/fs/nfsd/Kconfig
> @@ -81,6 +81,18 @@ config NFSD_V4
>
> If unsure, say N.
>
> +config NFSD_V4_2_SEEK
> + bool "Enable SEEK support for the NFS v4.2 server"
> + depends on NFSD_V4
> + help
> + Say Y here if you want to enable support for the NFS v4.2 operation
> + SEEK, which adds in SEEK_HOLE and SEEK_DATA support.
> +
> + WARNING: there is still a chance of backwards-incompatible protocol
> + changes. This feature is targeted at developers and testers only.
> +
> + If unsure, say N.
> +
> config NFSD_V4_SECURITY_LABEL
> bool "Provide Security Label support for NFSv4 server"
> depends on NFSD_V4 && SECURITY
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index 419572f..1283ca7 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -1028,6 +1028,59 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> return status;
> }
>
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> +static __be32
> +nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> + struct nfsd4_seek *seek)
> +{
> + struct file *file;
> + loff_t end_pos = 0;
> + __be32 status;
> +
> + nfs4_lock_state();
> + status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
> + &seek->seek_stateid,
> + RD_STATE | WR_STATE, &file);
> + if (status != nfs_ok) {
> + nfs4_unlock_state();
> + return status;
> + } else

this else isn?t needed.

-dros

> + get_file(file);
> + nfs4_unlock_state();
> +
> + switch (seek->seek_whence) {
> + case NFS4_CONTENT_APP_DATA_HOLE:
> + status = nfserr_union_notsupp;
> + break;
> + case NFS4_CONTENT_DATA:
> + seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_DATA);
> + end_pos = vfs_llseek(file, seek->seek_pos, SEEK_HOLE);
> + seek->seek_allocated = true;
> + break;
> + case NFS4_CONTENT_HOLE:
> + seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_HOLE);
> + end_pos = vfs_llseek(file, seek->seek_pos, SEEK_DATA);
> + seek->seek_allocated = false;
> + break;
> + default:
> + status = nfs_ok;
> + seek->seek_eof = true;
> + goto out;
> + }
> +
> + if (seek->seek_pos < 0) {
> + status = nfserrno(seek->seek_pos);
> + goto out;
> + }
> +
> + seek->seek_length = end_pos - seek->seek_pos;
> +
> +out:
> + fput(file);
> + return status;
> +}
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> +
> /* This routine never returns NFS_OK! If there are no other errors, it
> * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
> * attributes matched. VERIFY is implemented by mapping NFSERR_SAME
> @@ -1840,6 +1893,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
> .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
> .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
> },
> +
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> + [OP_SEEK] = {
> + .op_func = (nfsd4op_func)nfsd4_seek,
> + .op_name = "OP_SEEK",
> + },
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> };
>
> #ifdef NFSD_DEBUG
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 3af6c46..7041039 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -1507,6 +1507,24 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
> DECODE_TAIL;
> }
>
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> +static __be32
> +nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
> +{
> + DECODE_HEAD;
> +
> + status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
> + if (status)
> + return status;
> +
> + READ_BUF(12);
> + READ64(seek->seek_offset);
> + READ32(seek->seek_whence);
> +
> + DECODE_TAIL;
> +}
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> +
> static __be32
> nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
> {
> @@ -1589,7 +1607,11 @@ static nfsd4_dec nfsd4_dec_ops[] = {
> [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_notsupp,
> [OP_WRITE_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
> [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> + [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
> +#else
> [OP_SEEK] = (nfsd4_dec)nfsd4_decode_notsupp,
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
> };
>
> @@ -3514,6 +3536,28 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
> return nfserr;
> }
>
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> +static __be32
> +nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
> + struct nfsd4_seek *seek)
> +{
> + __be32 *p;
> +
> + if (nfserr)
> + return nfserr;
> +
> + RESERVE_SPACE(28);
> + WRITE32(seek->seek_eof);
> + WRITE32(seek->seek_whence);
> + WRITE64(seek->seek_pos);
> + WRITE64(seek->seek_length);
> + WRITE32(seek->seek_allocated);
> + ADJUST_ARGS();
> +
> + return nfserr;
> +}
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> +
> static __be32
> nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
> {
> @@ -3595,7 +3639,11 @@ static nfsd4_enc nfsd4_enc_ops[] = {
> [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_noop,
> [OP_WRITE_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
> [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
> +#ifdef CONFIG_NFSD_V4_2_SEEK
> + [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
> +#else
> [OP_SEEK] = (nfsd4_enc)nfsd4_encode_noop,
> +#endif /* CONFIG_NFSD_V4_2_SEEK */
> [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
> };
>
> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
> index b3ed644..c2f4e30 100644
> --- a/fs/nfsd/xdr4.h
> +++ b/fs/nfsd/xdr4.h
> @@ -430,6 +430,19 @@ struct nfsd4_reclaim_complete {
> u32 rca_one_fs;
> };
>
> +struct nfsd4_seek {
> + /* request */
> + stateid_t seek_stateid;
> + loff_t seek_offset;
> + u32 seek_whence;
> +
> + /* response */
> + u64 seek_pos;
> + u32 seek_eof;
> + u64 seek_length;
> + u32 seek_allocated;
> +};
> +
> struct nfsd4_op {
> int opnum;
> __be32 status;
> @@ -475,6 +488,9 @@ struct nfsd4_op {
> struct nfsd4_reclaim_complete reclaim_complete;
> struct nfsd4_test_stateid test_stateid;
> struct nfsd4_free_stateid free_stateid;
> +
> + /* NFSv4.2 */
> + struct nfsd4_seek seek;
> } u;
> struct nfs4_replay * replay;
> };
> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
> index e58e0eb..a35b0b6 100644
> --- a/include/linux/nfs4.h
> +++ b/include/linux/nfs4.h
> @@ -558,4 +558,10 @@ struct nfs4_deviceid {
> char data[NFS4_DEVICEID4_SIZE];
> };
>
> +enum data_content4 {
> + NFS4_CONTENT_DATA = 0,
> + NFS4_CONTENT_APP_DATA_HOLE = 1,
> + NFS4_CONTENT_HOLE = 2,
> +};
> +
> #endif
> --
> 1.8.4.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html


2013-11-13 19:31:01

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 1/3] NFSD: Update error codes

Recent NFS v4.2 drafts have removed NFS4ERR_METADATA_NOTSUPP and
reassigned the error code to NFS4ERR_UNION_NOTSUPP.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfsd/nfsd.h | 2 +-
include/linux/nfs4.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 30f34ab..4fe49e9 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -244,7 +244,7 @@ void nfsd_lockd_shutdown(void);
#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED)
#define nfserr_partner_notsupp cpu_to_be32(NFS4ERR_PARTNER_NOTSUPP)
#define nfserr_partner_no_auth cpu_to_be32(NFS4ERR_PARTNER_NO_AUTH)
-#define nfserr_metadata_notsupp cpu_to_be32(NFS4ERR_METADATA_NOTSUPP)
+#define nfserr_union_notsupp cpu_to_be32(NFS4ERR_UNION_NOTSUPP)
#define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED)
#define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS)
#define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index c163706..d9e30fb 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -235,7 +235,7 @@ enum nfsstat4 {
/* nfs42 */
NFS4ERR_PARTNER_NOTSUPP = 10088,
NFS4ERR_PARTNER_NO_AUTH = 10089,
- NFS4ERR_METADATA_NOTSUPP = 10090,
+ NFS4ERR_UNION_NOTSUPP = 10090,
NFS4ERR_OFFLOAD_DENIED = 10091,
NFS4ERR_WRONG_LFS = 10092,
NFS4ERR_BADLABEL = 10093,
--
1.8.4.2


2013-11-13 19:31:02

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 2/3] NFSD: Create nfs v4.2 decode ops

It's cleaner to introduce everything at once and have the server reply
with "not supported" than it would be to introduce extra operations when
implementing a specific one in the middle of the list.

Signed-off-by: Anna Schumaker <[email protected]>
---
fs/nfsd/nfs4xdr.c | 22 ++++++++++++++++++++++
include/linux/nfs4.h | 15 +++++++++++++--
2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 83db5a7..3af6c46 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1580,6 +1580,17 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid,
[OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
+
+ /* new operations for NFSv4.2 */
+ [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OFFLOAD_ABORT] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OFFLOAD_REVOKE] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_WRITE_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SEEK] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
};

static inline bool
@@ -3575,6 +3586,17 @@ static nfsd4_enc nfsd4_enc_ops[] = {
[OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
[OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop,
[OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop,
+
+ /* NFSv4.2 operations */
+ [OP_COPY] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_OFFLOAD_ABORT] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_OFFLOAD_REVOKE] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_WRITE_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_SEEK] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
};

/*
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index d9e30fb..e58e0eb 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -110,6 +110,17 @@ enum nfs_opnum4 {
OP_DESTROY_CLIENTID = 57,
OP_RECLAIM_COMPLETE = 58,

+ /* nfs42 */
+ OP_COPY = 59,
+ OP_OFFLOAD_ABORT = 60,
+ OP_COPY_NOTIFY = 61,
+ OP_OFFLOAD_REVOKE = 62,
+ OP_OFFLOAD_STATUS = 63,
+ OP_WRITE_PLUS = 64,
+ OP_READ_PLUS = 65,
+ OP_SEEK = 66,
+ OP_IO_ADVISE = 67,
+
OP_ILLEGAL = 10044,
};

@@ -117,10 +128,10 @@ enum nfs_opnum4 {
Needs to be updated if more operations are defined in future.*/

#define FIRST_NFS4_OP OP_ACCESS
-#define LAST_NFS4_OP OP_RECLAIM_COMPLETE
+#define LAST_NFS4_OP OP_IO_ADVISE
#define LAST_NFS40_OP OP_RELEASE_LOCKOWNER
#define LAST_NFS41_OP OP_RECLAIM_COMPLETE
-#define LAST_NFS42_OP OP_RECLAIM_COMPLETE
+#define LAST_NFS42_OP OP_IO_ADVISE

enum nfsstat4 {
NFS4_OK = 0,
--
1.8.4.2


2013-11-14 16:27:09

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v4 3/3] NFSD: Implement SEEK

This patch adds in the SEEK operation used by clients doing an llseek on
a file to find either hole or data segments. I am making the assumption
that allocated == true in the NFS4_CONTENT_DATA case and false for the
NFS4_CONTENT_HOLE case.

Signed-off-by: Anna Schumaker <[email protected]>

---
The first two patches in the series haven't changed, so I'm only
resubmitting this one :)

Changed in V4:
- Remove unnecessary "else" (thanks Dros!)
- Correct the switch statement now that I understand the spec better

fs/nfsd/Kconfig | 12 +++++++++++
fs/nfsd/nfs4proc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfs4xdr.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/xdr4.h | 16 +++++++++++++++
include/linux/nfs4.h | 6 ++++++
5 files changed, 138 insertions(+)

diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index dc8f1ef..680e017 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -81,6 +81,18 @@ config NFSD_V4

If unsure, say N.

+config NFSD_V4_2_SEEK
+ bool "Enable SEEK support for the NFS v4.2 server"
+ depends on NFSD_V4
+ help
+ Say Y here if you want to enable support for the NFS v4.2 operation
+ SEEK, which adds in SEEK_HOLE and SEEK_DATA support.
+
+ WARNING: there is still a chance of backwards-incompatible protocol
+ changes. This feature is targeted at developers and testers only.
+
+ If unsure, say N.
+
config NFSD_V4_SECURITY_LABEL
bool "Provide Security Label support for NFSv4 server"
depends on NFSD_V4 && SECURITY
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 419572f..89bde5a 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1028,6 +1028,55 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_seek *seek)
+{
+ struct file *file;
+ loff_t end_pos = 0;
+ __be32 status;
+
+ nfs4_lock_state();
+ status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
+ &seek->seek_stateid,
+ RD_STATE | WR_STATE, &file);
+ if (status != nfs_ok) {
+ nfs4_unlock_state();
+ return status;
+ }
+
+ get_file(file);
+ nfs4_unlock_state();
+
+ switch (seek->seek_whence) {
+ case NFS4_CONTENT_DATA:
+ seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_DATA);
+ end_pos = vfs_llseek(file, seek->seek_pos, SEEK_HOLE);
+ seek->seek_allocated = true;
+ break;
+ case NFS4_CONTENT_HOLE:
+ seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_HOLE);
+ end_pos = vfs_llseek(file, seek->seek_pos, SEEK_DATA);
+ seek->seek_allocated = false;
+ break;
+ default:
+ status = nfserr_union_notsupp;
+ goto out;
+ }
+
+ status = nfs_ok;
+ if (seek->seek_pos < 0)
+ status = nfserrno(seek->seek_pos);
+ else
+ seek->seek_length = end_pos - seek->seek_pos;
+
+out:
+ fput(file);
+ return status;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
/* This routine never returns NFS_OK! If there are no other errors, it
* will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
* attributes matched. VERIFY is implemented by mapping NFSERR_SAME
@@ -1840,6 +1889,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
},
+
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = {
+ .op_func = (nfsd4op_func)nfsd4_seek,
+ .op_name = "OP_SEEK",
+ },
+#endif /* CONFIG_NFSD_V4_2_SEEK */
};

#ifdef NFSD_DEBUG
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3af6c46..7041039 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1507,6 +1507,24 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
DECODE_TAIL;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
+{
+ DECODE_HEAD;
+
+ status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
+ if (status)
+ return status;
+
+ READ_BUF(12);
+ READ64(seek->seek_offset);
+ READ32(seek->seek_whence);
+
+ DECODE_TAIL;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
static __be32
nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
{
@@ -1589,7 +1607,11 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_WRITE_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
+#else
[OP_SEEK] = (nfsd4_dec)nfsd4_decode_notsupp,
+#endif /* CONFIG_NFSD_V4_2_SEEK */
[OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
};

@@ -3514,6 +3536,28 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
return nfserr;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
+ struct nfsd4_seek *seek)
+{
+ __be32 *p;
+
+ if (nfserr)
+ return nfserr;
+
+ RESERVE_SPACE(28);
+ WRITE32(seek->seek_eof);
+ WRITE32(seek->seek_whence);
+ WRITE64(seek->seek_pos);
+ WRITE64(seek->seek_length);
+ WRITE32(seek->seek_allocated);
+ ADJUST_ARGS();
+
+ return nfserr;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
static __be32
nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
{
@@ -3595,7 +3639,11 @@ static nfsd4_enc nfsd4_enc_ops[] = {
[OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_noop,
[OP_WRITE_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
[OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
+#else
[OP_SEEK] = (nfsd4_enc)nfsd4_encode_noop,
+#endif /* CONFIG_NFSD_V4_2_SEEK */
[OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
};

diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index b3ed644..c2f4e30 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -430,6 +430,19 @@ struct nfsd4_reclaim_complete {
u32 rca_one_fs;
};

+struct nfsd4_seek {
+ /* request */
+ stateid_t seek_stateid;
+ loff_t seek_offset;
+ u32 seek_whence;
+
+ /* response */
+ u64 seek_pos;
+ u32 seek_eof;
+ u64 seek_length;
+ u32 seek_allocated;
+};
+
struct nfsd4_op {
int opnum;
__be32 status;
@@ -475,6 +488,9 @@ struct nfsd4_op {
struct nfsd4_reclaim_complete reclaim_complete;
struct nfsd4_test_stateid test_stateid;
struct nfsd4_free_stateid free_stateid;
+
+ /* NFSv4.2 */
+ struct nfsd4_seek seek;
} u;
struct nfs4_replay * replay;
};
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index e58e0eb..a35b0b6 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -558,4 +558,10 @@ struct nfs4_deviceid {
char data[NFS4_DEVICEID4_SIZE];
};

+enum data_content4 {
+ NFS4_CONTENT_DATA = 0,
+ NFS4_CONTENT_APP_DATA_HOLE = 1,
+ NFS4_CONTENT_HOLE = 2,
+};
+
#endif
--
1.8.4.2


2013-11-14 19:17:56

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] NFSD: Implement SEEK

On 11/14/2013 11:47 AM, Cedric Blancher wrote:
> On 13 November 2013 20:30, Anna Schumaker <[email protected]> wrote:
>> These patches implement just the SEEK NFS v4.2 operation. WRITE_PLUS is
>> still under discussion with the IETF after my last series of patches, so I
>> am holding off on resubmitting until after spec discussion dies down.
>>
>> Questions? Comments? Thoughts?
>> Anna
>
> 1. Doesn't SEEK_HOLE/SEEK_DATA already work in NFSv4? I always had the
> impression this worked there...

If we did, it was vfs-level seeking. HOLE and DATA support are new to NFS with v4.2.

>
> 2. Does http://svn.nrubsig.org/svn/people/gisburn/code/sparsefiles/lsholes.c
> work with your changes (the name is unfortunate, but its useful to
> list the holes in a file and even has a short test)?

lsholes.c passes on NFS with these changes, although I think it needs a "-h" option to tell me how to use it without looking at the code :)

>
> 3. If you implement SEEK_HOLE/SEEK_DATA support you have to alter
> fpathconf() support and implement the _PC_MIN_HOLE_SIZE properly.

I don't think the NFS server exports a "minimum hole size" attribute, so I don't know how to find this without spec changes.

Anna

>
> Ced
>


2013-11-13 19:32:15

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v3 3/3] NFSD: Implement SEEK

This patch adds in the SEEK operation used by clients doing an llseek on
a file to find either hole or data segments. I am making the assumption
that allocated == true in the NFS4_CONTENT_DATA case and false for the
NFS4_CONTENT_HOLE case.

Signed-off-by: Anna Schumaker <[email protected]>

---
Changed in V3:
- SEEK is only compiled in when CONFIG_NFSD_V4_2_SEEK is enabled

fs/nfsd/Kconfig | 12 +++++++++++
fs/nfsd/nfs4proc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfs4xdr.c | 48 +++++++++++++++++++++++++++++++++++++++++
fs/nfsd/xdr4.h | 16 ++++++++++++++
include/linux/nfs4.h | 6 ++++++
5 files changed, 142 insertions(+)

diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index dc8f1ef..680e017 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -81,6 +81,18 @@ config NFSD_V4

If unsure, say N.

+config NFSD_V4_2_SEEK
+ bool "Enable SEEK support for the NFS v4.2 server"
+ depends on NFSD_V4
+ help
+ Say Y here if you want to enable support for the NFS v4.2 operation
+ SEEK, which adds in SEEK_HOLE and SEEK_DATA support.
+
+ WARNING: there is still a chance of backwards-incompatible protocol
+ changes. This feature is targeted at developers and testers only.
+
+ If unsure, say N.
+
config NFSD_V4_SECURITY_LABEL
bool "Provide Security Label support for NFSv4 server"
depends on NFSD_V4 && SECURITY
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 419572f..1283ca7 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1028,6 +1028,59 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ struct nfsd4_seek *seek)
+{
+ struct file *file;
+ loff_t end_pos = 0;
+ __be32 status;
+
+ nfs4_lock_state();
+ status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
+ &seek->seek_stateid,
+ RD_STATE | WR_STATE, &file);
+ if (status != nfs_ok) {
+ nfs4_unlock_state();
+ return status;
+ } else
+ get_file(file);
+ nfs4_unlock_state();
+
+ switch (seek->seek_whence) {
+ case NFS4_CONTENT_APP_DATA_HOLE:
+ status = nfserr_union_notsupp;
+ break;
+ case NFS4_CONTENT_DATA:
+ seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_DATA);
+ end_pos = vfs_llseek(file, seek->seek_pos, SEEK_HOLE);
+ seek->seek_allocated = true;
+ break;
+ case NFS4_CONTENT_HOLE:
+ seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_HOLE);
+ end_pos = vfs_llseek(file, seek->seek_pos, SEEK_DATA);
+ seek->seek_allocated = false;
+ break;
+ default:
+ status = nfs_ok;
+ seek->seek_eof = true;
+ goto out;
+ }
+
+ if (seek->seek_pos < 0) {
+ status = nfserrno(seek->seek_pos);
+ goto out;
+ }
+
+ seek->seek_length = end_pos - seek->seek_pos;
+
+out:
+ fput(file);
+ return status;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
/* This routine never returns NFS_OK! If there are no other errors, it
* will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
* attributes matched. VERIFY is implemented by mapping NFSERR_SAME
@@ -1840,6 +1893,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
.op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
},
+
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = {
+ .op_func = (nfsd4op_func)nfsd4_seek,
+ .op_name = "OP_SEEK",
+ },
+#endif /* CONFIG_NFSD_V4_2_SEEK */
};

#ifdef NFSD_DEBUG
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3af6c46..7041039 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1507,6 +1507,24 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
DECODE_TAIL;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
+{
+ DECODE_HEAD;
+
+ status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
+ if (status)
+ return status;
+
+ READ_BUF(12);
+ READ64(seek->seek_offset);
+ READ32(seek->seek_whence);
+
+ DECODE_TAIL;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
static __be32
nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
{
@@ -1589,7 +1607,11 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_WRITE_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
+#else
[OP_SEEK] = (nfsd4_dec)nfsd4_decode_notsupp,
+#endif /* CONFIG_NFSD_V4_2_SEEK */
[OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
};

@@ -3514,6 +3536,28 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
return nfserr;
}

+#ifdef CONFIG_NFSD_V4_2_SEEK
+static __be32
+nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
+ struct nfsd4_seek *seek)
+{
+ __be32 *p;
+
+ if (nfserr)
+ return nfserr;
+
+ RESERVE_SPACE(28);
+ WRITE32(seek->seek_eof);
+ WRITE32(seek->seek_whence);
+ WRITE64(seek->seek_pos);
+ WRITE64(seek->seek_length);
+ WRITE32(seek->seek_allocated);
+ ADJUST_ARGS();
+
+ return nfserr;
+}
+#endif /* CONFIG_NFSD_V4_2_SEEK */
+
static __be32
nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
{
@@ -3595,7 +3639,11 @@ static nfsd4_enc nfsd4_enc_ops[] = {
[OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_noop,
[OP_WRITE_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
[OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
+#ifdef CONFIG_NFSD_V4_2_SEEK
+ [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
+#else
[OP_SEEK] = (nfsd4_enc)nfsd4_encode_noop,
+#endif /* CONFIG_NFSD_V4_2_SEEK */
[OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
};

diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index b3ed644..c2f4e30 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -430,6 +430,19 @@ struct nfsd4_reclaim_complete {
u32 rca_one_fs;
};

+struct nfsd4_seek {
+ /* request */
+ stateid_t seek_stateid;
+ loff_t seek_offset;
+ u32 seek_whence;
+
+ /* response */
+ u64 seek_pos;
+ u32 seek_eof;
+ u64 seek_length;
+ u32 seek_allocated;
+};
+
struct nfsd4_op {
int opnum;
__be32 status;
@@ -475,6 +488,9 @@ struct nfsd4_op {
struct nfsd4_reclaim_complete reclaim_complete;
struct nfsd4_test_stateid test_stateid;
struct nfsd4_free_stateid free_stateid;
+
+ /* NFSv4.2 */
+ struct nfsd4_seek seek;
} u;
struct nfs4_replay * replay;
};
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index e58e0eb..a35b0b6 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -558,4 +558,10 @@ struct nfs4_deviceid {
char data[NFS4_DEVICEID4_SIZE];
};

+enum data_content4 {
+ NFS4_CONTENT_DATA = 0,
+ NFS4_CONTENT_APP_DATA_HOLE = 1,
+ NFS4_CONTENT_HOLE = 2,
+};
+
#endif
--
1.8.4.2


2013-11-14 16:47:07

by Cedric Blancher

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] NFSD: Implement SEEK

On 13 November 2013 20:30, Anna Schumaker <[email protected]> wrote:
> These patches implement just the SEEK NFS v4.2 operation. WRITE_PLUS is
> still under discussion with the IETF after my last series of patches, so I
> am holding off on resubmitting until after spec discussion dies down.
>
> Questions? Comments? Thoughts?
> Anna

1. Doesn't SEEK_HOLE/SEEK_DATA already work in NFSv4? I always had the
impression this worked there...

2. Does http://svn.nrubsig.org/svn/people/gisburn/code/sparsefiles/lsholes.c
work with your changes (the name is unfortunate, but its useful to
list the holes in a file and even has a short test)?

3. If you implement SEEK_HOLE/SEEK_DATA support you have to alter
fpathconf() support and implement the _PC_MIN_HOLE_SIZE properly.

Ced
--
Cedric Blancher <[email protected]>
Institute Pasteur

2013-11-13 20:02:46

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] NFSD: Implement SEEK

On 11/13/2013 03:01 PM, Weston Andros Adamson wrote:
>
> On Nov 13, 2013, at 2:30 PM, Anna Schumaker <[email protected]> wrote:
>
>> This patch adds in the SEEK operation used by clients doing an llseek on
>> a file to find either hole or data segments. I am making the assumption
>> that allocated == true in the NFS4_CONTENT_DATA case and false for the
>> NFS4_CONTENT_HOLE case.
>>
>> Signed-off-by: Anna Schumaker <[email protected]>
>>
>> ---
>> Changed in V3:
>> - SEEK is only compiled in when CONFIG_NFSD_V4_2_SEEK is enabled
>>
>> fs/nfsd/Kconfig | 12 +++++++++++
>> fs/nfsd/nfs4proc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> fs/nfsd/nfs4xdr.c | 48 +++++++++++++++++++++++++++++++++++++++++
>> fs/nfsd/xdr4.h | 16 ++++++++++++++
>> include/linux/nfs4.h | 6 ++++++
>> 5 files changed, 142 insertions(+)
>>
>> diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
>> index dc8f1ef..680e017 100644
>> --- a/fs/nfsd/Kconfig
>> +++ b/fs/nfsd/Kconfig
>> @@ -81,6 +81,18 @@ config NFSD_V4
>>
>> If unsure, say N.
>>
>> +config NFSD_V4_2_SEEK
>> + bool "Enable SEEK support for the NFS v4.2 server"
>> + depends on NFSD_V4
>> + help
>> + Say Y here if you want to enable support for the NFS v4.2 operation
>> + SEEK, which adds in SEEK_HOLE and SEEK_DATA support.
>> +
>> + WARNING: there is still a chance of backwards-incompatible protocol
>> + changes. This feature is targeted at developers and testers only.
>> +
>> + If unsure, say N.
>> +
>> config NFSD_V4_SECURITY_LABEL
>> bool "Provide Security Label support for NFSv4 server"
>> depends on NFSD_V4 && SECURITY
>> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
>> index 419572f..1283ca7 100644
>> --- a/fs/nfsd/nfs4proc.c
>> +++ b/fs/nfsd/nfs4proc.c
>> @@ -1028,6 +1028,59 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>> return status;
>> }
>>
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> +static __be32
>> +nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>> + struct nfsd4_seek *seek)
>> +{
>> + struct file *file;
>> + loff_t end_pos = 0;
>> + __be32 status;
>> +
>> + nfs4_lock_state();
>> + status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
>> + &seek->seek_stateid,
>> + RD_STATE | WR_STATE, &file);
>> + if (status != nfs_ok) {
>> + nfs4_unlock_state();
>> + return status;
>> + } else
>
> this else isn?t needed.

Good catch, thanks!

Anna

>
> -dros
>
>> + get_file(file);
>> + nfs4_unlock_state();
>> +
>> + switch (seek->seek_whence) {
>> + case NFS4_CONTENT_APP_DATA_HOLE:
>> + status = nfserr_union_notsupp;
>> + break;
>> + case NFS4_CONTENT_DATA:
>> + seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_DATA);
>> + end_pos = vfs_llseek(file, seek->seek_pos, SEEK_HOLE);
>> + seek->seek_allocated = true;
>> + break;
>> + case NFS4_CONTENT_HOLE:
>> + seek->seek_pos = vfs_llseek(file, seek->seek_offset, SEEK_HOLE);
>> + end_pos = vfs_llseek(file, seek->seek_pos, SEEK_DATA);
>> + seek->seek_allocated = false;
>> + break;
>> + default:
>> + status = nfs_ok;
>> + seek->seek_eof = true;
>> + goto out;
>> + }
>> +
>> + if (seek->seek_pos < 0) {
>> + status = nfserrno(seek->seek_pos);
>> + goto out;
>> + }
>> +
>> + seek->seek_length = end_pos - seek->seek_pos;
>> +
>> +out:
>> + fput(file);
>> + return status;
>> +}
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> +
>> /* This routine never returns NFS_OK! If there are no other errors, it
>> * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
>> * attributes matched. VERIFY is implemented by mapping NFSERR_SAME
>> @@ -1840,6 +1893,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
>> .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
>> .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
>> },
>> +
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> + [OP_SEEK] = {
>> + .op_func = (nfsd4op_func)nfsd4_seek,
>> + .op_name = "OP_SEEK",
>> + },
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> };
>>
>> #ifdef NFSD_DEBUG
>> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
>> index 3af6c46..7041039 100644
>> --- a/fs/nfsd/nfs4xdr.c
>> +++ b/fs/nfsd/nfs4xdr.c
>> @@ -1507,6 +1507,24 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
>> DECODE_TAIL;
>> }
>>
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> +static __be32
>> +nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
>> +{
>> + DECODE_HEAD;
>> +
>> + status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
>> + if (status)
>> + return status;
>> +
>> + READ_BUF(12);
>> + READ64(seek->seek_offset);
>> + READ32(seek->seek_whence);
>> +
>> + DECODE_TAIL;
>> +}
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> +
>> static __be32
>> nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
>> {
>> @@ -1589,7 +1607,11 @@ static nfsd4_dec nfsd4_dec_ops[] = {
>> [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_notsupp,
>> [OP_WRITE_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
>> [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp,
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> + [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek,
>> +#else
>> [OP_SEEK] = (nfsd4_dec)nfsd4_decode_notsupp,
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp,
>> };
>>
>> @@ -3514,6 +3536,28 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
>> return nfserr;
>> }
>>
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> +static __be32
>> +nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
>> + struct nfsd4_seek *seek)
>> +{
>> + __be32 *p;
>> +
>> + if (nfserr)
>> + return nfserr;
>> +
>> + RESERVE_SPACE(28);
>> + WRITE32(seek->seek_eof);
>> + WRITE32(seek->seek_whence);
>> + WRITE64(seek->seek_pos);
>> + WRITE64(seek->seek_length);
>> + WRITE32(seek->seek_allocated);
>> + ADJUST_ARGS();
>> +
>> + return nfserr;
>> +}
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> +
>> static __be32
>> nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
>> {
>> @@ -3595,7 +3639,11 @@ static nfsd4_enc nfsd4_enc_ops[] = {
>> [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_noop,
>> [OP_WRITE_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
>> [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop,
>> +#ifdef CONFIG_NFSD_V4_2_SEEK
>> + [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek,
>> +#else
>> [OP_SEEK] = (nfsd4_enc)nfsd4_encode_noop,
>> +#endif /* CONFIG_NFSD_V4_2_SEEK */
>> [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop,
>> };
>>
>> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
>> index b3ed644..c2f4e30 100644
>> --- a/fs/nfsd/xdr4.h
>> +++ b/fs/nfsd/xdr4.h
>> @@ -430,6 +430,19 @@ struct nfsd4_reclaim_complete {
>> u32 rca_one_fs;
>> };
>>
>> +struct nfsd4_seek {
>> + /* request */
>> + stateid_t seek_stateid;
>> + loff_t seek_offset;
>> + u32 seek_whence;
>> +
>> + /* response */
>> + u64 seek_pos;
>> + u32 seek_eof;
>> + u64 seek_length;
>> + u32 seek_allocated;
>> +};
>> +
>> struct nfsd4_op {
>> int opnum;
>> __be32 status;
>> @@ -475,6 +488,9 @@ struct nfsd4_op {
>> struct nfsd4_reclaim_complete reclaim_complete;
>> struct nfsd4_test_stateid test_stateid;
>> struct nfsd4_free_stateid free_stateid;
>> +
>> + /* NFSv4.2 */
>> + struct nfsd4_seek seek;
>> } u;
>> struct nfs4_replay * replay;
>> };
>> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
>> index e58e0eb..a35b0b6 100644
>> --- a/include/linux/nfs4.h
>> +++ b/include/linux/nfs4.h
>> @@ -558,4 +558,10 @@ struct nfs4_deviceid {
>> char data[NFS4_DEVICEID4_SIZE];
>> };
>>
>> +enum data_content4 {
>> + NFS4_CONTENT_DATA = 0,
>> + NFS4_CONTENT_APP_DATA_HOLE = 1,
>> + NFS4_CONTENT_HOLE = 2,
>> +};
>> +
>> #endif
>> --
>> 1.8.4.2
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>