int get_obj(void *ctx, void **handle, rgw_obj& obj, char **data, off_t ofs, off_t end);
- int obj_stat(void *ctx, rgw_bucket& bucket, std::string& obj, uint64_t *psize, time_t *pmtime);
+ int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs);
int delete_obj(void *ctx, std::string& id, rgw_obj& obj, bool sync);
};
}
template <class T>
-int RGWCache<T>::obj_stat(void *ctx, rgw_bucket& bucket, std::string& obj, uint64_t *psize, time_t *pmtime)
+int RGWCache<T>::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs)
{
- if (bucket.name[0] != '.')
- return T::obj_stat(ctx, bucket, obj, psize, pmtime);
+ string& bucket_name = obj.bucket.name;
+ string& oid = obj.object;
+ if (bucket_name[0] != '.')
+ return T::obj_stat(ctx, obj, psize, pmtime, attrs);
- string name = normal_name(bucket, obj);
+ string name = normal_name(obj.bucket, oid);
uint64_t size;
time_t mtime;
- int64_t t;
ObjectCacheInfo info;
- bufferlist& bl = info.data;
- int r = cache.get(name, info, CACHE_FLAG_META);
+ int r = cache.get(name, info, CACHE_FLAG_META | CACHE_FLAG_XATTRS);
if (r == 0) {
if (info.status < 0)
return info.status;
mtime = info.meta.mtime;
goto done;
}
- r = T::obj_stat(ctx, bucket, obj, &size, &mtime);
+ r = T::obj_stat(ctx, obj, &size, &mtime, &info.xattrs);
if (r < 0) {
if (r == -ENOENT) {
info.status = r;
info.status = 0;
info.meta.mtime = mtime;
info.meta.size = size;
- info.flags = CACHE_FLAG_META;
+ info.flags = CACHE_FLAG_META | CACHE_FLAG_XATTRS;
cache.put(name, info);
done:
if (psize)
*psize = size;
if (pmtime)
*pmtime = mtime;
+ if (attrs)
+ *attrs = info.xattrs;
return 0;
}
ret = clone_obj(ctx, dest_obj, 0, tmp_obj, 0, end + 1, NULL, attrs, category);
if (mtime)
- obj_stat(ctx, tmp_obj, NULL, mtime);
+ obj_stat(ctx, tmp_obj, NULL, mtime, NULL);
r = rgwstore->delete_obj(ctx, id, tmp_obj, false);
if (r < 0)
return r;
r = io_ctx.operate(oid, &op);
- if (r >= 0 && bucket.marker.size()) {
+ if ((r >= 0 || r == -ENOENT) && bucket.marker.size()) {
uint64_t epoch = io_ctx.get_last_version();
r = complete_update_index_del(bucket, obj.object, tag, epoch);
}
op.getxattrs();
op.stat();
bufferlist outbl;
- int r = io_ctx.operate(actual_obj, &op, &outbl);
+ int r = obj_stat(rctx, obj, &s->size, &s->mtime, &s->attrset);
if (r == -ENOENT) {
s->exists = false;
s->has_attrs = true;
return r;
s->exists = true;
-
- bufferlist::iterator oiter = outbl.begin();
- try {
- ::decode(s->attrset, oiter);
- } catch (buffer::error& err) {
- dout(0) << "ERROR: failed decoding s->attrset (obj=" << obj << "), aborting" << dendl;
- return -EIO;
- }
-
- map<string, bufferlist>::iterator aiter;
- for (aiter = s->attrset.begin(); aiter != s->attrset.end(); ++aiter) {
- dout(0) << "iter->first=" << aiter->first << dendl;
- }
-
- try {
- ::decode(s->size, oiter);
- utime_t ut;
- ::decode(ut, oiter);
- s->mtime = ut.sec();
- } catch (buffer::error& err) {
- dout(0) << "ERROR: failed decoding object (obj=" << obj << ") info (either size or mtime), aborting" << dendl;
- }
-
s->has_attrs = true;
map<string, bufferlist>::iterator iter = s->attrset.find(RGW_ATTR_SHADOW_OBJ);
if (iter != s->attrset.end()) {
return r;
}
-int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime)
+int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs)
{
rgw_bucket bucket;
std::string oid, key;
get_obj_bucket_and_oid_key(obj, bucket, oid, key);
librados::IoCtx io_ctx;
- RGWRadosCtx *rctx = (RGWRadosCtx *)ctx;
int r = open_bucket_ctx(bucket, io_ctx);
if (r < 0)
return r;
+
io_ctx.locator_set_key(key);
- if (rctx) {
- RGWObjState *astate;
- r = get_obj_state(rctx, obj, io_ctx, oid, &astate);
- if (r < 0)
- return r;
+ ObjectReadOperation op;
+ op.getxattrs();
+ op.stat();
+ bufferlist outbl;
+ r = io_ctx.operate(oid, &op, &outbl);
+ if (r < 0)
+ return r;
- if (!astate->exists)
- return -ENOENT;
+ map<string, bufferlist> attrset;
+ bufferlist::iterator oiter = outbl.begin();
+ try {
+ ::decode(attrset, oiter);
+ } catch (buffer::error& err) {
+ dout(0) << "ERROR: failed decoding s->attrset (obj=" << obj << "), aborting" << dendl;
+ return -EIO;
+ }
- if (psize)
- *psize = astate->size;
- if (pmtime)
- *pmtime = astate->mtime;
+ map<string, bufferlist>::iterator aiter;
+ for (aiter = attrset.begin(); aiter != attrset.end(); ++aiter) {
+ dout(0) << "iter->first=" << aiter->first << dendl;
+ }
- return 0;
+ uint64_t size;
+ time_t mtime;
+ try {
+ ::decode(size, oiter);
+ utime_t ut;
+ ::decode(ut, oiter);
+ mtime = ut.sec();
+ } catch (buffer::error& err) {
+ dout(0) << "ERROR: failed decoding object (obj=" << obj << ") info (either size or mtime), aborting" << dendl;
}
+ if (psize)
+ *psize = size;
+ if (pmtime)
+ *pmtime = mtime;
+ if (attrs)
+ *attrs = attrset;
- r = io_ctx.stat(oid, psize, pmtime);
- return r;
+ return 0;
}
int RGWRados::get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats)
cout << "processing intent log " << oid << std::endl;
uint64_t size;
rgw_obj obj(bucket, oid);
- int r = obj_stat(NULL, obj, &size, NULL);
+ int r = obj_stat(NULL, obj, &size, NULL, NULL);
if (r < 0) {
cerr << "error while doing stat on " << bucket << ":" << oid
<< " " << cpp_strerror(-r) << std::endl;