}
 
        if (new_mode != old_mode) {
+               newattrs.ia_ctime = current_time(inode);
                newattrs.ia_mode = new_mode;
                newattrs.ia_valid = ATTR_MODE;
                ret = __ceph_setattr(inode, &newattrs);
 
                    attr->ia_size > inode->i_size) {
                        i_size_write(inode, attr->ia_size);
                        inode->i_blocks = calc_inode_blocks(attr->ia_size);
-                       inode->i_ctime = attr->ia_ctime;
                        ci->i_reported_size = attr->ia_size;
                        dirtied |= CEPH_CAP_FILE_EXCL;
                } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
                     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
                     attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
                     only ? "ctime only" : "ignored");
-               inode->i_ctime = attr->ia_ctime;
                if (only) {
                        /*
                         * if kernel wants to dirty ctime but nothing else,
        if (dirtied) {
                inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied,
                                                           &prealloc_cf);
-               inode->i_ctime = current_time(inode);
+               inode->i_ctime = attr->ia_ctime;
        }
 
        release &= issued;
                req->r_inode_drop = release;
                req->r_args.setattr.mask = cpu_to_le32(mask);
                req->r_num_caps = 1;
+               req->r_stamp = attr->ia_ctime;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
        }
        dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,