Commit 4bd91ba18198eee42c39d4c334c825d1a0a4b445

Authored by Steven Whitehouse
1 parent bb8d8a6f54

[GFS2] Add nanosecond timestamp feature

This adds a nanosecond timestamp feature to the GFS2 filesystem. Due
to the way that the on-disk format works, older filesystems will just
appear to have this field set to zero. When mounted by an older version
of GFS2, the filesystem will simply ignore the extra fields so that
it will again appear to have whole second resolution, so that its
trivially backward compatible.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

Showing 7 changed files with 39 additions and 27 deletions Side-by-side Diff

... ... @@ -772,7 +772,7 @@
772 772 gfs2_free_data(ip, bstart, blen);
773 773 }
774 774  
775   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  775 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
776 776  
777 777 gfs2_dinode_out(ip, dibh->b_data);
778 778  
... ... @@ -847,7 +847,7 @@
847 847 }
848 848  
849 849 ip->i_di.di_size = size;
850   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  850 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
851 851  
852 852 error = gfs2_meta_inode_buffer(ip, &dibh);
853 853 if (error)
... ... @@ -958,7 +958,7 @@
958 958  
959 959 if (gfs2_is_stuffed(ip)) {
960 960 ip->i_di.di_size = size;
961   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  961 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
962 962 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
963 963 gfs2_dinode_out(ip, dibh->b_data);
964 964 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
... ... @@ -970,7 +970,7 @@
970 970  
971 971 if (!error) {
972 972 ip->i_di.di_size = size;
973   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  973 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
974 974 ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
975 975 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
976 976 gfs2_dinode_out(ip, dibh->b_data);
... ... @@ -1043,7 +1043,7 @@
1043 1043 ip->i_no_addr;
1044 1044 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
1045 1045 }
1046   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  1046 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1047 1047 ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
1048 1048  
1049 1049 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
... ... @@ -130,7 +130,7 @@
130 130 memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
131 131 if (ip->i_di.di_size < offset + size)
132 132 ip->i_di.di_size = offset + size;
133   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  133 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
134 134 gfs2_dinode_out(ip, dibh->b_data);
135 135  
136 136 brelse(dibh);
... ... @@ -228,7 +228,7 @@
228 228  
229 229 if (ip->i_di.di_size < offset + copied)
230 230 ip->i_di.di_size = offset + copied;
231   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  231 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
232 232  
233 233 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
234 234 gfs2_dinode_out(ip, dibh->b_data);
... ... @@ -1622,7 +1622,7 @@
1622 1622 break;
1623 1623 gfs2_trans_add_bh(ip->i_gl, bh, 1);
1624 1624 ip->i_di.di_entries++;
1625   - ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  1625 + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1626 1626 gfs2_dinode_out(ip, bh->b_data);
1627 1627 brelse(bh);
1628 1628 error = 0;
... ... @@ -1708,7 +1708,7 @@
1708 1708 gfs2_consist_inode(dip);
1709 1709 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1710 1710 dip->i_di.di_entries--;
1711   - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
  1711 + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1712 1712 gfs2_dinode_out(dip, bh->b_data);
1713 1713 brelse(bh);
1714 1714 mark_inode_dirty(&dip->i_inode);
... ... @@ -1756,7 +1756,7 @@
1756 1756 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1757 1757 }
1758 1758  
1759   - dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
  1759 + dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1760 1760 gfs2_dinode_out(dip, bh->b_data);
