with the given stats */
virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist>* rmattrs) = 0;
+ map<std::string, bufferlist>* rmattrs,
+ const bufferlist *data) = 0;
virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
off_t ofs, size_t len, bool exclusive) = 0;
virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
/* 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 ret = put_obj_data(ctx, obj, data, -1, len, exclusive);
- if (ret >= 0 && (attrs.size() || mtime)) {
- ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false, NULL);
- }
+ bufferlist bl;
+ bl.append(data, len);
+ int ret = put_obj_meta(ctx, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, exclusive, NULL, &bl);
return ret;
}
int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl);
int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist>* rmattrs);
+ map<std::string, bufferlist>* rmattrs, const bufferlist *data);
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,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist>* rmattrs)
+ map<std::string, bufferlist>* rmattrs, const bufferlist *data)
{
rgw_bucket bucket;
string oid;
info.xattrs = attrs;
info.status = 0;
info.flags = CACHE_FLAG_XATTRS;
+ if (data) {
+ info.data = *data;
+ info.flags |= CACHE_FLAG_DATA;
+ }
}
- int ret = T::put_obj_meta(ctx, obj, size, mtime, attrs, category, exclusive, rmattrs);
+ int ret = T::put_obj_meta(ctx, obj, size, mtime, attrs, category, exclusive, rmattrs, data);
if (cacheable) {
string name = normal_name(bucket, oid);
if (ret >= 0) {
int RGWFS::put_obj_meta(void *ctx, rgw_obj& obj,
uint64_t size, time_t *mtime, map<string, bufferlist>& attrs,
RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist> *rmattrs)
+ map<std::string, bufferlist> *rmattrs, const bufferlist *data)
{
rgw_bucket& bucket = obj.bucket;
std::string& oid = obj.object;
int create_bucket(std::string& owner, rgw_bucket& bucket, map<std::string, bufferlist>& attrs, bool system_bucket, bool exclusive, uint64_t auid=0);
int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist> *rmattrs);
+ map<std::string, bufferlist> *rmattrs, const bufferlist *data);
int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
off_t ofs, size_t size, bool exclusive);
int copy_obj(void *ctx, rgw_obj& dest_obj,
return 0;
}
+class RGWPutObjProcessor_Plain : public RGWPutObjProcessor
+{
+ bufferlist data;
+ rgw_obj obj;
+ off_t ofs;
+
+protected:
+ int prepare(struct req_state *s);
+ int handle_data(bufferlist& bl, off_t ofs, void **phandle);
+ int throttle_data(void *handle) { return 0; }
+ int complete(string& etag, map<string, bufferlist>& attrs);
+
+public:
+ RGWPutObjProcessor_Plain() : ofs(0) {}
+};
+
+int RGWPutObjProcessor_Plain::prepare(struct req_state *s)
+{
+ RGWPutObjProcessor::prepare(s);
+
+ obj.init(s->bucket, s->object_str);
+
+ return 0;
+};
+
+int RGWPutObjProcessor_Plain::handle_data(bufferlist& bl, off_t _ofs, void **phandle)
+{
+ if (ofs != _ofs)
+ return -EINVAL;
+
+ data.append(bl);
+ ofs += bl.length();
+
+ return 0;
+}
+
+int RGWPutObjProcessor_Plain::complete(string& etag, map<string, bufferlist>& attrs)
+{
+ int r = rgwstore->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs,
+ RGW_OBJ_CATEGORY_MAIN, false, NULL, &data);
+ return r;
+}
+
+
class RGWPutObjProcessor_Aio : public RGWPutObjProcessor
{
list<struct put_obj_aio_info> pending;
class RGWPutObjProcessor_Atomic : public RGWPutObjProcessor_Aio
{
- string oid;
bool remove_temp_obj;
protected:
int prepare(struct req_state *s);
{
RGWPutObjProcessor::prepare(s);
- oid = s->object_str;
+ string oid = s->object_str;
obj.set_ns(tmp_ns);
char buf[33];
class RGWPutObjProcessor_Multipart : public RGWPutObjProcessor_Aio
{
- string oid;
string part_num;
RGWMPObj mp;
protected:
{
RGWPutObjProcessor::prepare(s);
- oid = s->object_str;
+ string oid = s->object_str;
string upload_id;
url_decode(s->args.get("uploadId"), upload_id);
mp.init(oid, upload_id);
int RGWPutObjProcessor_Multipart::complete(string& etag, map<string, bufferlist>& attrs)
{
- int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
+ int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL);
if (r < 0)
return r;
bool multipart = s->args.exists("uploadId");
if (!multipart) {
- processor = new RGWPutObjProcessor_Atomic();
+ if (s->content_length <= RGW_MAX_CHUNK_SIZE)
+ processor = new RGWPutObjProcessor_Plain();
+ else
+ processor = new RGWPutObjProcessor_Atomic();
} else {
processor = new RGWPutObjProcessor_Multipart();
}
}
}
- ret = rgwstore->put_obj_meta(s->obj_ctx, obj, obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, &rmattrs);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, obj, obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, &rmattrs, NULL);
done:
send_response();
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, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL);
} while (ret == -EEXIST);
done:
send_response();
target_obj.init(s->bucket, s->object_str);
rgwstore->set_atomic(s->obj_ctx, target_obj);
- ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
+ ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL);
if (ret < 0)
goto done;
*/
int RGWRados::put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size,
time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<string, bufferlist>* rmattrs)
+ map<string, bufferlist>* rmattrs,
+ const bufferlist *data)
{
rgw_bucket bucket;
std::string oid, key;
}
}
+ if (data)
+ op.write_full(*data);
+
if (!op.size())
return 0;
/** Write/overwrite an object to the bucket storage. */
virtual int put_obj_meta(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
- map<std::string, bufferlist>* rmattrs);
+ map<std::string, bufferlist>* rmattrs, const bufferlist *data);
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,