/** write an object to the storage device in the appropriate pool
with the given stats */
virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive) = 0;
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+ map<std::string, bufferlist>* rmattrs) = 0;
virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t len) = 0;
virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
time_t *mtime, map<std::string, bufferlist>& attrs) {
int ret = put_obj_data(ctx, id, obj, data, -1, len);
if (ret >= 0) {
- ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false);
+ ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false, NULL);
}
return ret;
}
int RGWFS::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj,
uint64_t size, time_t *mtime, map<string, bufferlist>& attrs,
- RGWObjCategory category, bool exclusive)
+ RGWObjCategory category, bool exclusive,
+ map<std::string, bufferlist> *rmattrs)
{
rgw_bucket& bucket = obj.bucket;
std::string& oid = obj.object;
int create_bucket(std::string& id, rgw_bucket& bucket, map<std::string, bufferlist>& attrs, bool system_bucket, bool exclusive, uint64_t auid=0);
int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+ map<std::string, bufferlist> *rmattrs);
int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t size);
int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj,
return ret;
}
+static int get_obj_attrs(struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs)
+{
+ void *handle;
+ int ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, 0, NULL, &attrs, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err);
+ rgwstore->finish_get_obj(&handle);
+ return ret;
+}
+
int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
{
string upload_id;
goto done;
}
} else {
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
if (ret < 0)
goto done_err;
send_response();
}
+int RGWPutObjMetadata::verify_permission()
+{
+ if (!::verify_permission(s, RGW_PERM_WRITE))
+ return -EACCES;
+
+ return 0;
+}
+
+void RGWPutObjMetadata::execute()
+{
+ ret = -EINVAL;
+
+ const char *meta_prefix = RGW_ATTR_META_PREFIX;
+ int meta_prefix_len = sizeof(RGW_ATTR_META_PREFIX) - 1;
+ map<string, bufferlist> attrs, orig_attrs, rmattrs;
+ map<string, bufferlist>::iterator iter;
+ get_request_metadata(s, attrs);
+
+ rgw_obj obj(s->bucket, s->object_str);
+
+ rgwstore->set_atomic(s->obj_ctx, obj);
+
+ /* check if obj exists, read orig attrs */
+ ret = get_obj_attrs(s, obj, orig_attrs);
+ if (ret < 0)
+ goto done;
+
+ /* only remove meta attrs */
+ for (iter = orig_attrs.begin(); iter != orig_attrs.end(); ++iter) {
+ const string& name = iter->first;
+ if (name.compare(0, meta_prefix_len, meta_prefix) == 0) {
+ rmattrs[name] = iter->second;
+ }
+ }
+
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, &rmattrs);
+
+done:
+ send_response();
+}
+
int RGWDeleteObj::verify_permission()
{
if (!::verify_permission(s, RGW_PERM_WRITE))
obj.init(s->bucket, tmp_obj_name, s->object_str, mp_ns);
// the meta object will be indexed with 0 size, we c
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL);
} while (ret == -EEXIST);
done:
send_response();
static int get_multiparts_info(struct req_state *s, string& meta_oid, map<uint32_t, RGWUploadPartInfo>& parts,
RGWAccessControlPolicy& policy, map<string, bufferlist>& attrs)
{
- void *handle;
map<string, bufferlist> parts_map;
map<string, bufferlist>::iterator iter;
bufferlist header;
rgw_obj obj(s->bucket, meta_oid, s->object_str, mp_ns);
- int ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, 0, NULL, &attrs, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err);
- rgwstore->finish_get_obj(&handle);
-
+ int ret = get_obj_attrs(s, obj, attrs);
if (ret < 0)
return ret;
target_obj.init(s->bucket, s->object_str);
rgwstore->set_atomic(s->obj_ctx, target_obj);
- ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
if (ret < 0)
goto done;
virtual void send_response() = 0;
};
+class RGWPutObjMetadata : public RGWOp {
+protected:
+ int ret;
+
+public:
+ RGWPutObjMetadata() {}
+
+ virtual void init(struct req_state *s) {
+ RGWOp::init(s);
+ ret = 0;
+ }
+ int verify_permission();
+ void execute();
+
+ virtual void send_response() = 0;
+};
+
class RGWDeleteObj : public RGWOp {
protected:
int ret;
* Returns: 0 on success, -ERR# otherwise.
*/
int RGWRados::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size,
- time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive)
+ time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+ map<string, bufferlist>* rmattrs)
{
rgw_bucket bucket;
std::string oid, key;
bufferlist acl_bl;
map<string, bufferlist>::iterator iter;
+ if (rmattrs) {
+ for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) {
+ const string& name = iter->first;
+ op.rmxattr(name.c_str());
+ }
+ }
+
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
const string& name = iter->first;
bufferlist& bl = iter->second;
/** Write/overwrite an object to the bucket storage. */
virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
- map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
+ map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+ map<std::string, bufferlist>* rmattrs);
virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
off_t ofs, size_t len);
virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
int get_data();
};
+class RGWPutObjMetadata_REST : public RGWPutObjMetadata
+{
+public:
+ RGWPutObjMetadata_REST() {}
+ ~RGWPutObjMetadata_REST() {}
+};
+
class RGWDeleteObj_REST : public RGWDeleteObj {
public:
RGWDeleteObj_REST() {}
flush_formatter_to_req_state(s, s->formatter);
}
+void RGWPutObjMetadata_REST_SWIFT::send_response()
+{
+ if (!ret)
+ ret = STATUS_ACCEPTED;
+ set_req_state_err(s, ret);
+ dump_errno(s);
+ end_header(s);
+ flush_formatter_to_req_state(s, s->formatter);
+}
+
void RGWDeleteObj_REST_SWIFT::send_response()
{
int r = ret;
return NULL;
}
+RGWOp *RGWHandler_REST_SWIFT::get_post_op()
+{
+ if (s->object)
+ return new RGWPutObjMetadata_REST_SWIFT;
+
+ return NULL;
+}
+
int RGWHandler_REST_SWIFT::authorize()
{
bool authorized = rgw_verify_os_token(s);
void send_response();
};
+class RGWPutObjMetadata_REST_SWIFT : public RGWPutObjMetadata_REST {
+public:
+ RGWPutObjMetadata_REST_SWIFT() {}
+ ~RGWPutObjMetadata_REST_SWIFT() {}
+
+ void send_response();
+};
+
class RGWDeleteObj_REST_SWIFT : public RGWDeleteObj_REST {
public:
RGWDeleteObj_REST_SWIFT() {}
RGWOp *get_retrieve_op(bool get_data);
RGWOp *get_create_op();
RGWOp *get_delete_op();
- RGWOp *get_post_op() { return NULL; }
+ RGWOp *get_post_op();
public:
RGWHandler_REST_SWIFT() : RGWHandler_REST() {}