NFSv4: Add a helper to encode/decode struct timespec
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
40a3426c75
commit
36b3743fef
1 changed files with 30 additions and 15 deletions
|
@ -99,6 +99,7 @@ static int nfs4_stat_to_errno(int);
|
|||
((3+NFS4_FHSIZE) >> 2))
|
||||
#define nfs4_fattr_bitmap_maxsz 4
|
||||
#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
|
||||
#define nfstime4_maxsz (3)
|
||||
#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
|
||||
#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
|
||||
#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
|
||||
|
@ -113,7 +114,8 @@ static int nfs4_stat_to_errno(int);
|
|||
#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
|
||||
/* This is based on getfattr, which uses the most attributes: */
|
||||
#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
|
||||
3 + 3 + 3 + nfs4_owner_maxsz + \
|
||||
3*nfstime4_maxsz + \
|
||||
nfs4_owner_maxsz + \
|
||||
nfs4_group_maxsz + nfs4_label_maxsz + \
|
||||
decode_mdsthreshold_maxsz))
|
||||
#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
|
||||
|
@ -124,7 +126,8 @@ static int nfs4_stat_to_errno(int);
|
|||
nfs4_owner_maxsz + \
|
||||
nfs4_group_maxsz + \
|
||||
nfs4_label_maxsz + \
|
||||
4 + 4)
|
||||
1 + nfstime4_maxsz + \
|
||||
1 + nfstime4_maxsz)
|
||||
#define encode_savefh_maxsz (op_encode_hdr_maxsz)
|
||||
#define decode_savefh_maxsz (op_decode_hdr_maxsz)
|
||||
#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
|
||||
|
@ -1041,6 +1044,14 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
|
|||
encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE);
|
||||
}
|
||||
|
||||
static __be32 *
|
||||
xdr_encode_nfstime4(__be32 *p, const struct timespec *t)
|
||||
{
|
||||
p = xdr_encode_hyper(p, (__s64)t->tv_sec);
|
||||
*p++ = cpu_to_be32(t->tv_nsec);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
||||
const struct nfs4_label *label,
|
||||
const umode_t *umask,
|
||||
|
@ -1100,7 +1111,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
|||
if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
|
||||
if (iap->ia_valid & ATTR_ATIME_SET) {
|
||||
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
||||
len += 16;
|
||||
len += 4 + (nfstime4_maxsz << 2);
|
||||
} else if (iap->ia_valid & ATTR_ATIME) {
|
||||
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
||||
len += 4;
|
||||
|
@ -1109,7 +1120,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
|||
if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
|
||||
if (iap->ia_valid & ATTR_MTIME_SET) {
|
||||
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||
len += 16;
|
||||
len += 4 + (nfstime4_maxsz << 2);
|
||||
} else if (iap->ia_valid & ATTR_MTIME) {
|
||||
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||
len += 4;
|
||||
|
@ -1135,16 +1146,14 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
|||
if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
|
||||
if (iap->ia_valid & ATTR_ATIME_SET) {
|
||||
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
||||
p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec);
|
||||
*p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
|
||||
p = xdr_encode_nfstime4(p, &iap->ia_atime);
|
||||
} else
|
||||
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
||||
}
|
||||
if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
|
||||
if (iap->ia_valid & ATTR_MTIME_SET) {
|
||||
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
||||
p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec);
|
||||
*p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
|
||||
p = xdr_encode_nfstime4(p, &iap->ia_mtime);
|
||||
} else
|
||||
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
||||
}
|
||||
|
@ -4129,19 +4138,25 @@ out_overflow:
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static __be32 *
|
||||
xdr_decode_nfstime4(__be32 *p, struct timespec *t)
|
||||
{
|
||||
__u64 sec;
|
||||
|
||||
p = xdr_decode_hyper(p, &sec);
|
||||
t-> tv_sec = (time_t)sec;
|
||||
t->tv_nsec = be32_to_cpup(p++);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
|
||||
{
|
||||
__be32 *p;
|
||||
uint64_t sec;
|
||||
uint32_t nsec;
|
||||
|
||||
p = xdr_inline_decode(xdr, 12);
|
||||
p = xdr_inline_decode(xdr, nfstime4_maxsz << 2);
|
||||
if (unlikely(!p))
|
||||
goto out_overflow;
|
||||
p = xdr_decode_hyper(p, &sec);
|
||||
nsec = be32_to_cpup(p);
|
||||
time->tv_sec = (time_t)sec;
|
||||
time->tv_nsec = (long)nsec;
|
||||
xdr_decode_nfstime4(p, time);
|
||||
return 0;
|
||||
out_overflow:
|
||||
print_overflow_msg(__func__, xdr);
|
||||
|
|
Loading…
Reference in a new issue