diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2018-03-20 17:03:10 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2018-04-10 16:06:22 -0400 |
commit | 36b3743fef88616f92b49949fe1022f345970258 (patch) | |
tree | 48763cb5e2b2d51926b5813187da7a819bed64a2 /fs/nfs/nfs4xdr.c | |
parent | 40a3426c75e1621ee6d88be2352f5dd85f557aed (diff) |
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>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 3d088230c975..79f1774b9d68 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -99,6 +99,7 @@ static int nfs4_stat_to_errno(int); | |||
99 | ((3+NFS4_FHSIZE) >> 2)) | 99 | ((3+NFS4_FHSIZE) >> 2)) |
100 | #define nfs4_fattr_bitmap_maxsz 4 | 100 | #define nfs4_fattr_bitmap_maxsz 4 |
101 | #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) | 101 | #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) |
102 | #define nfstime4_maxsz (3) | ||
102 | #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) | 103 | #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) |
103 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) | 104 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) |
104 | #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) | 105 | #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) |
@@ -113,7 +114,8 @@ static int nfs4_stat_to_errno(int); | |||
113 | #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) | 114 | #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) |
114 | /* This is based on getfattr, which uses the most attributes: */ | 115 | /* This is based on getfattr, which uses the most attributes: */ |
115 | #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ | 116 | #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ |
116 | 3 + 3 + 3 + nfs4_owner_maxsz + \ | 117 | 3*nfstime4_maxsz + \ |
118 | nfs4_owner_maxsz + \ | ||
117 | nfs4_group_maxsz + nfs4_label_maxsz + \ | 119 | nfs4_group_maxsz + nfs4_label_maxsz + \ |
118 | decode_mdsthreshold_maxsz)) | 120 | decode_mdsthreshold_maxsz)) |
119 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ | 121 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ |
@@ -124,7 +126,8 @@ static int nfs4_stat_to_errno(int); | |||
124 | nfs4_owner_maxsz + \ | 126 | nfs4_owner_maxsz + \ |
125 | nfs4_group_maxsz + \ | 127 | nfs4_group_maxsz + \ |
126 | nfs4_label_maxsz + \ | 128 | nfs4_label_maxsz + \ |
127 | 4 + 4) | 129 | 1 + nfstime4_maxsz + \ |
130 | 1 + nfstime4_maxsz) | ||
128 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) | 131 | #define encode_savefh_maxsz (op_encode_hdr_maxsz) |
129 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) | 132 | #define decode_savefh_maxsz (op_decode_hdr_maxsz) |
130 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | 133 | #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 | |||
1041 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); | 1044 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); |
1042 | } | 1045 | } |
1043 | 1046 | ||
1047 | static __be32 * | ||
1048 | xdr_encode_nfstime4(__be32 *p, const struct timespec *t) | ||
1049 | { | ||
1050 | p = xdr_encode_hyper(p, (__s64)t->tv_sec); | ||
1051 | *p++ = cpu_to_be32(t->tv_nsec); | ||
1052 | return p; | ||
1053 | } | ||
1054 | |||
1044 | static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | 1055 | static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, |
1045 | const struct nfs4_label *label, | 1056 | const struct nfs4_label *label, |
1046 | const umode_t *umask, | 1057 | const umode_t *umask, |
@@ -1100,7 +1111,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | |||
1100 | if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) { | 1111 | if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) { |
1101 | if (iap->ia_valid & ATTR_ATIME_SET) { | 1112 | if (iap->ia_valid & ATTR_ATIME_SET) { |
1102 | bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; | 1113 | bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; |
1103 | len += 16; | 1114 | len += 4 + (nfstime4_maxsz << 2); |
1104 | } else if (iap->ia_valid & ATTR_ATIME) { | 1115 | } else if (iap->ia_valid & ATTR_ATIME) { |
1105 | bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; | 1116 | bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; |
1106 | len += 4; | 1117 | len += 4; |
@@ -1109,7 +1120,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | |||
1109 | if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) { | 1120 | if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) { |
1110 | if (iap->ia_valid & ATTR_MTIME_SET) { | 1121 | if (iap->ia_valid & ATTR_MTIME_SET) { |
1111 | bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; | 1122 | bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; |
1112 | len += 16; | 1123 | len += 4 + (nfstime4_maxsz << 2); |
1113 | } else if (iap->ia_valid & ATTR_MTIME) { | 1124 | } else if (iap->ia_valid & ATTR_MTIME) { |
1114 | bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; | 1125 | bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; |
1115 | len += 4; | 1126 | len += 4; |
@@ -1135,16 +1146,14 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | |||
1135 | if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { | 1146 | if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { |
1136 | if (iap->ia_valid & ATTR_ATIME_SET) { | 1147 | if (iap->ia_valid & ATTR_ATIME_SET) { |
1137 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); | 1148 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
1138 | p = xdr_encode_hyper(p, (s64)iap->ia_atime.tv_sec); | 1149 | p = xdr_encode_nfstime4(p, &iap->ia_atime); |
1139 | *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); | ||
1140 | } else | 1150 | } else |
1141 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); | 1151 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); |
1142 | } | 1152 | } |
1143 | if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { | 1153 | if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { |
1144 | if (iap->ia_valid & ATTR_MTIME_SET) { | 1154 | if (iap->ia_valid & ATTR_MTIME_SET) { |
1145 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); | 1155 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
1146 | p = xdr_encode_hyper(p, (s64)iap->ia_mtime.tv_sec); | 1156 | p = xdr_encode_nfstime4(p, &iap->ia_mtime); |
1147 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); | ||
1148 | } else | 1157 | } else |
1149 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); | 1158 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); |
1150 | } | 1159 | } |
@@ -4129,19 +4138,25 @@ out_overflow: | |||
4129 | return -EIO; | 4138 | return -EIO; |
4130 | } | 4139 | } |
4131 | 4140 | ||
4141 | static __be32 * | ||
4142 | xdr_decode_nfstime4(__be32 *p, struct timespec *t) | ||
4143 | { | ||
4144 | __u64 sec; | ||
4145 | |||
4146 | p = xdr_decode_hyper(p, &sec); | ||
4147 | t-> tv_sec = (time_t)sec; | ||
4148 | t->tv_nsec = be32_to_cpup(p++); | ||
4149 | return p; | ||
4150 | } | ||
4151 | |||
4132 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | 4152 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) |
4133 | { | 4153 | { |
4134 | __be32 *p; | 4154 | __be32 *p; |
4135 | uint64_t sec; | ||
4136 | uint32_t nsec; | ||
4137 | 4155 | ||
4138 | p = xdr_inline_decode(xdr, 12); | 4156 | p = xdr_inline_decode(xdr, nfstime4_maxsz << 2); |
4139 | if (unlikely(!p)) | 4157 | if (unlikely(!p)) |
4140 | goto out_overflow; | 4158 | goto out_overflow; |
4141 | p = xdr_decode_hyper(p, &sec); | 4159 | xdr_decode_nfstime4(p, time); |
4142 | nsec = be32_to_cpup(p); | ||
4143 | time->tv_sec = (time_t)sec; | ||
4144 | time->tv_nsec = (long)nsec; | ||
4145 | return 0; | 4160 | return 0; |
4146 | out_overflow: | 4161 | out_overflow: |
4147 | print_overflow_msg(__func__, xdr); | 4162 | print_overflow_msg(__func__, xdr); |