Commit 993474e8 authored by Chuck Lever's avatar Chuck Lever

NFSD: Add nfsd4_encode_fattr4_time_delta()

Refactor the encoder for FATTR4_TIME_DELTA into a helper. In a
subsequent patch, this helper will be called from a bitmask loop.

fattr4_time_delta is specified as an nfstime4, so de-duplicate this
encoder.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 2e38722d
...@@ -2561,31 +2561,6 @@ static __be32 nfsd4_encode_specdata4(struct xdr_stream *xdr, ...@@ -2561,31 +2561,6 @@ static __be32 nfsd4_encode_specdata4(struct xdr_stream *xdr,
return nfsd4_encode_uint32_t(xdr, minor); return nfsd4_encode_uint32_t(xdr, minor);
} }
/*
* ctime (in NFSv4, time_metadata) is not writeable, and the client
* doesn't really care what resolution could theoretically be stored by
* the filesystem.
*
* The client cares how close together changes can be while still
* guaranteeing ctime changes. For most filesystems (which have
* timestamps with nanosecond fields) that is limited by the resolution
* of the time returned from current_time() (which I'm assuming to be
* 1/HZ).
*/
static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
{
struct timespec64 ts;
u32 ns;
ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
ts = ns_to_timespec64(ns);
p = xdr_encode_hyper(p, ts.tv_sec);
*p++ = cpu_to_be32(ts.tv_nsec);
return p;
}
static __be32 static __be32
nfsd4_encode_change_info4(struct xdr_stream *xdr, const struct nfsd4_change_info *c) nfsd4_encode_change_info4(struct xdr_stream *xdr, const struct nfsd4_change_info *c)
{ {
...@@ -3267,6 +3242,27 @@ static __be32 nfsd4_encode_fattr4_time_create(struct xdr_stream *xdr, ...@@ -3267,6 +3242,27 @@ static __be32 nfsd4_encode_fattr4_time_create(struct xdr_stream *xdr,
return nfsd4_encode_nfstime4(xdr, &args->stat.btime); return nfsd4_encode_nfstime4(xdr, &args->stat.btime);
} }
/*
* ctime (in NFSv4, time_metadata) is not writeable, and the client
* doesn't really care what resolution could theoretically be stored by
* the filesystem.
*
* The client cares how close together changes can be while still
* guaranteeing ctime changes. For most filesystems (which have
* timestamps with nanosecond fields) that is limited by the resolution
* of the time returned from current_time() (which I'm assuming to be
* 1/HZ).
*/
static __be32 nfsd4_encode_fattr4_time_delta(struct xdr_stream *xdr,
const struct nfsd4_fattr_args *args)
{
const struct inode *inode = d_inode(args->dentry);
u32 ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
struct timespec64 ts = ns_to_timespec64(ns);
return nfsd4_encode_nfstime4(xdr, &ts);
}
/* /*
* Note: @fhp can be NULL; in this case, we might have to compose the filehandle * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
* ourselves. * ourselves.
...@@ -3605,10 +3601,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, ...@@ -3605,10 +3601,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
goto out; goto out;
} }
if (bmval1 & FATTR4_WORD1_TIME_DELTA) { if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
p = xdr_reserve_space(xdr, 12); status = nfsd4_encode_fattr4_time_delta(xdr, &args);
if (!p) if (status != nfs_ok)
goto out_resource; goto out;
p = encode_time_delta(p, d_inode(dentry));
} }
if (bmval1 & FATTR4_WORD1_TIME_METADATA) { if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
status = nfsd4_encode_nfstime4(xdr, &args.stat.ctime); status = nfsd4_encode_nfstime4(xdr, &args.stat.ctime);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment