]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: pre-compute unix attrs in write_finish() 15449/head
authorMatt Benjamin <mbenjamin@redhat.com>
Tue, 18 Apr 2017 13:19:13 +0000 (09:19 -0400)
committerNathan Cutler <ncutler@suse.com>
Sun, 27 Aug 2017 18:48:14 +0000 (20:48 +0200)
New serialized Unix attrs need to reflect the change being made,
and should be reverted if the change fails.

Fixes: http://tracker.ceph.com/issues/19653
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
(cherry picked from commit ed91d23ccaaac4e72a4c28a58e77485395949f04)

Conflicts:
    src/rgw/rgw_file.cc (processor->complete() takes different arguments in
        jewel than in master)

src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index 7d8c49728d26cbc25252fefcc6c78f6127e653a5..142d1b1ed31e87396e16d9f8d5e431ba306fcfb7 100644 (file)
@@ -1264,6 +1264,11 @@ namespace rgw {
     unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
     struct req_state* s = get_state();
 
+    size_t osize = rgw_fh->get_size();
+    struct timespec octime = rgw_fh->get_ctime();
+    struct timespec omtime = rgw_fh->get_mtime();
+    real_time appx_t = real_clock::now();
+
     s->obj_size = ofs; // XXX check ofs
     perfcounter->inc(l_rgw_put_b, s->obj_size);
 
@@ -1285,7 +1290,12 @@ namespace rgw {
     policy.encode(aclbl);
     emplace_attr(RGW_ATTR_ACL, std::move(aclbl));
 
+    /* unix attrs */
+    rgw_fh->set_mtime(real_clock::to_timespec(appx_t));
+    rgw_fh->set_ctime(real_clock::to_timespec(appx_t));
+    rgw_fh->set_size(bytes_written);
     rgw_fh->encode_attrs(ux_key, ux_attrs);
+
     emplace_attr(RGW_ATTR_UNIX_KEY1, std::move(ux_key));
     emplace_attr(RGW_ATTR_UNIX1, std::move(ux_attrs));
 
@@ -1309,12 +1319,13 @@ namespace rgw {
     }
 
     op_ret = processor->complete(etag, &mtime, real_time(), attrs,
-                                (delete_at ? *delete_at : real_time()), if_match, if_nomatch);
-    if (! op_ret) {
-      /* update stats */
-      rgw_fh->set_mtime(real_clock::to_timespec(mtime));
-      rgw_fh->set_ctime(real_clock::to_timespec(mtime));
-      rgw_fh->set_size(bytes_written);
+                                (delete_at ? *delete_at : real_time()),
+                                 if_match, if_nomatch);
+    if (op_ret != 0) {
+      /* revert attr updates */
+      rgw_fh->set_mtime(omtime);
+      rgw_fh->set_ctime(octime);
+      rgw_fh->set_size(osize);
     }
 
   done:
index ff164d7eea8ac952405002c0c791d3ff34f48479..0cfa5b331cb4d0dfb3d9db64b4f65ee78198a016 100644 (file)
@@ -340,6 +340,7 @@ namespace rgw {
     uint32_t get_owner_uid() const { return state.owner_uid; }
     uint32_t get_owner_gid() const { return state.owner_gid; }
 
+    struct timespec get_ctime() const { return state.ctime; }
     struct timespec get_mtime() const { return state.mtime; }
 
     void create_stat(struct stat* st, uint32_t mask) {