1761 1761 brelse(bh);
1762 1762 return 0;
... ... @@ -300,7 +300,7 @@
300 300  
301 301 error = gfs2_meta_inode_buffer(ip, &dibh);
302 302 if (!error) {
303   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  303 + ip->i_inode.i_ctime = CURRENT_TIME;
304 304 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
305 305 gfs2_dinode_out(ip, dibh->b_data);
306 306 brelse(dibh);
... ... @@ -717,7 +717,7 @@
717 717 (er->er_mode & S_IFMT));
718 718 ip->i_inode.i_mode = er->er_mode;
719 719 }
720   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  720 + ip->i_inode.i_ctime = CURRENT_TIME;
721 721 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
722 722 gfs2_dinode_out(ip, dibh->b_data);
723 723 brelse(dibh);
... ... @@ -852,7 +852,7 @@
852 852 (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
853 853 ip->i_inode.i_mode = er->er_mode;
854 854 }
855   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  855 + ip->i_inode.i_ctime = CURRENT_TIME;
856 856 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
857 857 gfs2_dinode_out(ip, dibh->b_data);
858 858 brelse(dibh);
... ... @@ -1133,7 +1133,7 @@
1133 1133  
1134 1134 error = gfs2_meta_inode_buffer(ip, &dibh);
1135 1135 if (!error) {
1136   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  1136 + ip->i_inode.i_ctime = CURRENT_TIME;
1137 1137 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1138 1138 gfs2_dinode_out(ip, dibh->b_data);
1139 1139 brelse(dibh);
... ... @@ -178,11 +178,11 @@
178 178 di->di_blocks = be64_to_cpu(str->di_blocks);
179 179 gfs2_set_inode_blocks(&ip->i_inode);
180 180 ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
181   - ip->i_inode.i_atime.tv_nsec = 0;
  181 + ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
182 182 ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
183   - ip->i_inode.i_mtime.tv_nsec = 0;
  183 + ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
184 184 ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
185   - ip->i_inode.i_ctime.tv_nsec = 0;
  185 + ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
186 186  
187 187 di->di_goal_meta = be64_to_cpu(str->di_goal_meta);
188 188 di->di_goal_data = be64_to_cpu(str->di_goal_data);
... ... @@ -317,7 +317,7 @@
317 317 else
318 318 drop_nlink(&ip->i_inode);
319 319  
320   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  320 + ip->i_inode.i_ctime = CURRENT_TIME;
321 321  
322 322 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
323 323 gfs2_dinode_out(ip, dibh->b_data);
... ... @@ -648,6 +648,7 @@
648 648 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
649 649 struct gfs2_dinode *di;
650 650 struct buffer_head *dibh;
  651 + struct timespec tv = CURRENT_TIME;
651 652  
652 653 dibh = gfs2_meta_new(gl, inum->no_addr);
653 654 gfs2_trans_add_bh(gl, dibh, 1);
... ... @@ -663,7 +664,7 @@
663 664 di->di_nlink = 0;
664 665 di->di_size = 0;
665 666 di->di_blocks = cpu_to_be64(1);
666   - di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
  667 + di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
667 668 di->di_major = cpu_to_be32(MAJOR(dev));
668 669 di->di_minor = cpu_to_be32(MINOR(dev));
669 670 di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
... ... @@ -693,6 +694,9 @@
693 694 di->di_entries = 0;
694 695 memset(&di->__pad4, 0, sizeof(di->__pad4));
695 696 di->di_eattr = 0;
  697 + di->di_atime_nsec = cpu_to_be32(tv.tv_nsec);
  698 + di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
  699 + di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
696 700 memset(&di->di_reserved, 0, sizeof(di->di_reserved));
697 701  
698 702 brelse(dibh);
699 703  
... ... @@ -1135,10 +1139,11 @@
1135 1139 struct gfs2_glock *gl = gh->gh_gl;
1136 1140 struct gfs2_sbd *sdp = gl->gl_sbd;
1137 1141 struct gfs2_inode *ip = gl->gl_object;
1138   - s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
  1142 + s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
1139 1143 unsigned int state;
1140 1144 int flags;
1141 1145 int error;
  1146 + struct timespec tv = CURRENT_TIME;
1142 1147  
1143 1148 if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
1144 1149 gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
... ... @@ -1156,8 +1161,7 @@
1156 1161 (sdp->sd_vfs->s_flags & MS_RDONLY))
1157 1162 return 0;
1158 1163  
1159   - curtime = get_seconds();
1160   - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
  1164 + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1161 1165 gfs2_glock_dq(gh);
1162 1166 gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
1163 1167 gh);
... ... @@ -1168,8 +1172,8 @@
1168 1172 /* Verify that atime hasn't been updated while we were
1169 1173 trying to get exclusive lock. */
1170 1174  
1171   - curtime = get_seconds();
1172   - if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
  1175 + tv = CURRENT_TIME;
  1176 + if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1173 1177 struct buffer_head *dibh;
1174 1178 struct gfs2_dinode *di;
1175 1179  
1176 1180  
... ... @@ -1183,11 +1187,12 @@
1183 1187 if (error)
1184 1188 goto fail_end_trans;
1185 1189  
1186   - ip->i_inode.i_atime.tv_sec = curtime;
  1190 + ip->i_inode.i_atime = tv;
1187 1191  
1188 1192 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1189 1193 di = (struct gfs2_dinode *)dibh->b_data;
1190 1194 di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
  1195 + di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
1191 1196 brelse(dibh);
1192 1197  
1193 1198 gfs2_trans_end(sdp);
... ... @@ -1290,6 +1295,9 @@
1290 1295 str->di_entries = cpu_to_be32(di->di_entries);
1291 1296  
1292 1297 str->di_eattr = cpu_to_be64(di->di_eattr);
  1298 + str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
  1299 + str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
  1300 + str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
1293 1301 }
1294 1302  
1295 1303 void gfs2_dinode_print(const struct gfs2_inode *ip)
fs/gfs2/ops_fstype.c
... ... @@ -104,6 +104,7 @@
104 104 sb->s_magic = GFS2_MAGIC;
105 105 sb->s_op = &gfs2_super_ops;
106 106 sb->s_export_op = &gfs2_export_ops;
  107 + sb->s_time_gran = 1;
107 108 sb->s_maxbytes = MAX_LFS_FILESIZE;
108 109  
109 110 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
... ... @@ -757,7 +757,7 @@
757 757 error = gfs2_meta_inode_buffer(ip, &dibh);
758 758 if (error)
759 759 goto out_end_trans;
760   - ip->i_inode.i_ctime = CURRENT_TIME_SEC;
  760 + ip->i_inode.i_ctime = CURRENT_TIME;
761 761 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
762 762 gfs2_dinode_out(ip, dibh->b_data);
763 763 brelse(dibh);
include/linux/gfs2_ondisk.h
... ... @@ -259,8 +259,11 @@
259 259 struct gfs2_inum __pad4; /* Unused even in current gfs1 */
260 260  
261 261 __be64 di_eattr; /* extended attribute block number */
  262 + __be32 di_atime_nsec; /* nsec portion of atime */
  263 + __be32 di_mtime_nsec; /* nsec portion of mtime */
  264 + __be32 di_ctime_nsec; /* nsec portion of ctime */
262 265  
263   - __u8 di_reserved[56];
  266 + __u8 di_reserved[44];
264 267 };
265 268  
266 269 /*