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: Arnd Bergmann <arnd@arndb.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
e29f470396
commit
92c5e46911
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user