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[] = { ...@@ -32,14 +32,14 @@ static u32 nfs3_ftypes[] = {
* XDR functions for basic NFS types * XDR functions for basic NFS types
*/ */
static __be32 * 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); *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
return p; return p;
} }
static __be32 * static __be32 *
decode_time3(__be32 *p, struct timespec *time) decode_time3(__be32 *p, struct timespec64 *time)
{ {
time->tv_sec = ntohl(*p++); time->tv_sec = ntohl(*p++);
time->tv_nsec = ntohl(*p++); time->tv_nsec = ntohl(*p++);
...@@ -167,7 +167,6 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, ...@@ -167,7 +167,6 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
struct kstat *stat) struct kstat *stat)
{ {
struct user_namespace *userns = nfsd_user_namespace(rqstp); struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct timespec ts;
*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
*p++ = htonl((u32) (stat->mode & S_IALLUGO)); *p++ = htonl((u32) (stat->mode & S_IALLUGO));
*p++ = htonl((u32) stat->nlink); *p++ = htonl((u32) stat->nlink);
...@@ -183,12 +182,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, ...@@ -183,12 +182,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
*p++ = htonl((u32) MINOR(stat->rdev)); *p++ = htonl((u32) MINOR(stat->rdev));
p = encode_fsid(p, fhp); p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, stat->ino); p = xdr_encode_hyper(p, stat->ino);
ts = timespec64_to_timespec(stat->atime); p = encode_time3(p, &stat->atime);
p = encode_time3(p, &ts); p = encode_time3(p, &stat->mtime);
ts = timespec64_to_timespec(stat->mtime); p = encode_time3(p, &stat->ctime);
p = encode_time3(p, &ts);
ts = timespec64_to_timespec(stat->ctime);
p = encode_time3(p, &ts);
return p; return p;
} }
...@@ -277,8 +273,8 @@ void fill_pre_wcc(struct svc_fh *fhp) ...@@ -277,8 +273,8 @@ void fill_pre_wcc(struct svc_fh *fhp)
stat.size = inode->i_size; stat.size = inode->i_size;
} }
fhp->fh_pre_mtime = timespec64_to_timespec(stat.mtime); fhp->fh_pre_mtime = stat.mtime;
fhp->fh_pre_ctime = timespec64_to_timespec(stat.ctime); fhp->fh_pre_ctime = stat.ctime;
fhp->fh_pre_size = stat.size; fhp->fh_pre_size = stat.size;
fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode); fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
fhp->fh_pre_saved = true; fhp->fh_pre_saved = true;
...@@ -330,7 +326,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p) ...@@ -330,7 +326,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp)); p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
if ((args->check_guard = ntohl(*p++)) != 0) { if ((args->check_guard = ntohl(*p++)) != 0) {
struct timespec time; struct timespec64 time;
p = decode_time3(p, &time); p = decode_time3(p, &time);
args->guardtime = time.tv_sec; args->guardtime = time.tv_sec;
} }
......
...@@ -42,8 +42,8 @@ typedef struct svc_fh { ...@@ -42,8 +42,8 @@ typedef struct svc_fh {
/* Pre-op attributes saved during fh_lock */ /* Pre-op attributes saved during fh_lock */
__u64 fh_pre_size; /* size before operation */ __u64 fh_pre_size; /* size before operation */
struct timespec fh_pre_mtime; /* mtime before oper */ struct timespec64 fh_pre_mtime; /* mtime before oper */
struct timespec fh_pre_ctime; /* ctime before oper */ struct timespec64 fh_pre_ctime; /* ctime before oper */
/* /*
* pre-op nfsv4 change attr: note must check IS_I_VERSION(inode) * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
* to find out if it is valid. * 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