]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Merge pull request #1781 from ceph/wip-8269
authorJosh Durgin <josh.durgin@inktank.com>
Fri, 9 May 2014 21:44:25 +0000 (14:44 -0700)
committerJosh Durgin <josh.durgin@inktank.com>
Fri, 9 May 2014 21:44:25 +0000 (14:44 -0700)
Wip 8269

Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
1  2 
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index a8defd6bb38834807c1017062f8cb029aa5097ce,7fc81cc0d65cc055c873ca7ff224d8848a7ea441..5000c6a6dd8dc15691260e0b047f313f929e014c
@@@ -1556,9 -1521,8 +1570,10 @@@ void RGWPutObj::execute(
    map<string, bufferlist> attrs;
    int len;
    map<string, string>::iterator iter;
+   bool multipart;
  
 +  bool need_calc_md5 = (obj_manifest == NULL);
 +
  
    perfcounter->inc(l_rgw_put);
    ret = -EINVAL;
      if (ret < 0)
        goto done;
  
 -    hash.Update(data_ptr, len);
 +    if (need_calc_md5) {
 +      hash.Update(data_ptr, len);
 +    }
  
-     ret = processor->throttle_data(handle);
-     if (ret < 0)
-       goto done;
+     /* do we need this operation to be synchronous? if we're dealing with an object with immutable
+      * head, e.g., multipart object we need to make sure we're the first one writing to this object
+      */
+     bool need_to_wait = (ofs == 0) && multipart;
+     ret = processor->throttle_data(handle, need_to_wait);
+     if (ret < 0) {
+       if (!need_to_wait || ret != -EEXIST) {
+         ldout(s->cct, 20) << "processor->thottle_data() returned ret=" << ret << dendl;
+         goto done;
+       }
+       ldout(s->cct, 5) << "NOTICE: processor->throttle_data() returned -EEXIST, need to restart write" << dendl;
+       /* restart processing with different oid suffix */
+       dispose_processor(processor);
+       processor = select_processor(&multipart);
+       string oid_rand;
+       char buf[33];
+       gen_rand_alphanumeric(store->ctx(), buf, sizeof(buf) - 1);
+       oid_rand.append(buf);
+       ret = processor->prepare(store, s->obj_ctx, &oid_rand);
+       if (ret < 0) {
+         ldout(s->cct, 0) << "ERROR: processor->prepare() returned " << ret << dendl;
+         goto done;
+       }
+       ret = processor->handle_data(data, ofs, &handle);
+       if (ret < 0) {
+         ldout(s->cct, 0) << "ERROR: processor->handle_data() returned " << ret << dendl;
+         goto done;
+       }
+       ret = processor->throttle_data(handle, false);
+       if (ret < 0) {
+         ldout(s->cct, 0) << "ERROR: processor->throttle_data() returned " << ret << dendl;
+         goto done;
+       }
+     }
  
      ofs += len;
    } while (len > 0);
index ed090e775725e1963417f4eeeb2e3f6c7a29c645,c28485dcf93a605d27495af7cbe094ad0217c311..95a34edc2b943d7d003b52bc8e91cf425283cd65
@@@ -341,11 -340,9 +341,11 @@@ public
      policy.set_ctx(s->cct);
    }
  
-   RGWPutObjProcessor *select_processor();
+   RGWPutObjProcessor *select_processor(bool *is_multipart);
    void dispose_processor(RGWPutObjProcessor *processor);
  
 +  int user_manifest_iterate_cb(rgw_bucket& bucket, RGWObjEnt& ent, RGWAccessControlPolicy *bucket_policy, off_t start_ofs, off_t end_ofs);
 +
    int verify_permission();
    void pre_exec();
    void execute();
index 5a8d09adbe1ccab8a4131643f1e29920bf8b6a0c,d8e278cf64ba7e7ccb427d05e62620ad5996bb0c..761674e5d75849e30f2874e16e266e3adffebddb
@@@ -597,10 -605,12 +605,12 @@@ void RGWObjManifest::obj_iterator::seek
      stripe_size = rule.stripe_max_size;
      stripe_size = MIN(manifest->get_obj_size() - stripe_ofs, stripe_size);
    } else {
 -    stripe_size = rule.part_size - (ofs - stripe_ofs);
 -    stripe_size = MIN(stripe_size, rule.stripe_max_size);
 +    uint64_t next = MIN(stripe_ofs + rule.stripe_max_size, part_ofs + rule.part_size);
 +    stripe_size = next - stripe_ofs;
    }
  
+   cur_override_prefix = rule.override_prefix;
    update_location();
  }
  
index 381682fd6b146a9d7f8f0ad74522a7279a88e9e4,9a8ff69f67baace46782dc1f423e7133ad25977e..9ff5f3d2eaeea99d9a8e65d8d0af7b18266260bb
@@@ -541,9 -545,9 +545,9 @@@ public
      store = _store;
      obj_ctx = _o;
      return 0;
 -  };
 +  }
    virtual int handle_data(bufferlist& bl, off_t ofs, void **phandle) = 0;
-   virtual int throttle_data(void *handle) = 0;
+   virtual int throttle_data(void *handle, bool need_to_wait) = 0;
    virtual int complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs);
  };