gfs2_free_data(ip, bstart, blen);
        }
 
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_dinode_out(ip, dibh->b_data);
 
        }
 
        ip->i_di.di_size = size;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (error)
 
        if (gfs2_is_stuffed(ip)) {
                ip->i_di.di_size = size;
-               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
 
                if (!error) {
                        ip->i_di.di_size = size;
-                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                        ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
                        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                        gfs2_dinode_out(ip, dibh->b_data);
                        ip->i_no_addr;
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
        }
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
 
        memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
        if (ip->i_di.di_size < offset + size)
                ip->i_di.di_size = offset + size;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(ip, dibh->b_data);
 
        brelse(dibh);
 
        if (ip->i_di.di_size < offset + copied)
                ip->i_di.di_size = offset + copied;
-       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
                                break;
                        gfs2_trans_add_bh(ip->i_gl, bh, 1);
                        ip->i_di.di_entries++;
-                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+                       ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
                        gfs2_dinode_out(ip, bh->b_data);
                        brelse(bh);
                        error = 0;
                gfs2_consist_inode(dip);
        gfs2_trans_add_bh(dip->i_gl, bh, 1);
        dip->i_di.di_entries--;
-       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(dip, bh->b_data);
        brelse(bh);
        mark_inode_dirty(&dip->i_inode);
                gfs2_trans_add_bh(dip->i_gl, bh, 1);
        }
 
-       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_dinode_out(dip, bh->b_data);
        brelse(bh);
        return 0;
 
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
                                            (er->er_mode & S_IFMT));
                        ip->i_inode.i_mode = er->er_mode;
                }
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
                        (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
                ip->i_inode.i_mode = er->er_mode;
        }
-       ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_ctime = CURRENT_TIME;
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
        brelse(dibh);
 
        error = gfs2_meta_inode_buffer(ip, &dibh);
        if (!error) {
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
 
        di->di_blocks = be64_to_cpu(str->di_blocks);
        gfs2_set_inode_blocks(&ip->i_inode);
        ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
-       ip->i_inode.i_atime.tv_nsec = 0;
+       ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
        ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
-       ip->i_inode.i_mtime.tv_nsec = 0;
+       ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
        ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
-       ip->i_inode.i_ctime.tv_nsec = 0;
+       ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
 
        di->di_goal_meta = be64_to_cpu(str->di_goal_meta);
        di->di_goal_data = be64_to_cpu(str->di_goal_data);
        else
                drop_nlink(&ip->i_inode);
 
-       ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+       ip->i_inode.i_ctime = CURRENT_TIME;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
        gfs2_dinode_out(ip, dibh->b_data);
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
        struct gfs2_dinode *di;
        struct buffer_head *dibh;
+       struct timespec tv = CURRENT_TIME;
 
        dibh = gfs2_meta_new(gl, inum->no_addr);
        gfs2_trans_add_bh(gl, dibh, 1);
        di->di_nlink = 0;
        di->di_size = 0;
        di->di_blocks = cpu_to_be64(1);
-       di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds());
+       di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
        di->di_major = cpu_to_be32(MAJOR(dev));
        di->di_minor = cpu_to_be32(MINOR(dev));
        di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
        di->di_entries = 0;
        memset(&di->__pad4, 0, sizeof(di->__pad4));
        di->di_eattr = 0;
+       di->di_atime_nsec = cpu_to_be32(tv.tv_nsec);
+       di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
+       di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
        memset(&di->di_reserved, 0, sizeof(di->di_reserved));
 
        brelse(dibh);
        struct gfs2_glock *gl = gh->gh_gl;
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct gfs2_inode *ip = gl->gl_object;
-       s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum);
+       s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
        unsigned int state;
        int flags;
        int error;
+       struct timespec tv = CURRENT_TIME;
 
        if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
            gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
            (sdp->sd_vfs->s_flags & MS_RDONLY))
                return 0;
 
-       curtime = get_seconds();
-       if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
+       if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
                gfs2_glock_dq(gh);
                gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
                                   gh);
                /* Verify that atime hasn't been updated while we were
                   trying to get exclusive lock. */
 
-               curtime = get_seconds();
-               if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
+               tv = CURRENT_TIME;
+               if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
                        struct buffer_head *dibh;
                        struct gfs2_dinode *di;
 
                        if (error)
                                goto fail_end_trans;
 
-                       ip->i_inode.i_atime.tv_sec = curtime;
+                       ip->i_inode.i_atime = tv;
 
                        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                        di = (struct gfs2_dinode *)dibh->b_data;
                        di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
+                       di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
                        brelse(dibh);
 
                        gfs2_trans_end(sdp);
        str->di_entries = cpu_to_be32(di->di_entries);
 
        str->di_eattr = cpu_to_be64(di->di_eattr);
+       str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
+       str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
+       str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
 }
 
 void gfs2_dinode_print(const struct gfs2_inode *ip)
 
        sb->s_magic = GFS2_MAGIC;
        sb->s_op = &gfs2_super_ops;
        sb->s_export_op = &gfs2_export_ops;
+       sb->s_time_gran = 1;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
 
        if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
 
                error = gfs2_meta_inode_buffer(ip, &dibh);
                if (error)
                        goto out_end_trans;
-               ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+               ip->i_inode.i_ctime = CURRENT_TIME;
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
                gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
 
        struct gfs2_inum __pad4; /* Unused even in current gfs1 */
 
        __be64 di_eattr;        /* extended attribute block number */
+       __be32 di_atime_nsec;   /* nsec portion of atime */
+       __be32 di_mtime_nsec;   /* nsec portion of mtime */
+       __be32 di_ctime_nsec;   /* nsec portion of ctime */
 
-       __u8 di_reserved[56];
+       __u8 di_reserved[44];
 };
 
 /*