return 0;
}
-/**
- * Store the set of buckets associated with a user on a n xattr
- * not used with all backends
- * This completely overwrites any previously-stored list, so be careful!
- * Returns 0 on success, -ERR# otherwise.
- */
-int rgw_write_buckets_attr(RGWRados *store, string user_id, RGWUserBuckets& buckets)
-{
- bufferlist bl;
- buckets.encode(bl);
-
- rgw_obj obj(store->zone.user_uid_pool, user_id);
-
- int ret = store->set_attr(NULL, obj, RGW_ATTR_BUCKETS, bl);
-
- return ret;
-}
-
int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket)
{
int ret;
obj.init(bucket, no_oid);
- ret = store->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl);
+ ret = store->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
if (ret < 0) {
lderr(store->ctx()) << "ERROR: failed to set acl on bucket" << dendl;
goto done;
return ret;
}
+int rgw_bucket_set_attrs(RGWRados *store, rgw_obj& obj,
+ map<string, bufferlist>& attrs,
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker)
+{
+ return store->meta_mgr->set_attrs(bucket_meta_handler, obj.bucket.name,
+ obj, attrs, rmattrs, objv_tracker);
+}
+
static void dump_mulipart_index_results(list<std::string>& objs_to_unlink,
Formatter *f)
{
string uid_str(user_id);
bufferlist aclbl;
rgw_obj obj(bucket, no_oid);
+ RGWObjVersionTracker objv_tracker;
- int r = store->get_attr(NULL, obj, RGW_ATTR_ACL, aclbl);
+ int r = store->get_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
if (r >= 0) {
RGWAccessControlPolicy policy;
ACLOwner owner;
aclbl.clear();
policy.encode(aclbl);
- r = store->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl);
+ r = store->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
if (r < 0)
return r;
bufferlist bl;
rgw_obj obj(bucket, object_name);
- int ret = store->get_attr(NULL, obj, RGW_ATTR_ACL, bl);
+ int ret = store->get_attr(NULL, obj, RGW_ATTR_ACL, bl, NULL);
if (ret < 0)
return ret;
};
int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) {
-#warning FIXME: use objv_tracker
rgw_bucket bucket;
int r = init_bucket(store, entry, bucket, &objv_tracker);
if (r < 0) {
extern int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets& buckets,
const string& marker, uint64_t max, bool need_stats);
-/**
- * Store the set of buckets associated with a user.
- * This completely overwrites any previously-stored list, so be careful!
- * Returns 0 on success, -ERR# otherwise.
- */
-extern int rgw_write_buckets_attr(RGWRados *store, string user_id, RGWUserBuckets& buckets);
-
extern int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket);
extern int rgw_remove_user_bucket_info(RGWRados *store, string user_id, rgw_bucket& bucket);
extern int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object);
extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children);
+extern int rgw_bucket_set_attrs(RGWRados *store, rgw_obj& obj,
+ map<string, bufferlist>& attrs,
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker);
+
extern void check_bad_user_bucket_mapping(RGWRados *store, const string& user_id, bool fix);
struct RGWBucketAdminOpState {
public:
RGWCache() {}
- int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl);
+ int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl, RGWObjVersionTracker *objv_tracker);
int set_attrs(void *ctx, rgw_obj& obj,
map<string, bufferlist>& attrs,
- map<string, bufferlist>* rmattrs);
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker);
int put_obj_meta_impl(void *ctx, rgw_obj& obj, uint64_t size, time_t *mtime,
map<std::string, bufferlist>& attrs, RGWObjCategory category, int flags,
map<std::string, bufferlist>* rmattrs, const bufferlist *data,
}
template <class T>
-int RGWCache<T>::set_attr(void *ctx, rgw_obj& obj, const char *attr_name, bufferlist& bl)
+int RGWCache<T>::set_attr(void *ctx, rgw_obj& obj, const char *attr_name, bufferlist& bl, RGWObjVersionTracker *objv_tracker)
{
rgw_bucket bucket;
string oid;
info.status = 0;
info.flags = CACHE_FLAG_MODIFY_XATTRS;
}
- int ret = T::set_attr(ctx, obj, attr_name, bl);
+ int ret = T::set_attr(ctx, obj, attr_name, bl, objv_tracker);
if (cacheable) {
string name = normal_name(bucket, oid);
if (ret >= 0) {
template <class T>
int RGWCache<T>::set_attrs(void *ctx, rgw_obj& obj,
map<string, bufferlist>& attrs,
- map<string, bufferlist>* rmattrs)
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker)
{
rgw_bucket bucket;
string oid;
info.status = 0;
info.flags = CACHE_FLAG_MODIFY_XATTRS;
}
- int ret = T::set_attrs(ctx, obj, attrs, rmattrs);
+ int ret = T::set_attrs(ctx, obj, attrs, rmattrs, objv_tracker);
if (cacheable) {
string name = normal_name(bucket, oid);
if (ret >= 0) {
}
}
-int RGWMetadataManager::put_entry(RGWMetadataHandler *handler, string& key, bufferlist& bl, bool exclusive,
- RGWObjVersionTracker *objv_tracker, map<string, bufferlist> *pattrs)
+int RGWMetadataManager::pre_modify(RGWMetadataHandler *handler, string& section, string& key,
+ RGWMetadataLogData& log_data, RGWObjVersionTracker *objv_tracker)
{
- bufferlist logbl;
- string section = handler->get_type();
+ section = handler->get_type();
/* if write version has not been set, and there's a read version, set it so that we can
* log it
objv_tracker->write_version.ver++;
}
- RGWMetadataLogData log_data;
log_data.read_version = objv_tracker->read_version;
log_data.write_version = objv_tracker->write_version;
log_data.status = MDLOG_STATUS_WRITING;
+ bufferlist logbl;
::encode(log_data, logbl);
int ret = md_log->add_entry(store, section, key, logbl);
if (ret < 0)
return ret;
- ret = handler->put_entry(store, key, bl, exclusive, objv_tracker, pattrs);
- if (ret < 0)
- return ret;
+ return 0;
+}
+int RGWMetadataManager::post_modify(string& section, string& key, RGWMetadataLogData& log_data,
+ RGWObjVersionTracker *objv_tracker)
+{
log_data.status = MDLOG_STATUS_COMPLETE;
- logbl.clear();
+ bufferlist logbl;
::encode(log_data, logbl);
- ret = md_log->add_entry(store, section, key, logbl);
+ int ret = md_log->add_entry(store, section, key, logbl);
if (ret < 0)
return ret;
return 0;
}
+int RGWMetadataManager::put_entry(RGWMetadataHandler *handler, string& key, bufferlist& bl, bool exclusive,
+ RGWObjVersionTracker *objv_tracker, map<string, bufferlist> *pattrs)
+{
+ string section;
+ RGWMetadataLogData log_data;
+ int ret = pre_modify(handler, section, key, log_data, objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ ret = handler->put_entry(store, key, bl, exclusive, objv_tracker, pattrs);
+ if (ret < 0)
+ return ret;
+
+ ret = post_modify(section, key, log_data, objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int RGWMetadataManager::set_attrs(RGWMetadataHandler *handler, string& key,
+ rgw_obj& obj, map<string, bufferlist>& attrs,
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker)
+{
+ string section;
+ RGWMetadataLogData log_data;
+ int ret = pre_modify(handler, section, key, log_data, objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ ret = store->set_attrs(NULL, obj, attrs, rmattrs, objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ ret = post_modify(section, key, log_data, objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
int trim(RGWRados *store, utime_t& from_time, utime_t& end_time);
};
+class RGWMetadataLogData;
+
class RGWMetadataManager {
map<string, RGWMetadataHandler *> handlers;
CephContext *cct;
void parse_metadata_key(const string& metadata_key, string& type, string& entry);
int find_handler(const string& metadata_key, RGWMetadataHandler **handler, string& entry);
+ int pre_modify(RGWMetadataHandler *handler, string& section, string& key,
+ RGWMetadataLogData& log_data, RGWObjVersionTracker *objv_tracker);
+ int post_modify(string& section, string& key, RGWMetadataLogData& log_data,
+ RGWObjVersionTracker *objv_tracker);
public:
RGWMetadataManager(CephContext *_cct, RGWRados *_store);
int put_entry(RGWMetadataHandler *handler, string& key, bufferlist& bl, bool exclusive,
RGWObjVersionTracker *objv_tracker, map<string, bufferlist> *pattrs = NULL);
+ int set_attr(RGWMetadataHandler *handler, string& key, rgw_obj& obj, string& attr, bufferlist& bl,
+ RGWObjVersionTracker *objv_tracker);
+ int set_attrs(RGWMetadataHandler *handler, string& key,
+ rgw_obj& obj, map<string, bufferlist>& attrs,
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker);
int get(string& metadata_key, Formatter *f);
int put(string& metadata_key, bufferlist& bl);
int remove(string& metadata_key);
int ret = 0;
if (obj.bucket.name.size()) {
- ret = store->get_attr(ctx, obj, RGW_ATTR_ACL, bl);
+ RGWObjVersionTracker objv_tracker;
+ ret = store->get_attr(ctx, obj, RGW_ATTR_ACL, bl, &objv_tracker);
if (ret >= 0) {
bufferlist::iterator iter = bl.begin();
/* object exists, but policy is broken */
RGWBucketInfo info;
RGWUserInfo uinfo;
- RGWObjVersionTracker objv_tracker;
int r = store->get_bucket_info(ctx, obj.bucket.name, info, &objv_tracker);
if (r < 0)
goto done;
return ret;
}
-static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs, uint64_t *obj_size)
+static int get_obj_attrs(RGWRados *store, struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs,
+ uint64_t *obj_size, RGWObjVersionTracker *objv_tracker)
{
void *handle;
int ret = store->prepare_get_obj(s->obj_ctx, obj, NULL, NULL, &attrs, NULL,
- NULL, NULL, NULL, NULL, NULL, obj_size, NULL, &handle, &s->err);
+ NULL, NULL, NULL, NULL, NULL, obj_size, objv_tracker, &handle, &s->err);
store->finish_get_obj(&handle);
return ret;
}
map<string, bufferlist>::iterator iter;
bufferlist bl, cors_bl;
+ bool object_op = (!s->object_str.empty());
+
rgw_obj obj(s->bucket, s->object_str);
store->set_atomic(s->obj_ctx, obj);
rgw_get_request_metadata(s, attrs);
+ RGWObjVersionTracker objv_tracker;
+
+ /* no need to track object versioning, need it for bucket's data only */
+ RGWObjVersionTracker *ptracker = (object_op ? NULL : &objv_tracker);
+
/* check if obj exists, read orig attrs */
- ret = get_obj_attrs(store, s, obj, orig_attrs, NULL);
+ ret = get_obj_attrs(store, s, obj, orig_attrs, NULL, ptracker);
if (ret < 0)
return;
cors_config.encode(cors_bl);
attrs[RGW_ATTR_CORS] = cors_bl;
}
- ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs);
+ if (object_op) {
+ ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
+ } else {
+ ret = rgw_bucket_set_attrs(store, obj, attrs, &rmattrs, ptracker);
+ }
}
int RGWDeleteObj::verify_permission()
*_dout << dendl;
}
+ bool object_op = (!s->object_str.empty());
+
+ RGWObjVersionTracker objv_tracker;
+ RGWObjVersionTracker *ptracker = (object_op ? NULL : &objv_tracker);
+
new_policy.encode(bl);
obj.init(s->bucket, s->object_str);
store->set_atomic(s->obj_ctx, obj);
- ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_ACL, bl);
+ ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_ACL, bl, ptracker);
}
int RGWGetCORS::verify_permission()
*_dout << dendl;
}
+ bool object_op = (!s->object_str.empty());
+
+ RGWObjVersionTracker objv_tracker;
+ RGWObjVersionTracker *ptracker = (object_op ? NULL : &objv_tracker);
+
string no_obj;
cors_config->encode(bl);
obj.init(s->bucket, no_obj);
store->set_atomic(s->obj_ctx, obj);
- ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, bl);
+ ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, bl, ptracker);
}
int RGWDeleteCORS::verify_permission()
store->set_atomic(s->obj_ctx, obj);
map<string, bufferlist> orig_attrs, attrs, rmattrs;
map<string, bufferlist>::iterator iter;
+ bool object_op = (!s->object_str.empty());
+
+ RGWObjVersionTracker objv_tracker;
+ RGWObjVersionTracker *ptracker = (object_op ? NULL : &objv_tracker);
+
/* check if obj exists, read orig attrs */
- ret = get_obj_attrs(store, s, obj, orig_attrs, NULL);
+ ret = get_obj_attrs(store, s, obj, orig_attrs, NULL, ptracker);
if (ret < 0)
return;
attrs[name] = iter->second;
}
}
- ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs);
+ ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
}
void RGWOptionsCORS::get_response_params(string& hdrs, string& exp_hdrs, unsigned *max_age) {
rgw_obj obj;
obj.init_ns(s->bucket, meta_oid, mp_ns);
- int ret = get_obj_attrs(store, s, obj, attrs, NULL);
+ int ret = get_obj_attrs(store, s, obj, attrs, NULL, NULL);
if (ret < 0)
return ret;
string no_object;
rgw_obj no_obj(s->bucket, no_object);
if (no_obj.bucket.name.size()) {
- ret = store->get_attr(s->obj_ctx, no_obj, RGW_ATTR_CORS, bl);
+ ret = store->get_attr(s->obj_ctx, no_obj, RGW_ATTR_CORS, bl, NULL);
if (ret >= 0) {
bufferlist::iterator iter = bl.begin();
s->bucket_cors = new RGWCORSConfiguration();
* dest: bufferlist to store the result in
* Returns: 0 on success, -ERR# otherwise.
*/
-int RGWRados::get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest)
+int RGWRados::get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest,
+ RGWObjVersionTracker *objv_tracker)
{
rgw_bucket bucket;
std::string oid, key;
return 0;
return -ENODATA;
}
+
+ ObjectReadOperation op;
+
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_read(&op);
+ }
+
+ int rval;
+ op.getxattr(name, &dest, &rval);
- r = io_ctx.getxattr(actual_obj, name, dest);
+ r = io_ctx.operate(actual_obj, &op, NULL);
if (r < 0)
return r;
* bl: the contents of the attr
* Returns: 0 on success, -ERR# otherwise.
*/
-int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl)
+int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl, RGWObjVersionTracker *objv_tracker)
{
rgw_bucket bucket;
std::string oid, key;
if (r < 0)
return r;
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_write(&op);
+ }
+
op.setxattr(name, bl);
io_ctx.locator_set_key(key);
int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
map<string, bufferlist>& attrs,
- map<string, bufferlist>* rmattrs)
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker)
{
rgw_bucket bucket;
std::string oid, key;
if (r < 0)
return r;
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_write(&op);
+ }
+
map<string, bufferlist>::iterator iter;
if (rmattrs) {
for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) {
}
}
if (if_match || if_nomatch) {
- r = get_attr(rctx, obj, RGW_ATTR_ETAG, etag);
+ r = get_attr(rctx, obj, RGW_ATTR_ETAG, etag, NULL);
if (r < 0)
goto done_err;
* dest: bufferlist to store the result in
* Returns: 0 on success, -ERR# otherwise.
*/
- virtual int get_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& dest);
+ virtual int get_attr(void *ctx, rgw_obj& obj, const char *name,
+ bufferlist& dest, RGWObjVersionTracker *objv_tracker);
/**
* Set an attr on an object.
* bl: the contents of the attr
* Returns: 0 on success, -ERR# otherwise.
*/
- virtual int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl);
+ virtual int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl,
+ RGWObjVersionTracker *objv_tracker);
virtual int set_attrs(void *ctx, rgw_obj& obj,
map<string, bufferlist>& attrs,
- map<string, bufferlist>* rmattrs);
+ map<string, bufferlist>* rmattrs,
+ RGWObjVersionTracker *objv_tracker);
/**
* Get data about an object out of RADOS and into memory.
* Store a list of the user's buckets, with associated functinos.
*/
-/**
- * Get all the buckets owned by a user and fill up an RGWUserBuckets with them.
- * Returns: 0 on success, -ERR# on failure.
- */
-//extern int rgw_read_user_buckets(RGWRados *store, string user_id, RGWUserBuckets& buckets, bool need_stats);
-
-/**
- * Store the set of buckets associated with a user.
- * This completely overwrites any previously-stored list, so be careful!
- * Returns 0 on success, -ERR# otherwise.
- */
-//extern int rgw_write_buckets_attr(RGWRados *store, string user_id, RGWUserBuckets& buckets);
-
-//extern int rgw_add_bucket(RGWRados *store, string user_id, rgw_bucket& bucket);
-//extern int rgw_remove_user_bucket_info(RGWRados *store, string user_id, rgw_bucket& bucket);
-
/*
* remove the different indexes
*/