Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ceph: use timespec64 for inode timestamp

Since the vfs structures are all using timespec64, we can now
change the internal representation, using ceph_encode_timespec64 and
ceph_decode_timespec64.

In case of ceph_aux_inode however, we need to avoid doing a memcmp()
on uninitialized padding data, so the members of the i_mtime field get
copied individually into 64-bit integers.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

authored by

Arnd Bergmann and committed by
Ilya Dryomov
9bbeab41 63ecae7e

+71 -74
+7 -4
fs/ceph/cache.c
··· 25 25 #include "cache.h" 26 26 27 27 struct ceph_aux_inode { 28 - u64 version; 29 - struct timespec mtime; 28 + u64 version; 29 + u64 mtime_sec; 30 + u64 mtime_nsec; 30 31 }; 31 32 32 33 struct fscache_netfs ceph_cache_netfs = { ··· 131 130 132 131 memset(&aux, 0, sizeof(aux)); 133 132 aux.version = ci->i_version; 134 - aux.mtime = timespec64_to_timespec(inode->i_mtime); 133 + aux.mtime_sec = inode->i_mtime.tv_sec; 134 + aux.mtime_nsec = inode->i_mtime.tv_nsec; 135 135 136 136 if (memcmp(data, &aux, sizeof(aux)) != 0) 137 137 return FSCACHE_CHECKAUX_OBSOLETE; ··· 165 163 if (!ci->fscache) { 166 164 memset(&aux, 0, sizeof(aux)); 167 165 aux.version = ci->i_version; 168 - aux.mtime = timespec64_to_timespec(inode->i_mtime); 166 + aux.mtime_sec = inode->i_mtime.tv_sec; 167 + aux.mtime_nsec = inode->i_mtime.tv_nsec; 169 168 ci->fscache = fscache_acquire_cookie(fsc->fscache, 170 169 &ceph_fscache_inode_object_def, 171 170 &ci->i_vino, sizeof(ci->i_vino),
+13 -13
fs/ceph/caps.c
··· 1125 1125 u64 flush_tid, oldest_flush_tid, size, max_size; 1126 1126 u64 xattr_version; 1127 1127 struct ceph_buffer *xattr_buf; 1128 - struct timespec atime, mtime, ctime; 1128 + struct timespec64 atime, mtime, ctime; 1129 1129 int op, caps, wanted, dirty; 1130 1130 u32 seq, issue_seq, mseq, time_warp_seq; 1131 1131 u32 flags; ··· 1146 1146 struct ceph_msg *msg; 1147 1147 void *p; 1148 1148 size_t extra_len; 1149 - struct timespec zerotime = {0}; 1149 + struct timespec64 zerotime = {0}; 1150 1150 struct ceph_osd_client *osdc = &arg->session->s_mdsc->fsc->client->osdc; 1151 1151 1152 1152 dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s" ··· 1186 1186 1187 1187 fc->size = cpu_to_le64(arg->size); 1188 1188 fc->max_size = cpu_to_le64(arg->max_size); 1189 - ceph_encode_timespec(&fc->mtime, &arg->mtime); 1190 - ceph_encode_timespec(&fc->atime, &arg->atime); 1191 - ceph_encode_timespec(&fc->ctime, &arg->ctime); 1189 + ceph_encode_timespec64(&fc->mtime, &arg->mtime); 1190 + ceph_encode_timespec64(&fc->atime, &arg->atime); 1191 + ceph_encode_timespec64(&fc->ctime, &arg->ctime); 1192 1192 fc->time_warp_seq = cpu_to_le32(arg->time_warp_seq); 1193 1193 1194 1194 fc->uid = cpu_to_le32(from_kuid(&init_user_ns, arg->uid)); ··· 1237 1237 * We just zero these out for now, as the MDS ignores them unless 1238 1238 * the requisite feature flags are set (which we don't do yet). 1239 1239 */ 1240 - ceph_encode_timespec(p, &zerotime); 1240 + ceph_encode_timespec64(p, &zerotime); 1241 1241 p += sizeof(struct ceph_timespec); 1242 1242 ceph_encode_64(&p, 0); 1243 1243 ··· 1360 1360 arg.xattr_buf = NULL; 1361 1361 } 1362 1362 1363 - arg.mtime = timespec64_to_timespec(inode->i_mtime); 1364 - arg.atime = timespec64_to_timespec(inode->i_atime); 1365 - arg.ctime = timespec64_to_timespec(inode->i_ctime); 1363 + arg.mtime = inode->i_mtime; 1364 + arg.atime = inode->i_atime; 1365 + arg.ctime = inode->i_ctime; 1366 1366 1367 1367 arg.op = op; 1368 1368 arg.caps = cap->implemented; ··· 3148 3148 } 3149 3149 3150 3150 if (newcaps & CEPH_CAP_ANY_RD) { 3151 - struct timespec mtime, atime, ctime; 3151 + struct timespec64 mtime, atime, ctime; 3152 3152 /* ctime/mtime/atime? */ 3153 - ceph_decode_timespec(&mtime, &grant->mtime); 3154 - ceph_decode_timespec(&atime, &grant->atime); 3155 - ceph_decode_timespec(&ctime, &grant->ctime); 3153 + ceph_decode_timespec64(&mtime, &grant->mtime); 3154 + ceph_decode_timespec64(&atime, &grant->atime); 3155 + ceph_decode_timespec64(&ctime, &grant->ctime); 3156 3156 ceph_fill_file_time(inode, extra_info->issued, 3157 3157 le32_to_cpu(grant->time_warp_seq), 3158 3158 &ctime, &mtime, &atime);
+3 -3
fs/ceph/dir.c
··· 1397 1397 " rfiles: %20lld\n" 1398 1398 " rsubdirs: %20lld\n" 1399 1399 "rbytes: %20lld\n" 1400 - "rctime: %10ld.%09ld\n", 1400 + "rctime: %10lld.%09ld\n", 1401 1401 ci->i_files + ci->i_subdirs, 1402 1402 ci->i_files, 1403 1403 ci->i_subdirs, ··· 1405 1405 ci->i_rfiles, 1406 1406 ci->i_rsubdirs, 1407 1407 ci->i_rbytes, 1408 - (long)ci->i_rctime.tv_sec, 1409 - (long)ci->i_rctime.tv_nsec); 1408 + ci->i_rctime.tv_sec, 1409 + ci->i_rctime.tv_nsec); 1410 1410 } 1411 1411 1412 1412 if (*ppos >= dfi->dir_info_len)
+36 -40
fs/ceph/inode.c
··· 658 658 } 659 659 660 660 void ceph_fill_file_time(struct inode *inode, int issued, 661 - u64 time_warp_seq, struct timespec *ctime, 662 - struct timespec *mtime, struct timespec *atime) 661 + u64 time_warp_seq, struct timespec64 *ctime, 662 + struct timespec64 *mtime, struct timespec64 *atime) 663 663 { 664 664 struct ceph_inode_info *ci = ceph_inode(inode); 665 - struct timespec64 ctime64 = timespec_to_timespec64(*ctime); 666 - struct timespec64 mtime64 = timespec_to_timespec64(*mtime); 667 - struct timespec64 atime64 = timespec_to_timespec64(*atime); 668 665 int warn = 0; 669 666 670 667 if (issued & (CEPH_CAP_FILE_EXCL| ··· 670 673 CEPH_CAP_AUTH_EXCL| 671 674 CEPH_CAP_XATTR_EXCL)) { 672 675 if (ci->i_version == 0 || 673 - timespec64_compare(&ctime64, &inode->i_ctime) > 0) { 676 + timespec64_compare(ctime, &inode->i_ctime) > 0) { 674 677 dout("ctime %lld.%09ld -> %lld.%09ld inc w/ cap\n", 675 - (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, 676 - (long long)ctime->tv_sec, ctime->tv_nsec); 677 - inode->i_ctime = ctime64; 678 + inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, 679 + ctime->tv_sec, ctime->tv_nsec); 680 + inode->i_ctime = *ctime; 678 681 } 679 682 if (ci->i_version == 0 || 680 683 ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { 681 684 /* the MDS did a utimes() */ 682 685 dout("mtime %lld.%09ld -> %lld.%09ld " 683 686 "tw %d -> %d\n", 684 - (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, 685 - (long long)mtime->tv_sec, mtime->tv_nsec, 687 + inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, 688 + mtime->tv_sec, mtime->tv_nsec, 686 689 ci->i_time_warp_seq, (int)time_warp_seq); 687 690 688 - inode->i_mtime = mtime64; 689 - inode->i_atime = atime64; 691 + inode->i_mtime = *mtime; 692 + inode->i_atime = *atime; 690 693 ci->i_time_warp_seq = time_warp_seq; 691 694 } else if (time_warp_seq == ci->i_time_warp_seq) { 692 695 /* nobody did utimes(); take the max */ 693 - if (timespec64_compare(&mtime64, &inode->i_mtime) > 0) { 696 + if (timespec64_compare(mtime, &inode->i_mtime) > 0) { 694 697 dout("mtime %lld.%09ld -> %lld.%09ld inc\n", 695 - (long long)inode->i_mtime.tv_sec, 698 + inode->i_mtime.tv_sec, 696 699 inode->i_mtime.tv_nsec, 697 - (long long)mtime->tv_sec, mtime->tv_nsec); 698 - inode->i_mtime = mtime64; 700 + mtime->tv_sec, mtime->tv_nsec); 701 + inode->i_mtime = *mtime; 699 702 } 700 - if (timespec64_compare(&atime64, &inode->i_atime) > 0) { 703 + if (timespec64_compare(atime, &inode->i_atime) > 0) { 701 704 dout("atime %lld.%09ld -> %lld.%09ld inc\n", 702 - (long long)inode->i_atime.tv_sec, 705 + inode->i_atime.tv_sec, 703 706 inode->i_atime.tv_nsec, 704 - (long long)atime->tv_sec, atime->tv_nsec); 705 - inode->i_atime = atime64; 707 + atime->tv_sec, atime->tv_nsec); 708 + inode->i_atime = *atime; 706 709 } 707 710 } else if (issued & CEPH_CAP_FILE_EXCL) { 708 711 /* we did a utimes(); ignore mds values */ ··· 712 715 } else { 713 716 /* we have no write|excl caps; whatever the MDS says is true */ 714 717 if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) { 715 - inode->i_ctime = ctime64; 716 - inode->i_mtime = mtime64; 717 - inode->i_atime = atime64; 718 + inode->i_ctime = *ctime; 719 + inode->i_mtime = *mtime; 720 + inode->i_atime = *atime; 718 721 ci->i_time_warp_seq = time_warp_seq; 719 722 } else { 720 723 warn = 1; ··· 740 743 struct ceph_mds_reply_inode *info = iinfo->in; 741 744 struct ceph_inode_info *ci = ceph_inode(inode); 742 745 int issued, new_issued, info_caps; 743 - struct timespec mtime, atime, ctime; 746 + struct timespec64 mtime, atime, ctime; 744 747 struct ceph_buffer *xattr_blob = NULL; 745 748 struct ceph_string *pool_ns = NULL; 746 749 struct ceph_cap *new_cap = NULL; ··· 820 823 821 824 if (new_version || (new_issued & CEPH_CAP_ANY_RD)) { 822 825 /* be careful with mtime, atime, size */ 823 - ceph_decode_timespec(&atime, &info->atime); 824 - ceph_decode_timespec(&mtime, &info->mtime); 825 - ceph_decode_timespec(&ctime, &info->ctime); 826 + ceph_decode_timespec64(&atime, &info->atime); 827 + ceph_decode_timespec64(&mtime, &info->mtime); 828 + ceph_decode_timespec64(&ctime, &info->ctime); 826 829 ceph_fill_file_time(inode, issued, 827 830 le32_to_cpu(info->time_warp_seq), 828 831 &ctime, &mtime, &atime); ··· 869 872 ci->i_rbytes = le64_to_cpu(info->rbytes); 870 873 ci->i_rfiles = le64_to_cpu(info->rfiles); 871 874 ci->i_rsubdirs = le64_to_cpu(info->rsubdirs); 872 - ceph_decode_timespec(&ci->i_rctime, &info->rctime); 875 + ceph_decode_timespec64(&ci->i_rctime, &info->rctime); 873 876 } 874 877 } 875 878 ··· 1951 1954 int err = 0; 1952 1955 int inode_dirty_flags = 0; 1953 1956 bool lock_snap_rwsem = false; 1954 - struct timespec ts; 1955 1957 1956 1958 prealloc_cf = ceph_alloc_cap_flush(); 1957 1959 if (!prealloc_cf) ··· 2026 2030 2027 2031 if (ia_valid & ATTR_ATIME) { 2028 2032 dout("setattr %p atime %lld.%ld -> %lld.%ld\n", inode, 2029 - (long long)inode->i_atime.tv_sec, inode->i_atime.tv_nsec, 2030 - (long long)attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec); 2033 + inode->i_atime.tv_sec, inode->i_atime.tv_nsec, 2034 + attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec); 2031 2035 if (issued & CEPH_CAP_FILE_EXCL) { 2032 2036 ci->i_time_warp_seq++; 2033 2037 inode->i_atime = attr->ia_atime; ··· 2039 2043 dirtied |= CEPH_CAP_FILE_WR; 2040 2044 } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 || 2041 2045 !timespec64_equal(&inode->i_atime, &attr->ia_atime)) { 2042 - ts = timespec64_to_timespec(attr->ia_atime); 2043 - ceph_encode_timespec(&req->r_args.setattr.atime, &ts); 2046 + ceph_encode_timespec64(&req->r_args.setattr.atime, 2047 + &attr->ia_atime); 2044 2048 mask |= CEPH_SETATTR_ATIME; 2045 2049 release |= CEPH_CAP_FILE_SHARED | 2046 2050 CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR; ··· 2048 2052 } 2049 2053 if (ia_valid & ATTR_MTIME) { 2050 2054 dout("setattr %p mtime %lld.%ld -> %lld.%ld\n", inode, 2051 - (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, 2052 - (long long)attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec); 2055 + inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, 2056 + attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec); 2053 2057 if (issued & CEPH_CAP_FILE_EXCL) { 2054 2058 ci->i_time_warp_seq++; 2055 2059 inode->i_mtime = attr->ia_mtime; ··· 2061 2065 dirtied |= CEPH_CAP_FILE_WR; 2062 2066 } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 || 2063 2067 !timespec64_equal(&inode->i_mtime, &attr->ia_mtime)) { 2064 - ts = timespec64_to_timespec(attr->ia_mtime); 2065 - ceph_encode_timespec(&req->r_args.setattr.mtime, &ts); 2068 + ceph_encode_timespec64(&req->r_args.setattr.mtime, 2069 + &attr->ia_mtime); 2066 2070 mask |= CEPH_SETATTR_MTIME; 2067 2071 release |= CEPH_CAP_FILE_SHARED | 2068 2072 CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR; ··· 2093 2097 bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME| 2094 2098 ATTR_MODE|ATTR_UID|ATTR_GID)) == 0; 2095 2099 dout("setattr %p ctime %lld.%ld -> %lld.%ld (%s)\n", inode, 2096 - (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, 2097 - (long long)attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec, 2100 + inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, 2101 + attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec, 2098 2102 only ? "ctime only" : "ignored"); 2099 2103 if (only) { 2100 2104 /*
+2 -5
fs/ceph/mds_client.c
··· 2961 2961 rec.v2.flock_len = (__force __le32) 2962 2962 ((ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) ? 0 : 1); 2963 2963 } else { 2964 - struct timespec ts; 2965 2964 rec.v1.cap_id = cpu_to_le64(cap->cap_id); 2966 2965 rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci)); 2967 2966 rec.v1.issued = cpu_to_le32(cap->issued); 2968 2967 rec.v1.size = cpu_to_le64(inode->i_size); 2969 - ts = timespec64_to_timespec(inode->i_mtime); 2970 - ceph_encode_timespec(&rec.v1.mtime, &ts); 2971 - ts = timespec64_to_timespec(inode->i_atime); 2972 - ceph_encode_timespec(&rec.v1.atime, &ts); 2968 + ceph_encode_timespec64(&rec.v1.mtime, &inode->i_mtime); 2969 + ceph_encode_timespec64(&rec.v1.atime, &inode->i_atime); 2973 2970 rec.v1.snaprealm = cpu_to_le64(ci->i_snap_realm->ino); 2974 2971 rec.v1.pathbase = cpu_to_le64(pathbase); 2975 2972 }
+3 -3
fs/ceph/snap.c
··· 594 594 595 595 BUG_ON(capsnap->writing); 596 596 capsnap->size = inode->i_size; 597 - capsnap->mtime = timespec64_to_timespec(inode->i_mtime); 598 - capsnap->atime = timespec64_to_timespec(inode->i_atime); 599 - capsnap->ctime = timespec64_to_timespec(inode->i_ctime); 597 + capsnap->mtime = inode->i_mtime; 598 + capsnap->atime = inode->i_atime; 599 + capsnap->ctime = inode->i_ctime; 600 600 capsnap->time_warp_seq = ci->i_time_warp_seq; 601 601 capsnap->truncate_size = ci->i_truncate_size; 602 602 capsnap->truncate_seq = ci->i_truncate_seq;
+5 -4
fs/ceph/super.h
··· 193 193 u64 xattr_version; 194 194 195 195 u64 size; 196 - struct timespec mtime, atime, ctime; 196 + struct timespec64 mtime, atime, ctime; 197 197 u64 time_warp_seq; 198 198 u64 truncate_size; 199 199 u32 truncate_seq; ··· 307 307 char *i_symlink; 308 308 309 309 /* for dirs */ 310 - struct timespec i_rctime; 310 + struct timespec64 i_rctime; 311 311 u64 i_rbytes, i_rfiles, i_rsubdirs; 312 312 u64 i_files, i_subdirs; 313 313 ··· 857 857 extern int ceph_fill_file_size(struct inode *inode, int issued, 858 858 u32 truncate_seq, u64 truncate_size, u64 size); 859 859 extern void ceph_fill_file_time(struct inode *inode, int issued, 860 - u64 time_warp_seq, struct timespec *ctime, 861 - struct timespec *mtime, struct timespec *atime); 860 + u64 time_warp_seq, struct timespec64 *ctime, 861 + struct timespec64 *mtime, 862 + struct timespec64 *atime); 862 863 extern int ceph_fill_trace(struct super_block *sb, 863 864 struct ceph_mds_request *req); 864 865 extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+2 -2
fs/ceph/xattr.c
··· 224 224 static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, 225 225 size_t size) 226 226 { 227 - return snprintf(val, size, "%ld.09%ld", (long)ci->i_rctime.tv_sec, 228 - (long)ci->i_rctime.tv_nsec); 227 + return snprintf(val, size, "%lld.09%ld", ci->i_rctime.tv_sec, 228 + ci->i_rctime.tv_nsec); 229 229 } 230 230 231 231 /* quotas */