]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: clean up system obj interfaces
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 8 Oct 2014 00:07:22 +0000 (17:07 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Mon, 19 Jan 2015 23:57:40 +0000 (15:57 -0800)
Create a new structure to use, RGWRados::SystemObject, similar to the
previous changes made for the data objects.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_tools.cc
src/rgw/rgw_tools.h

index 2a01d21b87b1a62db3270975713fd3fc05a8161b..41ab5a3418e701940e555824575b39c708d65941 100644 (file)
@@ -522,7 +522,8 @@ int bucket_stats(rgw_bucket& bucket, Formatter *formatter)
 {
   RGWBucketInfo bucket_info;
   time_t mtime;
-  int r = store->get_bucket_info(NULL, bucket.name, bucket_info, &mtime);
+  RGWRados::ObjectCtx obj_ctx(store);
+  int r = store->get_bucket_info(obj_ctx, bucket.name, bucket_info, &mtime);
   if (r < 0)
     return r;
 
@@ -564,7 +565,8 @@ public:
 static int init_bucket(string& bucket_name, RGWBucketInfo& bucket_info, rgw_bucket& bucket)
 {
   if (!bucket_name.empty()) {
-    int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL);
+    RGWRados::ObjectCtx obj_ctx(store);
+    int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL);
     if (r < 0) {
       cerr << "could not get bucket info for bucket=" << bucket_name << std::endl;
       return r;
@@ -714,7 +716,8 @@ int set_bucket_quota(RGWRados *store, int opt_cmd, string& bucket_name, int64_t
 {
   RGWBucketInfo bucket_info;
   map<string, bufferlist> attrs;
-  int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL, &attrs);
+  RGWRados::ObjectCtx obj_ctx(store);
+  int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL, &attrs);
   if (r < 0) {
     cerr << "could not get bucket info for bucket=" << bucket_name << ": " << cpp_strerror(-r) << std::endl;
     return -r;
@@ -778,13 +781,15 @@ int check_min_obj_stripe_size(RGWRados *store, rgw_obj& obj, uint64_t min_stripe
 {
   map<string, bufferlist> attrs;
   uint64_t obj_size;
-  void *handle;
 
-  void *obj_ctx = store->create_context(NULL);
-  int ret = store->prepare_get_obj(obj_ctx, obj, NULL, NULL, &attrs, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, &obj_size, NULL, &handle, NULL);
-  store->finish_get_obj(&handle);
-  store->destroy_context(obj_ctx);
+  RGWRados::ObjectCtx obj_ctx(store);
+  RGWRados::Object op_target(store, obj_ctx, obj);
+  RGWRados::Object::Read read_op(&op_target);
+
+  read_op.params.attrs = &attrs;
+  read_op.params.obj_size = &obj_size;
+
+  int ret = read_op.prepare(NULL, NULL);
   if (ret < 0) {
     lderr(store->ctx()) << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << dendl;
     return ret;
@@ -2127,14 +2132,16 @@ next:
     rgw_obj obj(bucket, object);
     obj.set_instance(object_version);
 
-    void *handle;
     uint64_t obj_size;
     map<string, bufferlist> attrs;
-    void *obj_ctx = store->create_context(NULL);
-    ret = store->prepare_get_obj(obj_ctx, obj, NULL, NULL, &attrs, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, &obj_size, NULL, &handle, NULL);
-    store->finish_get_obj(&handle);
-    store->destroy_context(obj_ctx);
+    RGWRados::ObjectCtx obj_ctx(store);
+    RGWRados::Object op_target(store, obj_ctx, obj);
+    RGWRados::Object::Read read_op(&op_target);
+
+    read_op.params.attrs = &attrs;
+    read_op.params.obj_size = &obj_size;
+
+    ret = read_op.prepare(NULL, NULL);
     if (ret < 0) {
       cerr << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << std::endl;
       return 1;
index 13a33f9b58ce28ecf5552d6baf6d8844fd0e22ad..c16830e50dd23a9fbf30d312e41f66153b209806 100644 (file)
@@ -268,10 +268,13 @@ static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map
 static int get_system_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs,
                          uint64_t *obj_size, RGWObjVersionTracker *objv_tracker)
 {
-  void *handle;
-  int ret = store->prepare_get_obj(s->obj_ctx, obj, NULL, NULL, &attrs, NULL,
-                                      NULL, NULL, NULL, NULL, NULL, obj_size, objv_tracker, &handle, &s->err);
-  store->finish_get_obj(&handle);
+  RGWRados::SystemObject src(store, *(RGWRados::ObjectCtx *)s->obj_ctx, obj);
+  RGWRados::SystemObject::Read rop(&src);
+
+  rop.stat_params.attrs = &attrs;
+  rop.stat_params.obj_size = obj_size;
+
+  int ret = rop.stat(objv_tracker);
   return ret;
 }
 
@@ -332,6 +335,7 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
   int ret = 0;
   rgw_obj_key obj;
   RGWUserInfo bucket_owner_info;
+  RGWRados::ObjectCtx& obj_ctx = *(RGWRados::ObjectCtx *)s->obj_ctx;
 
   s->bucket_instance_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "bucket-instance");
 
@@ -349,7 +353,7 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
 
     RGWBucketInfo source_info;
 
-    ret = store->get_bucket_info(s->obj_ctx, copy_source_str, source_info, NULL);
+    ret = store->get_bucket_info(obj_ctx, copy_source_str, source_info, NULL);
     if (ret == 0) {
       string& region = source_info.region;
       s->local_source = store->region.equals(region);
@@ -359,9 +363,9 @@ static int rgw_build_policies(RGWRados *store, struct req_state *s, bool only_bu
   if (!s->bucket_name_str.empty()) {
     s->bucket_exists = true;
     if (s->bucket_instance_id.empty()) {
-      ret = store->get_bucket_info(s->obj_ctx, s->bucket_name_str, s->bucket_info, NULL, &s->bucket_attrs);
+      ret = store->get_bucket_info(obj_ctx, s->bucket_name_str, s->bucket_info, NULL, &s->bucket_attrs);
     } else {
-      ret = store->get_bucket_instance_info(s->obj_ctx, s->bucket_instance_id, s->bucket_info, NULL, &s->bucket_attrs);
+      ret = store->get_bucket_instance_info(obj_ctx, s->bucket_instance_id, s->bucket_info, NULL, &s->bucket_attrs);
     }
     if (ret < 0) {
       if (ret != -ENOENT) {
@@ -792,7 +796,8 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
   if (bucket_name.compare(s->bucket.name) != 0) {
     RGWBucketInfo bucket_info;
     map<string, bufferlist> bucket_attrs;
-    int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL, &bucket_attrs);
+    RGWRados::ObjectCtx obj_ctx(store);
+    int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL, &bucket_attrs);
     if (r < 0) {
       ldout(s->cct, 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
       return r;
@@ -858,7 +863,6 @@ void RGWGetObj::pre_exec()
 
 void RGWGetObj::execute()
 {
-  void *handle = NULL;
   utime_t start_time = s->time;
   bufferlist bl;
   gc_invalidate_time = ceph_clock_now(s->cct);
@@ -926,11 +930,8 @@ void RGWGetObj::execute()
     goto done_err;
   }
 
-  store->finish_get_obj(&handle);
-
 done_err:
   send_response_data(bl, 0, 0);
-  store->finish_get_obj(&handle);
 }
 
 int RGWGetObj::init_common()
@@ -1281,7 +1282,8 @@ void RGWCreateBucket::execute()
   }
 
   /* we need to make sure we read bucket info, it's not read before for this specific request */
-  ret = store->get_bucket_info(s->obj_ctx, s->bucket_name_str, s->bucket_info, NULL, &s->bucket_attrs);
+  RGWRados::ObjectCtx& obj_ctx = *(RGWRados::ObjectCtx *)s->obj_ctx;
+  ret = store->get_bucket_info(obj_ctx, s->bucket_name_str, s->bucket_info, NULL, &s->bucket_attrs);
   if (ret < 0 && ret != -ENOENT)
     return;
   s->bucket_exists = (ret != -ENOENT);
@@ -2140,7 +2142,9 @@ int RGWCopyObj::verify_permission()
 
   map<string, bufferlist> src_attrs;
 
-  ret = store->get_bucket_info(s->obj_ctx, src_bucket_name, src_bucket_info, NULL, &src_attrs);
+  RGWRados::ObjectCtx& obj_ctx = *(RGWRados::ObjectCtx *)s->obj_ctx;
+
+  ret = store->get_bucket_info(obj_ctx, src_bucket_name, src_bucket_info, NULL, &src_attrs);
   if (ret < 0)
     return ret;
 
@@ -2168,7 +2172,7 @@ int RGWCopyObj::verify_permission()
   if (src_bucket_name.compare(dest_bucket_name) == 0) { /* will only happen if s->local_source */
     dest_bucket_info = src_bucket_info;
   } else {
-    ret = store->get_bucket_info(s->obj_ctx, dest_bucket_name, dest_bucket_info, NULL, &dest_attrs);
+    ret = store->get_bucket_info(obj_ctx, dest_bucket_name, dest_bucket_info, NULL, &dest_attrs);
     if (ret < 0)
       return ret;
   }
index 67372bdf3bc623765c4f6edc840919704fd438fd..9e19cede26670f318c5576884e95ca2a3467d81f 100644 (file)
@@ -116,7 +116,8 @@ int RGWRegion::read_default(RGWDefaultRegionInfo& default_info)
 
   rgw_bucket pool(pool_name.c_str());
   bufferlist bl;
-  ret = rgw_get_system_obj(store, NULL, pool, oid, bl, NULL, NULL);
+  RGWRados::ObjectCtx obj_ctx(store);
+  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
   if (ret < 0)
     return ret;
 
@@ -214,7 +215,8 @@ int RGWRegion::read_info(const string& region_name)
 
   string oid = region_info_oid_prefix + name;
 
-  ret = rgw_get_system_obj(store, NULL, pool, oid, bl, NULL, NULL);
+  RGWRados::ObjectCtx obj_ctx(store);
+  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
   if (ret < 0) {
     lderr(cct) << "failed reading region info from " << pool << ":" << oid << ": " << cpp_strerror(-ret) << dendl;
     return ret;
@@ -357,7 +359,8 @@ int RGWZoneParams::init(CephContext *cct, RGWRados *store, RGWRegion& region)
   bufferlist bl;
 
   string oid = zone_info_oid_prefix + name;
-  ret = rgw_get_system_obj(store, NULL, pool, oid, bl, NULL, NULL);
+  RGWRados::ObjectCtx obj_ctx(store);
+  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
   if (ret < 0)
     return ret;
 
@@ -444,7 +447,8 @@ int RGWRegionMap::read(CephContext *cct, RGWRados *store)
   rgw_bucket pool(pool_name.c_str());
 
   bufferlist bl;
-  int ret = rgw_get_system_obj(store, NULL, pool, oid, bl, NULL, NULL);
+  RGWRados::ObjectCtx obj_ctx(store);
+  int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
   if (ret < 0)
     return ret;
 
@@ -2447,7 +2451,8 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
     if (ret == -EEXIST) {
        /* we need to reread the info and return it, caller will have a use for it */
       info.objv_tracker.clear();
-      r = get_bucket_info(NULL, bucket.name, info, NULL, NULL);
+      ObjectCtx obj_ctx(this);
+      r = get_bucket_info(obj_ctx, bucket.name, info, NULL, NULL);
       if (r < 0) {
         if (r == -ENOENT) {
           continue;
@@ -2590,7 +2595,8 @@ int RGWRados::select_legacy_bucket_placement(const string& bucket_name, rgw_buck
 
   rgw_obj obj(zone.domain_root, avail_pools);
 
-  int ret = rgw_get_system_obj(this, NULL, zone.domain_root, avail_pools, map_bl, NULL, NULL);
+  RGWRados::ObjectCtx obj_ctx(this);
+  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, avail_pools, map_bl, NULL, NULL);
   if (ret < 0) {
     goto read_omap;
   }
@@ -3699,7 +3705,8 @@ int RGWRados::set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner)
 {
   RGWBucketInfo info;
   map<string, bufferlist> attrs;
-  int r = get_bucket_info(NULL, bucket.name, info, NULL, &attrs);
+  ObjectCtx obj_ctx(this);
+  int r = get_bucket_info(obj_ctx, bucket.name, info, NULL, &attrs);
   if (r < 0) {
     ldout(cct, 0) << "NOTICE: get_bucket_info on bucket=" << bucket.name << " returned err=" << r << dendl;
     return r;
@@ -3732,7 +3739,8 @@ int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
 
     RGWBucketInfo info;
     map<string, bufferlist> attrs;
-    int r = get_bucket_info(NULL, bucket.name, info, NULL, &attrs);
+    ObjectCtx obj_ctx(this);
+    int r = get_bucket_info(obj_ctx, bucket.name, info, NULL, &attrs);
     if (r < 0) {
       ldout(cct, 0) << "NOTICE: get_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
       ret = r;
@@ -3757,7 +3765,8 @@ int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
 int RGWRados::bucket_suspended(rgw_bucket& bucket, bool *suspended)
 {
   RGWBucketInfo bucket_info;
-  int ret = get_bucket_info(NULL, bucket.name, bucket_info, NULL);
+  ObjectCtx obj_ctx(this);
+  int ret = get_bucket_info(obj_ctx, bucket.name, bucket_info, NULL);
   if (ret < 0) {
     return ret;
   }
@@ -4586,177 +4595,54 @@ int RGWRados::Object::Read::prepare(int64_t *pofs, int64_t *pend)
   return 0;
 }
 
-/**
- * Get data about an object out of RADOS and into memory.
- * bucket: name of the bucket the object is in.
- * obj: name/key of the object to read
- * data: if get_data==true, this pointer will be set
- *    to an address containing the object's data/value
- * ofs: the offset of the object to read from
- * end: the point in the object to stop reading
- * attrs: if non-NULL, the pointed-to map will contain
- *    all the attrs of the object when this function returns
- * mod_ptr: if non-NULL, compares the object's mtime to *mod_ptr,
- *    and if mtime is smaller it fails.
- * unmod_ptr: if non-NULL, compares the object's mtime to *unmod_ptr,
- *    and if mtime is >= it fails.
- * if_match/nomatch: if non-NULL, compares the object's etag attr
- *    to the string and, if it doesn't/does match, fails out.
- * get_data: if true, the object's data/value will be read out, otherwise not
- * err: Many errors will result in this structure being filled
- *    with extra informatin on the error.
- * Returns: -ERR# on failure, otherwise
- *          (if get_data==true) length of read data,
- *          (if get_data==false) length of the object
- */
-int RGWRados::prepare_get_obj(void *ctx, rgw_obj& obj,
-            off_t *pofs, off_t *pend,
-            map<string, bufferlist> *attrs,
-            const time_t *mod_ptr,
-            const time_t *unmod_ptr,
-            time_t *lastmod,
-            const char *if_match,
-            const char *if_nomatch,
-            uint64_t *total_size,
-            uint64_t *obj_size,
-            RGWObjVersionTracker *objv_tracker,
-            void **handle,
-            struct rgw_err *err)
+int RGWRados::SystemObject::get_state(RGWObjState **pstate, RGWObjVersionTracker *objv_tracker)
 {
-  bufferlist etag;
-  time_t ctime;
-  ObjectCtx *rctx = static_cast<ObjectCtx *>(ctx);
-  ObjectCtx *new_ctx = NULL;
-  RGWObjState *astate = NULL;
-  off_t ofs = 0;
-  off_t end = -1;
-
-  map<string, bufferlist>::iterator iter;
-
-  *handle = NULL;
-
-  GetObjState *state = new GetObjState;
-  if (!state)
-    return -ENOMEM;
-
-  *handle = state;
-
-  int r = get_obj_ioctx(obj, &state->io_ctx);
-  if (r < 0) {
-    delete state;
-    return r;
-  }
+  return store->get_obj_state(&ctx, obj, pstate, objv_tracker, false);
+}
 
-  if (!rctx) {
-    new_ctx = new ObjectCtx(this);
-    rctx = new_ctx;
-  }
+int RGWRados::stat_system_obj(RGWRados::ObjectCtx& obj_ctx,
+                              RGWRados::SystemObject::Read::GetObjState& state,
+                              rgw_obj& obj,
+                              map<string, bufferlist> *attrs,
+                              time_t *lastmod,
+                              uint64_t *obj_size,
+                              RGWObjVersionTracker *objv_tracker)
+{
+  RGWObjState *astate = NULL;
 
-  r = get_obj_state(rctx, obj, &astate, objv_tracker);
+  int r = get_obj_state(&obj_ctx, obj, &astate, objv_tracker);
   if (r < 0)
-    goto done_err;
+    return r;
 
   if (!astate->exists) {
-    r = -ENOENT;
-    goto done_err;
+    return -ENOENT;
   }
 
   if (attrs) {
     *attrs = astate->attrset;
     if (cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+      map<string, bufferlist>::iterator iter;
       for (iter = attrs->begin(); iter != attrs->end(); ++iter) {
         ldout(cct, 20) << "Read xattr: " << iter->first << dendl;
       }
     }
   }
 
-  /* Convert all times go GMT to make them compatible */
-  if (mod_ptr || unmod_ptr) {
-    ctime = astate->mtime;
-
-    if (mod_ptr) {
-      ldout(cct, 10) << "If-Modified-Since: " << *mod_ptr << " Last-Modified: " << ctime << dendl;
-      if (ctime <= *mod_ptr) {
-        r = -ERR_NOT_MODIFIED;
-        goto done_err;
-      }
-    }
-
-    if (unmod_ptr) {
-      ldout(cct, 10) << "If-UnModified-Since: " << *unmod_ptr << " Last-Modified: " << ctime << dendl;
-      if (ctime > *unmod_ptr) {
-        r = -ERR_PRECONDITION_FAILED;
-        goto done_err;
-      }
-    }
-  }
-  if (if_match || if_nomatch) {
-    r = get_attr(*rctx, obj, RGW_ATTR_ETAG, etag);
-    if (r < 0)
-      goto done_err;
-
-    if (if_match) {
-      string if_match_str = rgw_string_unquote(if_match);
-      ldout(cct, 10) << "ETag: " << etag.c_str() << " " << " If-Match: " << if_match_str << dendl;
-      if (if_match_str.compare(etag.c_str()) != 0) {
-        r = -ERR_PRECONDITION_FAILED;
-        goto done_err;
-      }
-    }
-
-    if (if_nomatch) {
-      string if_nomatch_str = rgw_string_unquote(if_nomatch);
-      ldout(cct, 10) << "ETag: " << etag.c_str() << " " << " If-NoMatch: " << if_nomatch_str << dendl;
-      if (if_nomatch_str.compare(etag.c_str()) == 0) {
-        r = -ERR_NOT_MODIFIED;
-        goto done_err;
-      }
-    }
-  }
-
-  if (pofs)
-    ofs = *pofs;
-  if (pend)
-    end = *pend;
-
-  if (ofs < 0) {
-    ofs += astate->size;
-    if (ofs < 0)
-      ofs = 0;
-    end = astate->size - 1;
-  } else if (end < 0) {
-    end = astate->size - 1;
-  }
-
-  if (astate->size > 0) {
-    if (ofs >= (off_t)astate->size) {
-      r = -ERANGE;
-      goto done_err;
-    }
-    if (end >= (off_t)astate->size) {
-      end = astate->size - 1;
-    }
-  }
-
-  if (pofs)
-    *pofs = ofs;
-  if (pend)
-    *pend = end;
-  if (total_size)
-    *total_size = (ofs <= end ? end + 1 - ofs : 0);
   if (obj_size)
     *obj_size = astate->size;
   if (lastmod)
     *lastmod = astate->mtime;
 
-  delete new_ctx;
-
   return 0;
+}
 
-done_err:
-  delete new_ctx;
-  finish_get_obj(handle);
-  return r;
+int RGWRados::SystemObject::Read::stat(RGWObjVersionTracker *objv_tracker)
+{
+  RGWRados *store = source->get_store();
+  rgw_obj& obj = source->get_obj();
+
+  return store->stat_system_obj(source->get_ctx(), state, obj, stat_params.attrs,
+                                stat_params.lastmod, stat_params.obj_size, objv_tracker);
 }
 
 int RGWRados::Bucket::UpdateIndex::prepare(RGWModifyOp op)
@@ -4922,125 +4808,81 @@ int RGWRados::Object::Read::read(int64_t ofs, int64_t end, bufferlist& bl)
   return 0;
 }
 
-int RGWRados::get_obj(void *ctx, RGWObjVersionTracker *objv_tracker, void **handle, rgw_obj& obj,
-                      bufferlist& bl, off_t ofs, off_t end, rgw_cache_entry_info *cache_info)
+int RGWRados::SystemObject::Read::GetObjState::get_ioctx(RGWRados *store, rgw_obj& obj, librados::IoCtx **ioctx)
+{
+  if (!has_ioctx) {
+    int r = store->get_obj_ioctx(obj, &io_ctx);
+    if (r < 0) {
+      return r;
+    }
+    has_ioctx = true;
+  }
+  *ioctx = &io_ctx;
+  return 0;
+
+}
+
+int RGWRados::get_system_obj(ObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
+                             RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
+                             bufferlist& bl, off_t ofs, off_t end,
+                             rgw_cache_entry_info *cache_info)
 {
   rgw_bucket bucket;
   std::string oid, key;
-  rgw_obj read_obj = obj;
-  uint64_t read_ofs = ofs;
-  uint64_t len, read_len;
-  ObjectCtx *rctx = static_cast<ObjectCtx *>(ctx);
-  ObjectCtx *new_ctx = NULL;
-  bool reading_from_head = true;
+  uint64_t len;
   ObjectReadOperation op;
 
-  GetObjState *state = *(GetObjState **)handle;
   RGWObjState *astate = NULL;
 
-  bool merge_bl = false;
-  bufferlist *pbl = &bl;
-  bufferlist read_bl;
-  uint64_t max_chunk_size;
-
-
   get_obj_bucket_and_oid_loc(obj, bucket, oid, key);
 
-  if (!rctx) {
-    new_ctx = new ObjectCtx(this);
-    rctx = new_ctx;
-  }
-
-  int r = get_obj_state(rctx, obj, &astate, NULL);
+  int r = get_obj_state(&obj_ctx, obj, &astate, NULL);
   if (r < 0)
-    goto done_ret;
+    return r;
 
   if (end < 0)
     len = 0;
   else
     len = end - ofs + 1;
 
-  if (astate->has_manifest && astate->manifest.has_tail()) {
-    /* now get the relevant object part */
-    RGWObjManifest::obj_iterator iter = astate->manifest.obj_find(ofs);
+  if (objv_tracker) {
+    objv_tracker->prepare_op_for_read(&op);
+  }
 
-    uint64_t stripe_ofs = iter.get_stripe_ofs();
-    read_obj = iter.get_location();
-    len = min(len, iter.get_stripe_size() - (ofs - stripe_ofs));
-    read_ofs = iter.location_ofs() + (ofs - stripe_ofs);
-    reading_from_head = (read_obj == obj);
+  ldout(cct, 20) << "rados->read ofs=" << ofs << " len=" << len << dendl;
+  op.read(ofs, len, &bl, NULL);
 
-    if (!reading_from_head) {
-      get_obj_bucket_and_oid_loc(read_obj, bucket, oid, key);
-    }
+  librados::IoCtx *io_ctx;
+  r = read_state.get_ioctx(this, obj, &io_ctx);
+  if (r < 0) {
+    ldout(cct, 20) << "get_ioctx() on obj=" << obj << " returned " << r << dendl;
+    return r;
   }
-
-  r = get_max_chunk_size(bucket, &max_chunk_size);
+  r = io_ctx->operate(oid, &op, NULL);
   if (r < 0) {
-    ldout(cct, 0) << "ERROR: failed to get max_chunk_size() for bucket " << bucket << dendl;
-    goto done_ret;
+    ldout(cct, 20) << "rados->read r=" << r << " bl.length=" << bl.length() << dendl;
+    return r;
   }
 
-  if (len > max_chunk_size)
-    len = max_chunk_size;
-
-
-  state->io_ctx.locator_set_key(key);
-
-  read_len = len;
-
-  if (reading_from_head) {
-    /* only when reading from the head object do we need to do the atomic test */
-    r = append_atomic_test(rctx, read_obj, op, &astate);
-    if (r < 0)
-      goto done_ret;
-
-    if (astate && astate->prefetch_data) {
-      if (!ofs && astate->data.length() >= len) {
-        bl = astate->data;
-        goto done;
-      }
-
-      if (ofs < astate->data.length()) {
-        unsigned copy_len = min((uint64_t)astate->data.length() - ofs, len);
-        astate->data.copy(ofs, copy_len, bl);
-        read_len -= copy_len;
-        read_ofs += copy_len;
-        if (!read_len)
-         goto done;
-
-        merge_bl = true;
-        pbl = &read_bl;
-      }
-    }
-  }
+  uint64_t op_ver = io_ctx->get_last_version();
 
-  if (objv_tracker) {
-    objv_tracker->prepare_op_for_read(&op);
+  if (read_state.last_ver > 0 &&
+      read_state.last_ver != op_ver) {
+    ldout(cct, 5) << "raced with an object write, abort" << dendl;
+    return -ECANCELED;
   }
 
+  read_state.last_ver = op_ver;
 
-  ldout(cct, 20) << "rados->read obj-ofs=" << ofs << " read_ofs=" << read_ofs << " read_len=" << read_len << dendl;
-  op.read(read_ofs, read_len, pbl, NULL);
-
-  r = state->io_ctx.operate(oid, &op, NULL);
-  ldout(cct, 20) << "rados->read r=" << r << " bl.length=" << bl.length() << dendl;
-
-  if (merge_bl)
-    bl.append(read_bl);
-
-done:
-  if (r >= 0) {
-    r = bl.length();
-  }
-  if (r < 0 || !len || ((off_t)(ofs + len - 1) == end)) {
-    finish_get_obj(handle);
-  }
+  return bl.length();
+}
 
-done_ret:
-  delete new_ctx;
+int RGWRados::SystemObject::Read::read(int64_t ofs, int64_t end, bufferlist& bl, RGWObjVersionTracker *objv_tracker)
+{
+  RGWRados *store = source->get_store();
+  rgw_obj& obj = source->get_obj();
 
-  return r;
+  return store->get_system_obj(source->get_ctx(), state, objv_tracker, obj, bl, ofs, end, read_params.cache_info);
 }
 
 struct get_obj_data;
@@ -5429,16 +5271,6 @@ done:
   return r;
 }
 
-void RGWRados::finish_get_obj(void **handle)
-{
-#warning remove me
-  if (*handle) {
-    GetObjState *state = *(GetObjState **)handle;
-    delete state;
-    *handle = NULL;
-  }
-}
-
 int RGWRados::iterate_obj(void *ctx, rgw_obj& obj,
                           off_t ofs, off_t end,
                          uint64_t max_chunk_size,
@@ -6153,7 +5985,7 @@ void RGWRados::get_bucket_instance_obj(rgw_bucket& bucket, rgw_obj& obj)
   }
 }
 
-int RGWRados::get_bucket_instance_info(void *ctx, const string& meta_key, RGWBucketInfo& info,
+int RGWRados::get_bucket_instance_info(ObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info,
                                        time_t *pmtime, map<string, bufferlist> *pattrs)
 {
   int pos = meta_key.find(':');
@@ -6162,10 +5994,10 @@ int RGWRados::get_bucket_instance_info(void *ctx, const string& meta_key, RGWBuc
   }
   string oid = RGW_BUCKET_INSTANCE_MD_PREFIX + meta_key;
 
-  return get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
+  return get_bucket_instance_from_oid(obj_ctx, oid, info, pmtime, pattrs);
 }
 
-int RGWRados::get_bucket_instance_info(void *ctx, rgw_bucket& bucket, RGWBucketInfo& info,
+int RGWRados::get_bucket_instance_info(ObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info,
                                        time_t *pmtime, map<string, bufferlist> *pattrs)
 {
   string oid;
@@ -6175,10 +6007,10 @@ int RGWRados::get_bucket_instance_info(void *ctx, rgw_bucket& bucket, RGWBucketI
     oid = bucket.oid;
   }
 
-  return get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
+  return get_bucket_instance_from_oid(obj_ctx, oid, info, pmtime, pattrs);
 }
 
-int RGWRados::get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info,
+int RGWRados::get_bucket_instance_from_oid(ObjectCtx& obj_ctx, string& oid, RGWBucketInfo& info,
                                            time_t *pmtime, map<string, bufferlist> *pattrs,
                                            rgw_cache_entry_info *cache_info)
 {
@@ -6186,7 +6018,7 @@ int RGWRados::get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo
 
   bufferlist epbl;
 
-  int ret = rgw_get_system_obj(this, ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs, cache_info);
+  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs, cache_info);
   if (ret < 0) {
     return ret;
   }
@@ -6202,7 +6034,7 @@ int RGWRados::get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo
   return 0;
 }
 
-int RGWRados::get_bucket_entrypoint_info(void *ctx, const string& bucket_name,
+int RGWRados::get_bucket_entrypoint_info(ObjectCtx& obj_ctx, const string& bucket_name,
                                          RGWBucketEntryPoint& entry_point,
                                          RGWObjVersionTracker *objv_tracker,
                                          time_t *pmtime,
@@ -6211,7 +6043,7 @@ int RGWRados::get_bucket_entrypoint_info(void *ctx, const string& bucket_name,
 {
   bufferlist bl;
 
-  int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, objv_tracker, pmtime, pattrs, cache_info);
+  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, bucket_name, bl, objv_tracker, pmtime, pattrs, cache_info);
   if (ret < 0) {
     return ret;
   }
@@ -6226,7 +6058,7 @@ int RGWRados::get_bucket_entrypoint_info(void *ctx, const string& bucket_name,
   return 0;
 }
 
-int RGWRados::convert_old_bucket_info(void *ctx, string& bucket_name)
+int RGWRados::convert_old_bucket_info(ObjectCtx& obj_ctx, string& bucket_name)
 {
   RGWBucketEntryPoint entry_point;
   time_t ep_mtime;
@@ -6236,7 +6068,7 @@ int RGWRados::convert_old_bucket_info(void *ctx, string& bucket_name)
 
   ldout(cct, 10) << "RGWRados::convert_old_bucket_info(): bucket=" << bucket_name << dendl;
 
-  int ret = get_bucket_entrypoint_info(ctx, bucket_name, entry_point, &ot, &ep_mtime, &attrs);
+  int ret = get_bucket_entrypoint_info(obj_ctx, bucket_name, entry_point, &ot, &ep_mtime, &attrs);
   if (ret < 0) {
     ldout(cct, 0) << "ERROR: get_bucket_entrypont_info() returned " << ret << " bucket=" << bucket_name << dendl;
     return ret;
@@ -6269,7 +6101,7 @@ struct bucket_info_entry {
 
 static RGWChainedCacheImpl<bucket_info_entry> binfo_cache;
 
-int RGWRados::get_bucket_info(void *ctx, const string& bucket_name, RGWBucketInfo& info,
+int RGWRados::get_bucket_info(ObjectCtx& obj_ctx, const string& bucket_name, RGWBucketInfo& info,
                               time_t *pmtime, map<string, bufferlist> *pattrs)
 {
   bucket_info_entry e;
@@ -6288,7 +6120,7 @@ int RGWRados::get_bucket_info(void *ctx, const string& bucket_name, RGWBucketInf
   time_t ep_mtime;
   RGWObjVersionTracker ot;
   rgw_cache_entry_info entry_cache_info;
-  int ret = get_bucket_entrypoint_info(ctx, bucket_name, entry_point, &ot, &ep_mtime, pattrs, &entry_cache_info);
+  int ret = get_bucket_entrypoint_info(obj_ctx, bucket_name, entry_point, &ot, &ep_mtime, pattrs, &entry_cache_info);
   if (ret < 0) {
     info.bucket.name = bucket_name; /* only init this field */
     return ret;
@@ -6321,7 +6153,7 @@ int RGWRados::get_bucket_info(void *ctx, const string& bucket_name, RGWBucketInf
 
   rgw_cache_entry_info cache_info;
 
-  ret = get_bucket_instance_from_oid(ctx, oid, e.info, &e.mtime, &e.attrs, &cache_info);
+  ret = get_bucket_instance_from_oid(obj_ctx, oid, e.info, &e.mtime, &e.attrs, &cache_info);
   e.info.ep_objv = ot.read_version;
   info = e.info;
   if (ret < 0) {
index cf87c2ceacbbd08f3a078b902b7ada8a00c8dad1..5973bb924bf7622eafd6b5fbbc68069b7b916d58 100644 (file)
@@ -1346,14 +1346,56 @@ public:
   virtual int list_placement_set(set<string>& names);
   virtual int create_pools(vector<string>& names, vector<int>& retcodes);
 
-  struct GetObjState {
-#warning remove me
-    librados::IoCtx io_ctx;
-    bool sent_data;
+  class SystemObject {
+    RGWRados *store;
+    RGWRados::ObjectCtx& ctx;
+    rgw_obj obj;
+
+    RGWObjState *state;
+
+  protected:
+    int get_state(RGWObjState **pstate, RGWObjVersionTracker *objv_tracker);
+
+  public:
+    SystemObject(RGWRados *_store, RGWRados::ObjectCtx& _ctx, rgw_obj& _obj) : store(_store), ctx(_ctx), obj(_obj), state(NULL) {}
+
+    RGWRados *get_store() { return store; }
+    rgw_obj& get_obj() { return obj; }
+    RGWRados::ObjectCtx& get_ctx() { return ctx; }
+
+    struct Read {
+      RGWRados::SystemObject *source;
+
+      struct GetObjState {
+        librados::IoCtx io_ctx;
+        bool has_ioctx;
+        uint64_t last_ver;
+
+        GetObjState() : has_ioctx(false), last_ver(0) {}
 
-    GetObjState() : sent_data(false) {}
-  } state;
+        int get_ioctx(RGWRados *store, rgw_obj& obj, librados::IoCtx **ioctx);
+      } state;
       
+      struct StatParams {
+        time_t *lastmod;
+        uint64_t *obj_size;
+        map<string, bufferlist> *attrs;
+        struct rgw_err *perr;
+
+        StatParams() : lastmod(NULL), obj_size(NULL), attrs(NULL) {}
+      } stat_params;
+
+      struct ReadParams {
+        rgw_cache_entry_info *cache_info;
+      } read_params;
+
+      Read(RGWRados::SystemObject *_source) : source(_source) {}
+
+      int stat(RGWObjVersionTracker *objv_tracker);
+      int read(int64_t ofs, int64_t end, bufferlist& bl, RGWObjVersionTracker *objv_tracker);
+    };
+  };
+
   class Object {
     RGWRados *store;
     RGWRados::ObjectCtx& ctx;
@@ -1607,46 +1649,19 @@ public:
   int get_obj_state(ObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker) {
     return get_obj_state(rctx, obj, state, objv_tracker, true);
   }
-/**
- * Get data about an object out of RADOS and into memory.
- * bucket: name of the bucket the object is in.
- * obj: name/key of the object to read
- * data: if get_data==true, this pointer will be set
- *    to an address containing the object's data/value
- * ofs: the offset of the object to read from
- * end: the point in the object to stop reading
- * attrs: if non-NULL, the pointed-to map will contain
- *    all the attrs of the object when this function returns
- * mod_ptr: if non-NULL, compares the object's mtime to *mod_ptr,
- *    and if mtime is smaller it fails.
- * unmod_ptr: if non-NULL, compares the object's mtime to *unmod_ptr,
- *    and if mtime is >= it fails.
- * if_match/nomatch: if non-NULL, compares the object's etag attr
- *    to the string and, if it doesn't/does match, fails out.
- * err: Many errors will result in this structure being filled
- *    with extra informatin on the error.
- * Returns: -ERR# on failure, otherwise
- *          (if get_data==true) length of read data,
- *          (if get_data==false) length of the object
- */
-  virtual int prepare_get_obj(void *ctx, rgw_obj& obj,
-            off_t *ofs, off_t *end,
-            map<string, bufferlist> *attrs,
-            const time_t *mod_ptr,
-            const time_t *unmod_ptr,
-            time_t *lastmod,
-            const char *if_match,
-            const char *if_nomatch,
-            uint64_t *total_size,
-            uint64_t *obj_size,
-            RGWObjVersionTracker *objv_tracker,
-            void **handle,
-            struct rgw_err *err);
-
-  virtual int get_obj(void *ctx, RGWObjVersionTracker *objv_tracker, void **handle, rgw_obj& obj,
-                      bufferlist& bl, off_t ofs, off_t end, rgw_cache_entry_info *cache_info);
-
-  virtual void finish_get_obj(void **handle);
+
+  virtual int stat_system_obj(RGWRados::ObjectCtx& obj_ctx,
+                              RGWRados::SystemObject::Read::GetObjState& state,
+                              rgw_obj& obj,
+                              map<string, bufferlist> *attrs,
+                              time_t *lastmod,
+                              uint64_t *obj_size,
+                              RGWObjVersionTracker *objv_tracker);
+
+  virtual int get_system_obj(ObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
+                             RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
+                             bufferlist& bl, off_t ofs, off_t end,
+                             rgw_cache_entry_info *cache_info);
 
   virtual bool chain_cache_entry(list<rgw_cache_entry_info *>& cache_info_entries, RGWChainedCache::Entry *chained_entry) { return false; }
 
@@ -1750,15 +1765,15 @@ public:
   int put_bucket_entrypoint_info(const string& bucket_name, RGWBucketEntryPoint& entry_point, bool exclusive, RGWObjVersionTracker& objv_tracker, time_t mtime,
                                  map<string, bufferlist> *pattrs);
   int put_bucket_instance_info(RGWBucketInfo& info, bool exclusive, time_t mtime, map<string, bufferlist> *pattrs);
-  int get_bucket_entrypoint_info(void *ctx, const string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime,
+  int get_bucket_entrypoint_info(ObjectCtx& obj_ctx, const string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime,
                                  map<string, bufferlist> *pattrs, rgw_cache_entry_info *cache_info = NULL);
-  int get_bucket_instance_info(void *ctx, const string& meta_key, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
-  int get_bucket_instance_info(void *ctx, rgw_bucket& bucket, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
-  int get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs,
+  int get_bucket_instance_info(ObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+  int get_bucket_instance_info(ObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+  int get_bucket_instance_from_oid(ObjectCtx& obj_ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs,
                                    rgw_cache_entry_info *cache_info = NULL);
 
-  int convert_old_bucket_info(void *ctx, string& bucket_name);
-  virtual int get_bucket_info(void *ctx, const string& bucket_name, RGWBucketInfo& info,
+  int convert_old_bucket_info(ObjectCtx& obj_ctx, string& bucket_name);
+  virtual int get_bucket_info(ObjectCtx& obj_ctx, const string& bucket_name, RGWBucketInfo& info,
                               time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
   virtual int put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, time_t mtime, obj_version *pep_objv,
                                      map<string, bufferlist> *pattrs, bool create_entry_point);
index 158bb796b5a64e05427c55ab1d11fe6ebc400971..90c8a07a57e66b0f25cf644eaa655aa4f65e1596 100644 (file)
@@ -37,25 +37,34 @@ int rgw_put_system_obj(RGWRados *rgwstore, rgw_bucket& bucket, string& oid, cons
   return ret;
 }
 
-int rgw_get_system_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
+int rgw_get_system_obj(RGWRados *rgwstore, RGWRados::ObjectCtx& obj_ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
                        RGWObjVersionTracker *objv_tracker, time_t *pmtime, map<string, bufferlist> *pattrs,
                        rgw_cache_entry_info *cache_info)
 {
   struct rgw_err err;
-  void *handle = NULL;
   bufferlist::iterator iter;
   int request_len = READ_CHUNK_LEN;
   rgw_obj obj(bucket, key);
 
   do {
-    int ret = rgwstore->prepare_get_obj(ctx, obj, NULL, NULL, pattrs, NULL,
-                                        NULL, pmtime, NULL, NULL, NULL, NULL,
-                                        objv_tracker, &handle, &err);
+    RGWRados::SystemObject source(rgwstore, obj_ctx, obj);
+    RGWRados::SystemObject::Read rop(&source);
+
+    rop.stat_params.attrs = pattrs;
+    rop.stat_params.lastmod = pmtime;
+    rop.stat_params.perr = &err;
+
+    int ret = rop.stat(objv_tracker);
     if (ret < 0)
       return ret;
 
-    ret = rgwstore->get_obj(ctx, objv_tracker, &handle, obj, bl, 0, request_len - 1, cache_info);
-    rgwstore->finish_get_obj(&handle);
+    rop.read_params.cache_info = cache_info;
+
+    ret = rop.read(0, request_len - 1, bl, objv_tracker);
+    if (ret == -ECANCELED) {
+      /* raced, restart */
+      continue;
+    }
     if (ret < 0)
       return ret;
 
index 8a7bf0cb2e044554aa15c91b75a86e700a1daa71..aeb4cdb9693eec4dda17bf61c23504196d90e77e 100644 (file)
@@ -16,7 +16,7 @@ struct obj_version;
 
 int rgw_put_system_obj(RGWRados *rgwstore, rgw_bucket& bucket, string& oid, const char *data, size_t size, bool exclusive,
                        RGWObjVersionTracker *objv_tracker, time_t set_mtime, map<string, bufferlist> *pattrs = NULL);
-int rgw_get_system_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
+int rgw_get_system_obj(RGWRados *rgwstore, RGWRados::ObjectCtx& obj_ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
                        RGWObjVersionTracker *objv_tracker, time_t *pmtime, map<string, bufferlist> *pattrs = NULL,
                        rgw_cache_entry_info *cache_info = NULL);