/* conditional increase, return -EAGAIN if condition fails */
void cls_version_inc(librados::ObjectWriteOperation& op, obj_version& ver, VersionCond cond);
+int cls_version_read(bufferlist& outbl);
+
int cls_version_read(librados::IoCtx& io_ctx, string& oid, obj_version *ver);
void cls_version_check(librados::ObjectOperation& op, obj_version& ver, VersionCond cond);
int set_attrs(void *ctx, rgw_obj& obj,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs);
- int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
+ int put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, int flags,
map<std::string, bufferlist>* rmattrs, const bufferlist *data,
- RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs);
-
+ RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs,
+ bool modify_version, obj_version *objv);
int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
off_t ofs, size_t len, bool exclusive);
}
template <class T>
-int RGWCache<T>::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
+int RGWCache<T>::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, int flags,
map<std::string, bufferlist>* rmattrs, const bufferlist *data,
- RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs)
+ RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs,
+ bool modify_version, obj_version *objv)
{
rgw_bucket bucket;
string oid;
info.flags |= CACHE_FLAG_DATA;
}
}
- int ret = T::put_obj_meta(ctx, obj, size, mtime, attrs, category, flags, rmattrs, data, manifest, ptag, remove_objs);
+ int ret = T::put_obj_meta_impl(ctx, obj, size, mtime, attrs, category, flags, rmattrs, data, manifest, ptag, remove_objs,
+ modify_version, objv);
if (cacheable) {
string name = normal_name(bucket, oid);
if (ret >= 0) {
int RGWPutObjProcessor_Plain::do_complete(string& etag, map<string, bufferlist>& attrs)
{
- int r = store->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, &data, NULL, NULL, NULL);
+ int r = store->put_obj_meta(s->obj_ctx, obj, data.length(), attrs,
+ RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE,
+ &data);
return r;
}
store->set_atomic(s->obj_ctx, head_obj);
- int r = store->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, &first_chunk, &manifest, NULL, NULL);
+ RGWRados::PutObjMetaExtraParams extra_params;
+ extra_params.data = &first_chunk;
+ extra_params.manifest = &manifest;
+
+ int r = store->put_obj_meta(s->obj_ctx, head_obj, obj_len, attrs,
+ RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE,
+ extra_params);
return r;
}
{
complete_parts();
- int r = store->put_obj_meta(s->obj_ctx, head_obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, 0, NULL, NULL, NULL, NULL, NULL);
+ int r = store->put_obj_meta(s->obj_ctx, head_obj, s->obj_size, attrs, RGW_OBJ_CATEGORY_MAIN, 0);
if (r < 0)
return r;
obj.init_ns(s->bucket, tmp_obj_name, mp_ns);
// the meta object will be indexed with 0 size, we c
- ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL, NULL, NULL, NULL, NULL, NULL);
+ ret = store->put_obj_meta(s->obj_ctx, obj, 0, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL);
} while (ret == -EEXIST);
}
store->set_atomic(s->obj_ctx, target_obj);
- ret = store->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs,
- RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE, NULL, NULL, &manifest, NULL, &remove_objs);
+ RGWRados::PutObjMetaExtraParams extra_params;
+
+ extra_params.manifest = &manifest;
+ extra_params.remove_objs = &remove_objs;
+
+ ret = store->put_obj_meta(s->obj_ctx, target_obj, ofs, attrs,
+ RGW_OBJ_CATEGORY_MAIN, PUT_OBJ_CREATE,
+ extra_params);
if (ret < 0)
return;
#include "cls/rgw/cls_rgw_types.h"
#include "cls/rgw/cls_rgw_client.h"
#include "cls/refcount/cls_refcount_client.h"
+#include "cls/version/cls_version_client.h"
#include "rgw_tools.h"
* exclusive: create object exclusively
* Returns: 0 on success, -ERR# otherwise.
*/
-int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size,
+int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size,
time_t *mtime, map<string, bufferlist>& attrs,
RGWObjCategory category, int flags,
map<string, bufferlist>* rmattrs,
const bufferlist *data,
RGWObjManifest *manifest,
const string *ptag,
- list<string> *remove_objs)
+ list<string> *remove_objs,
+ bool modify_version,
+ obj_version *objv)
{
rgw_bucket bucket;
std::string oid, key;
return r;
}
+ if (modify_version) {
+ if (objv) {
+ cls_version_set(op, *objv);
+ } else {
+ cls_version_inc(op);
+ }
+ }
+
if (data) {
/* if we want to overwrite the data, we also want to overwrite the
xattrs, so just remove the object */
rgw_bucket bucket;
get_obj_bucket_and_oid_key(first_part->loc, bucket, oid, key);
librados::IoCtx io_ctx;
+ PutObjMetaExtraParams ep;
ret = open_bucket_ctx(bucket, io_ctx);
if (ret < 0)
first_part->size = first_chunk.length();
}
- ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, PUT_OBJ_CREATE, NULL, &first_chunk, pmanifest, &tag, NULL);
+ ep.data = &first_chunk;
+ ep.manifest = pmanifest;
+ ep.ptag = &tag;
+
+ ret = put_obj_meta(ctx, dest_obj, end + 1, attrset, category, PUT_OBJ_CREATE, ep);
if (mtime)
- obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL);
+ obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL, NULL);
return 0;
int ret, r;
off_t ofs = 0;
+ PutObjMetaExtraParams ep;
do {
bufferlist bl;
}
manifest.obj_size = ofs;
- ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, PUT_OBJ_CREATE, NULL, &first_chunk, &manifest, NULL, NULL);
+ ep.data = &first_chunk;
+ ep.manifest = &manifest;
+
+ ret = put_obj_meta(ctx, dest_obj, end + 1, attrs, category, PUT_OBJ_CREATE, ep);
if (mtime)
- obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL);
+ obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL, NULL, NULL);
finish_get_obj(&handle);
if (s->has_attrs)
return 0;
- int r = obj_stat(rctx, obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL));
+ obj_version *objv = NULL;
+
+ if (bucket_is_system(obj.bucket)) {
+// objv = &s->objv;
+#warning FIXME
+ }
+
+ int r = obj_stat(rctx, obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), objv);
if (r == -ENOENT) {
s->exists = false;
s->has_attrs = true;
return r;
}
-int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, map<string, bufferlist> *attrs, bufferlist *first_chunk)
+int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, map<string, bufferlist> *attrs, bufferlist *first_chunk,
+ obj_version *objv)
{
rgw_bucket bucket;
std::string oid, key;
time_t mtime = 0;
ObjectReadOperation op;
+ if (objv) {
+#warning FIXME
+ }
op.getxattrs(&attrset, NULL);
op.stat(&size, &mtime, NULL);
if (first_chunk) {
#include "common/RefCountedObj.h"
#include "rgw_common.h"
#include "cls/rgw/cls_rgw_types.h"
+#include "cls/version/cls_version_types.h"
#include "rgw_log.h"
class RGWWatcher;
virtual int list_placement_set(set<string>& names);
virtual int create_pools(vector<string>& names, vector<int>& retcodes);
+ struct PutObjMetaExtraParams {
+ time_t *mtime;
+ map<std::string, bufferlist>* rmattrs;
+ const bufferlist *data;
+ RGWObjManifest *manifest;
+ const string *ptag;
+ list<string> *remove_objs;
+ bool modify_version;
+ obj_version *objv;
+
+ PutObjMetaExtraParams() : mtime(NULL), rmattrs(NULL),
+ data(NULL), manifest(NULL), ptag(NULL),
+ remove_objs(NULL), modify_version(false), objv(NULL) {}
+ };
+
/** Write/overwrite an object to the bucket storage. */
- virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
+ virtual int put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, int flags,
map<std::string, bufferlist>* rmattrs, const bufferlist *data,
- RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs);
+ RGWObjManifest *manifest, const string *ptag, list<string> *remove_objs,
+ bool modify_version, obj_version *objv);
+
+ virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size,
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, int flags,
+ const bufferlist *data = NULL) {
+ return put_obj_meta_impl(ctx, obj, size, NULL, attrs, category, flags,
+ NULL, data, NULL, NULL, NULL,
+ false, NULL);
+ }
+
+ virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, map<std::string, bufferlist>& attrs,
+ RGWObjCategory category, int flags, PutObjMetaExtraParams& params) {
+ return put_obj_meta_impl(ctx, obj, size, params.mtime, attrs, category, flags,
+ params.rmattrs, params.data, params.manifest, params.ptag, params.remove_objs,
+ params.modify_version, params.objv);
+ }
+
virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
off_t ofs, size_t len, bool exclusive);
virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
off_t ofs, bool exclusive, void **handle);
/* note that put_obj doesn't set category on an object, only use it for none user objects */
- int put_obj(void *ctx, rgw_obj& obj, const char *data, size_t len, bool exclusive,
- time_t *mtime, map<std::string, bufferlist>& attrs) {
+ int put_system_obj(void *ctx, rgw_obj& obj, const char *data, size_t len, bool exclusive,
+ time_t *mtime, map<std::string, bufferlist>& attrs, obj_version *objv) {
bufferlist bl;
bl.append(data, len);
int flags = PUT_OBJ_CREATE;
if (exclusive)
flags |= PUT_OBJ_EXCL;
- int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, flags, NULL, &bl, NULL, NULL, NULL);
+
+ PutObjMetaExtraParams ep;
+ ep.mtime = mtime;
+ ep.data = &bl;
+ ep.modify_version = true;
+ ep.objv = objv;
+
+ int ret = put_obj_meta(ctx, obj, len, attrs, RGW_OBJ_CATEGORY_NONE, flags, ep);
return ret;
}
virtual int aio_wait(void *handle);
virtual int read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& bl);
virtual int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime,
- uint64_t *epoch, map<string, bufferlist> *attrs, bufferlist *first_chunk);
+ uint64_t *epoch, map<string, bufferlist> *attrs, bufferlist *first_chunk,
+ obj_version *objv);
virtual bool supports_omap() { return true; }
int omap_get_vals(rgw_obj& obj, bufferlist& header, const std::string& marker, uint64_t count, std::map<string, bufferlist>& m);
rgw_obj obj(bucket, oid);
- int ret = rgwstore->put_obj(NULL, obj, data, size, exclusive, NULL, *pattrs);
+ int ret = rgwstore->put_system_obj(NULL, obj, data, size, exclusive, NULL, *pattrs, NULL);
if (ret == -ENOENT) {
ret = rgwstore->create_pool(bucket);
if (ret >= 0)
- ret = rgwstore->put_obj(NULL, obj, data, size, exclusive, NULL, *pattrs);
+ ret = rgwstore->put_system_obj(NULL, obj, data, size, exclusive, NULL, *pattrs, NULL);
}
return ret;