mirror of
https://github.com/ceph/ceph
synced 2025-03-11 02:39:05 +00:00
rgw: push hash calculater deeper
This might have been the culprit for #9307. Before we were calculating the hash after the call to processor->handle_data(), however, that method might have spliced the bufferlist, so we can't be sure that the pointer that we were holding originally is still invalid. Instead, push the hash calculation down. Added a new explicit complete_hash() call to the processor, since when we're at complete() it's too late (we need to have the hash at that point already). Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
parent
9f4c687288
commit
d41c3e858c
@ -1575,22 +1575,15 @@ int RGWPutObj::user_manifest_iterate_cb(rgw_bucket& bucket, RGWObjEnt& ent, RGWA
|
||||
static int put_data_and_throttle(RGWPutObjProcessor *processor, bufferlist& data, off_t ofs,
|
||||
MD5 *hash, bool need_to_wait)
|
||||
{
|
||||
const unsigned char *data_ptr = (hash ? (const unsigned char *)data.c_str() : NULL);
|
||||
bool again;
|
||||
uint64_t len = data.length();
|
||||
|
||||
do {
|
||||
void *handle;
|
||||
|
||||
int ret = processor->handle_data(data, ofs, &handle, &again);
|
||||
int ret = processor->handle_data(data, ofs, hash, &handle, &again);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (hash) {
|
||||
hash->Update(data_ptr, len);
|
||||
hash = NULL; /* only calculate hash once */
|
||||
}
|
||||
|
||||
ret = processor->throttle_data(handle, need_to_wait);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1728,6 +1721,7 @@ void RGWPutObj::execute()
|
||||
}
|
||||
|
||||
if (need_calc_md5) {
|
||||
processor->complete_hash(&hash);
|
||||
hash.Final(m);
|
||||
|
||||
buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
|
||||
|
@ -905,8 +905,10 @@ int RGWPutObjProcessor_Plain::prepare(RGWRados *store, void *obj_ctx, string *oi
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGWPutObjProcessor_Plain::handle_data(bufferlist& bl, off_t _ofs, void **phandle, bool *again)
|
||||
int RGWPutObjProcessor_Plain::handle_data(bufferlist& bl, off_t _ofs, MD5 *hash, void **phandle, bool *again)
|
||||
{
|
||||
assert(!hash);
|
||||
|
||||
*again = false;
|
||||
|
||||
if (ofs != _ofs)
|
||||
@ -1033,7 +1035,7 @@ int RGWPutObjProcessor_Atomic::write_data(bufferlist& bl, off_t ofs, void **phan
|
||||
return RGWPutObjProcessor_Aio::handle_obj_data(cur_obj, bl, ofs - cur_part_ofs, ofs, phandle, exclusive);
|
||||
}
|
||||
|
||||
int RGWPutObjProcessor_Atomic::handle_data(bufferlist& bl, off_t ofs, void **phandle, bool *again)
|
||||
int RGWPutObjProcessor_Atomic::handle_data(bufferlist& bl, off_t ofs, MD5 *hash, void **phandle, bool *again)
|
||||
{
|
||||
*again = false;
|
||||
|
||||
@ -1067,7 +1069,10 @@ int RGWPutObjProcessor_Atomic::handle_data(bufferlist& bl, off_t ofs, void **pha
|
||||
if (!data_ofs && !immutable_head()) {
|
||||
first_chunk.claim(bl);
|
||||
obj_len = (uint64_t)first_chunk.length();
|
||||
int r = prepare_next_part(first_chunk.length());
|
||||
if (hash) {
|
||||
hash->Update((const byte *)first_chunk.c_str(), obj_len);
|
||||
}
|
||||
int r = prepare_next_part(obj_len);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
@ -1079,6 +1084,9 @@ int RGWPutObjProcessor_Atomic::handle_data(bufferlist& bl, off_t ofs, void **pha
|
||||
bool exclusive = (!write_ofs && immutable_head()); /* immutable head object, need to verify nothing exists there
|
||||
we could be racing with another upload, to the same
|
||||
object and cleanup can be messy */
|
||||
if (hash) {
|
||||
hash->Update((const byte *)bl.c_str(), bl.length());
|
||||
}
|
||||
int ret = write_data(bl, write_ofs, phandle, exclusive);
|
||||
if (ret >= 0) { /* we might return, need to clear bl as it was already sent */
|
||||
bl.clear();
|
||||
@ -1086,6 +1094,11 @@ int RGWPutObjProcessor_Atomic::handle_data(bufferlist& bl, off_t ofs, void **pha
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RGWPutObjProcessor_Atomic::complete_hash(MD5 *hash)
|
||||
{
|
||||
hash->Update((const byte *)pending_data_bl.c_str(), pending_data_bl.length());
|
||||
}
|
||||
|
||||
|
||||
int RGWPutObjProcessor_Atomic::prepare_init(RGWRados *store, void *obj_ctx, string *oid_rand)
|
||||
{
|
||||
@ -3045,7 +3058,7 @@ public:
|
||||
|
||||
do {
|
||||
void *handle;
|
||||
int ret = processor->handle_data(bl, ofs, &handle, &again);
|
||||
int ret = processor->handle_data(bl, ofs, NULL, &handle, &again);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -3510,7 +3523,7 @@ int RGWRados::copy_obj_data(void *ctx,
|
||||
do {
|
||||
void *handle;
|
||||
|
||||
ret = processor.handle_data(bl, ofs, &handle, &again);
|
||||
ret = processor.handle_data(bl, ofs, NULL, &handle, &again);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -565,8 +565,11 @@ public:
|
||||
obj_ctx = _o;
|
||||
return 0;
|
||||
}
|
||||
virtual int handle_data(bufferlist& bl, off_t ofs, void **phandle, bool *again) = 0;
|
||||
virtual int handle_data(bufferlist& bl, off_t ofs, MD5 *hash, void **phandle, bool *again) = 0;
|
||||
virtual int throttle_data(void *handle, bool need_to_wait) = 0;
|
||||
virtual void complete_hash(MD5 *hash) {
|
||||
assert(0);
|
||||
}
|
||||
virtual int complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs);
|
||||
|
||||
CephContext *ctx();
|
||||
@ -583,7 +586,7 @@ class RGWPutObjProcessor_Plain : public RGWPutObjProcessor
|
||||
|
||||
protected:
|
||||
int prepare(RGWRados *store, void *obj_ctx, string *oid_rand);
|
||||
int handle_data(bufferlist& bl, off_t ofs, void **phandle, bool *again);
|
||||
int handle_data(bufferlist& bl, off_t ofs, MD5 *hash /* NULL expected */, void **phandle, bool *again);
|
||||
int do_complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs);
|
||||
|
||||
public:
|
||||
@ -673,7 +676,8 @@ public:
|
||||
void set_extra_data_len(uint64_t len) {
|
||||
extra_data_len = len;
|
||||
}
|
||||
virtual int handle_data(bufferlist& bl, off_t ofs, void **phandle, bool *again);
|
||||
virtual int handle_data(bufferlist& bl, off_t ofs, MD5 *hash, void **phandle, bool *again);
|
||||
virtual void complete_hash(MD5 *hash);
|
||||
bufferlist& get_extra_data() { return extra_data_bl; }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user