New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rgw: Multipart upload may failed when object size is large and near byte quota limit #17960
Conversation
227e867
to
ad079d1
Compare
src/cls/rgw/cls_rgw.cc
Outdated
@@ -707,10 +707,27 @@ int rgw_bucket_prepare_op(cls_method_context_t hctx, bufferlist *in, bufferlist | |||
return write_bucket_header(hctx, &header); | |||
} | |||
|
|||
static bool obj_name_filter(string& name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation looks wrong in function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The format problem has been corrected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add tracker issue : http://tracker.ceph.com/issues/21565
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function name should be something more descriptive. "is_multipart_objname" or some such.
name can be const. And this could be inline.
@gaosibei It's better to create a tracker issue and add a link to it with Fixes: in your commit message |
Thanks for taking a look! |
src/cls/rgw/cls_rgw.cc
Outdated
int ret = true; | ||
if (name.substr(0,10) == MP_MULTI_SUFFIX) { | ||
int len = name.size(); | ||
size_t pos = name.find(MP_META_SUFFIX, len - 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using "find" here is suboptimal. Use boost::algorithm::ends_with or perhaps name.compare.
Also, -5 is magic - not good to bury knowledge of length of MP_META_SUFFIX like this.
src/cls/rgw/cls_rgw.cc
Outdated
static bool obj_name_filter(string& name) | ||
{ | ||
int ret = true; | ||
if (name.substr(0,10) == MP_MULTI_SUFFIX) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like below "10" is magic, ugh. also substr makes a temp copy - better to use compare. Or better yet use "boost::algorithm::starts_with".
src/cls/rgw/cls_rgw_types.h
Outdated
@@ -11,6 +11,8 @@ | |||
#define CEPH_RGW_TAG_TIMEOUT 120 | |||
#define CEPH_RGW_DIR_SUGGEST_LOG_OP 0x80 | |||
#define CEPH_RGW_DIR_SUGGEST_OP_MASK 0x7f | |||
#define MP_META_SUFFIX ".meta" | |||
#define MP_MULTI_SUFFIX "_multipart" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't really a suffix is it? This looks like it's supposed to match "RGW_OBJ_NS_MULTIPART" - however that omits the '_' which is inconvenient.
I don't have a good way to fix this, but I wish there were some way to share more of the oid/ns code in src/rgw with this logic. This logic here is basically duplicating a small subset of that logic with code that doesn't obviously match it, which is not an ideal style choice. |
@mdw-at-linuxbox According to your review, I have modified the code with boost. But, I'm not sure this change is a good way to fix this bug. If this change is s`till not a good method, I would parse oid and ns from entry.key.name which like the function: parse_raw_oid in src/rgw/rgw_common.h. |
"parse_raw_oid" looks intriguing, so that's probably the "right" way to do this. If you can try it and see if it works, that would be wonderful. If it turns out to be a complicated change touching lots of files, can you push it as a separate PR? I think we might want to keep this change for jewel/backports, and use "parse_raw_oid" going forward in master. Thanks! |
There were some impatient people around, so I created another PR with a revised copy of this change. |
@mdw-at-linuxbox According to the PR#18123, I think the function name should be changed to "is_not_multipart_objname". When the return value is The another way is changed the return value from false to true, when the object name is multipart. |
f5c1809
to
2121cfb
Compare
@mattbenjamin @mdw-at-linuxbox |
@gaosibei this new approach looks appealing, thanks very much! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaosibei need to verify that s3-tests still pass with this one. One thing to check is whether the behavior of deleting a bucket with incomplete multipart upload changed.
src/cls/rgw/cls_rgw_types.h
Outdated
@@ -97,12 +97,13 @@ struct rgw_bucket_dir_entry_meta { | |||
string content_type; | |||
uint64_t accounted_size; | |||
string user_data; | |||
bool multipart; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be called multipart
, should be something like accounted_entry
. Should default to true
, and the logic should be flipped.
src/rgw/rgw_rados.cc
Outdated
@@ -6897,7 +6897,7 @@ int RGWRados::Object::Write::_do_write_meta(uint64_t size, uint64_t accounted_si | |||
uint64_t orig_size; | |||
|
|||
if (!reset_obj) { //Multipart upload, it has immutable head. | |||
orig_exists = false; | |||
orig_exists = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should comment why this is true
@mattbenjamin @mdw-at-linuxbox @yehudasa can you take a look again? |
can you take a look again? |
@@ -130,6 +132,8 @@ struct rgw_bucket_dir_entry_meta { | |||
accounted_size = size; | |||
if (struct_v >= 5) | |||
::decode(user_data, bl); | |||
if (struct_v >= 6) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need to set accounted_entry as true for older version which don't have this flag.
otherwise when you delete them you won't remove them from the accounting (which there were already accounted for)
This pr needs upgrade tests to make sure we don't break the accounting on them |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
This pull request has been automatically closed because there has been no activity for 90 days. Please feel free to reopen this pull request (or open a new one) if the proposed change is still appropriate. Thank you for your contribution! |
This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days. |
This pull request has been automatically closed because there has been no activity for 90 days. Please feel free to reopen this pull request (or open a new one) if the proposed change is still appropriate. Thank you for your contribution! |
@cbodley is this change still relevant ? |
@gaosibei can you please rebase this? |
This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days. |
needs rebase |
This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days. |
This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days. |
This pull request has been automatically closed because there has been no activity for 90 days. Please feel free to reopen this pull request (or open a new one) if the proposed change is still appropriate. Thank you for your contribution! |
When user upload big object using multipart api, they may upload failed. The reason is that the big object is considered to be multiple objects for quota stats
Fixes:http://tracker.ceph.com/issues/21565
Signed-off-by: Sibei Gao gaosb@inspur.com