]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: pre-compute unix attrs in write_finish() 14609/head
authorMatt Benjamin <mbenjamin@redhat.com>
Tue, 18 Apr 2017 13:19:13 +0000 (09:19 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Tue, 18 Apr 2017 13:19:13 +0000 (09:19 -0400)
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>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index 15f20ee1eabe9b60738fdbdb90ba6a7098b697ee..be3d356ec41a6461df098c28d68186bde3b0796d 100644 (file)
@@ -1280,6 +1280,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);
 
@@ -1300,7 +1305,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));
 
@@ -1324,12 +1334,13 @@ namespace rgw {
     }
 
     op_ret = processor->complete(s->obj_size, 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 df53d4246aa41bb13c578be18ff16805299d288f..5d964f9c2aa1e8d125c8b8fdb960ac796f7d2836 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) {