Commit 92c5e469 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by J. Bruce Fields

nfsd: handle nfs3 timestamps as unsigned

The decode_time3 function behaves differently on 32-bit
and 64-bit architectures: on the former, a 32-bit timestamp
gets converted into an signed number and then into a timestamp
between 1902 and 2038, while on the latter it is interpreted
as unsigned in the range 1970-2106.

Change all the remaining 'timespec' in nfsd to 'timespec64'
to make the behavior the same, and use the current interpretation
of the dominant 64-bit architectures.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent e29f4703
......@@ -32,14 +32,14 @@ static u32 nfs3_ftypes[] = {
* XDR functions for basic NFS types
*/
static __be32 *
encode_time3(__be32 *p, struct timespec *time)
encode_time3(__be32 *p, struct timespec64 *time)
{
*p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
return p;
}
static __be32 *
decode_time3(__be32 *p, struct timespec *time)
decode_time3(__be32 *p, struct timespec64 *time)
{
time->tv_sec = ntohl(*p++);
time->tv_nsec = ntohl(*p++);
......@@ -167,7 +167,6 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
struct kstat *stat)
{
struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct timespec ts;
*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
*p++ = htonl((u32) (stat->mode & S_IALLUGO));
*p++ = htonl((u32) stat->nlink);
......@@ -183,12 +182,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
*p++ = htonl((u32) MINOR(stat->rdev));
p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, stat->ino);
ts = timespec64_to_timespec(stat->atime);
p = encode_time3(p, &ts);
ts = timespec64_to_timespec(stat->mtime);
p = encode_time3(p, &ts);
ts = timespec64_to_timespec(stat->ctime);
p = encode_time3(p, &ts);
p = encode_time3(p, &stat->atime);
p = encode_time3(p, &stat->mtime);
p = encode_time3(p, &stat->ctime);
return p;
}
......@@ -277,8 +273,8 @@ void fill_pre_wcc(struct svc_fh *fhp)
stat.size = inode->i_size;
}
fhp->fh_pre_mtime = timespec64_to_timespec(stat.mtime);
fhp->fh_pre_ctime = timespec64_to_timespec(stat.ctime);
fhp->fh_pre_mtime = stat.mtime;
fhp->fh_pre_ctime = stat.ctime;
fhp->fh_pre_size = stat.size;
fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
fhp->fh_pre_saved = true;
......@@ -330,7 +326,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
if ((args->check_guard = ntohl(*p++)) != 0) {
struct timespec time;
struct timespec64 time;
p = decode_time3(p, &time);
args->guardtime = time.tv_sec;
}
......
......@@ -42,8 +42,8 @@ typedef struct svc_fh {
/* Pre-op attributes saved during fh_lock */
__u64 fh_pre_size; /* size before operation */
struct timespec fh_pre_mtime; /* mtime before oper */
struct timespec fh_pre_ctime; /* ctime before oper */
struct timespec64 fh_pre_mtime; /* mtime before oper */
struct timespec64 fh_pre_ctime; /* ctime before oper */
/*
* pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
* to find out if it is valid.
......
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