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
|
@ -99,6 +99,7 @@ static int nfs4_stat_to_errno(int);
|
||||||
((3+NFS4_FHSIZE) >> 2))
|
((3+NFS4_FHSIZE) >> 2))
|
||||||
#define nfs4_fattr_bitmap_maxsz 4
|
#define nfs4_fattr_bitmap_maxsz 4
|
||||||
#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
|
#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_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
|
||||||
#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
|
#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
|
||||||
#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
|
#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)
|
#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
|
||||||
/* This is based on getfattr, which uses the most attributes: */
|
/* 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 + \
|
#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 + \
|
nfs4_group_maxsz + nfs4_label_maxsz + \
|
||||||
decode_mdsthreshold_maxsz))
|
decode_mdsthreshold_maxsz))
|
||||||
#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
|
#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
|
||||||
|
@ -124,7 +126,8 @@ static int nfs4_stat_to_errno(int);
|
||||||
nfs4_owner_maxsz + \
|
nfs4_owner_maxsz + \
|
||||||
nfs4_group_maxsz + \
|
nfs4_group_maxsz + \
|
||||||
nfs4_label_maxsz + \
|
nfs4_label_maxsz + \
|
||||||
4 + 4)
|
1 + nfstime4_maxsz + \
|
||||||
|
1 + nfstime4_maxsz)
|
||||||
#define encode_savefh_maxsz (op_encode_hdr_maxsz)
|
#define encode_savefh_maxsz (op_encode_hdr_maxsz)
|
||||||
#define decode_savefh_maxsz (op_decode_hdr_maxsz)
|
#define decode_savefh_maxsz (op_decode_hdr_maxsz)
|
||||||
#define encode_restorefh_maxsz (op_encode_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);
|
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,
|
static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
||||||
const struct nfs4_label *label,
|
const struct nfs4_label *label,
|
||||||
const umode_t *umask,
|
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 (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
|
||||||
if (iap->ia_valid & ATTR_ATIME_SET) {
|
if (iap->ia_valid & ATTR_ATIME_SET) {
|
||||||
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
||||||
len += 16;
|
len += 4 + (nfstime4_maxsz << 2);
|
||||||
} else if (iap->ia_valid & ATTR_ATIME) {
|
} else if (iap->ia_valid & ATTR_ATIME) {
|
||||||
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
||||||
len += 4;
|
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 (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
|
||||||
if (iap->ia_valid & ATTR_MTIME_SET) {
|
if (iap->ia_valid & ATTR_MTIME_SET) {
|
||||||
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||||
len += 16;
|
len += 4 + (nfstime4_maxsz << 2);
|
||||||
} else if (iap->ia_valid & ATTR_MTIME) {
|
} else if (iap->ia_valid & ATTR_MTIME) {
|
||||||
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||||
len += 4;
|
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 (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
|
||||||
if (iap->ia_valid & ATTR_ATIME_SET) {
|
if (iap->ia_valid & ATTR_ATIME_SET) {
|
||||||
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
||||||
p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec);
|
p = xdr_encode_nfstime4(p, &iap->ia_atime);
|
||||||
*p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
|
|
||||||
} else
|
} else
|
||||||
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
||||||
}
|
}
|
||||||
if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
|
if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
|
||||||
if (iap->ia_valid & ATTR_MTIME_SET) {
|
if (iap->ia_valid & ATTR_MTIME_SET) {
|
||||||
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
|
||||||
p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec);
|
p = xdr_encode_nfstime4(p, &iap->ia_mtime);
|
||||||
*p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
|
|
||||||
} else
|
} else
|
||||||
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
||||||
}
|
}
|
||||||
|
@ -4129,19 +4138,25 @@ out_overflow:
|
||||||
return -EIO;
|
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)
|
static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__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))
|
if (unlikely(!p))
|
||||||
goto out_overflow;
|
goto out_overflow;
|
||||||
p = xdr_decode_hyper(p, &sec);
|
xdr_decode_nfstime4(p, time);
|
||||||
nsec = be32_to_cpup(p);
|
|
||||||
time->tv_sec = (time_t)sec;
|
|
||||||
time->tv_nsec = (long)nsec;
|
|
||||||
return 0;
|
return 0;
|
||||||
out_overflow:
|
out_overflow:
|
||||||
print_overflow_msg(__func__, xdr);
|
print_overflow_msg(__func__, xdr);
|
||||||
|
|
Loading…
Reference in New Issue