]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement swift metadata POST
authorYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 19 Oct 2011 21:58:22 +0000 (14:58 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 19 Oct 2011 21:58:22 +0000 (14:58 -0700)
src/rgw/rgw_access.h
src/rgw/rgw_fs.cc
src/rgw/rgw_fs.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h

index 7020302db3839ce8817e2fa54366511c871e2e7b..2b6d08136dbfc6cb24eb55f5b39bb347e9b8480f 100644 (file)
@@ -72,7 +72,8 @@ public:
   /** write an object to the storage device in the appropriate pool
     with the given stats */
   virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
-                      map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive) = 0;
+                      map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+                      map<std::string, bufferlist>* rmattrs) = 0;
   virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
                       off_t ofs, size_t len) = 0;
   virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
@@ -83,7 +84,7 @@ public:
               time_t *mtime, map<std::string, bufferlist>& attrs) {
     int ret = put_obj_data(ctx, id, obj, data, -1, len);
     if (ret >= 0) {
-      ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false);
+      ret = put_obj_meta(ctx, id, obj, len, mtime, attrs, RGW_OBJ_CATEGORY_NONE, false, NULL);
     }
     return ret;
   }
index 21b714e3edd74e5398b9e1f5ce527e92aeb10a44..06e624dd580ff27d0354ac8744df16aa487cd4a9 100644 (file)
@@ -206,7 +206,8 @@ int RGWFS::create_bucket(std::string& id, rgw_bucket& bucket, map<std::string, b
 
 int RGWFS::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj,
                   uint64_t size, time_t *mtime, map<string, bufferlist>& attrs,
-                  RGWObjCategory category, bool exclusive)
+                  RGWObjCategory category, bool exclusive,
+                 map<std::string, bufferlist> *rmattrs)
 {
   rgw_bucket& bucket = obj.bucket;
   std::string& oid = obj.object;
index ce91624afb16e689c389d48f511deac2f335a284..664951ca5415624669214d3c81e6d2f844144ee5 100644 (file)
@@ -20,7 +20,8 @@ public:
 
   int create_bucket(std::string& id, rgw_bucket& bucket, map<std::string, bufferlist>& attrs, bool system_bucket, bool exclusive, uint64_t auid=0);
   int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
-             map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
+             map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+             map<std::string, bufferlist> *rmattrs);
   int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
               off_t ofs, size_t size);
   int copy_obj(void *ctx, std::string& id, rgw_obj& dest_obj,
index b3b3e931341753249716d1bb6dc91ead38a78a74..0164e3c62b24a5dfcd75d1112a45762e2078af24 100644 (file)
@@ -163,6 +163,15 @@ static int get_policy_from_attr(void *ctx, RGWAccessControlPolicy *policy, rgw_o
   return ret;
 }
 
+static int get_obj_attrs(struct req_state *s, rgw_obj& obj, map<string, bufferlist>& attrs)
+{
+  void *handle;
+  int ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, 0, NULL, &attrs, NULL,
+                                      NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err);
+  rgwstore->finish_get_obj(&handle);
+  return ret;
+}
+
 int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
 {
   string upload_id;
@@ -771,7 +780,7 @@ void RGWPutObj::execute()
           goto done;
       }
     } else {
-      ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
+      ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
       if (ret < 0)
         goto done_err;
 
@@ -802,6 +811,47 @@ done_err:
   send_response();
 }
 
+int RGWPutObjMetadata::verify_permission()
+{
+  if (!::verify_permission(s, RGW_PERM_WRITE))
+    return -EACCES;
+
+  return 0;
+}
+
+void RGWPutObjMetadata::execute()
+{
+  ret = -EINVAL;
+
+  const char *meta_prefix = RGW_ATTR_META_PREFIX;
+  int meta_prefix_len = sizeof(RGW_ATTR_META_PREFIX) - 1;
+  map<string, bufferlist> attrs, orig_attrs, rmattrs;
+  map<string, bufferlist>::iterator iter;
+  get_request_metadata(s, attrs);
+
+  rgw_obj obj(s->bucket, s->object_str);
+
+  rgwstore->set_atomic(s->obj_ctx, obj);
+
+  /* check if obj exists, read orig attrs */
+  ret = get_obj_attrs(s, obj, orig_attrs);
+  if (ret < 0)
+    goto done;
+
+  /* only remove meta attrs */
+  for (iter = orig_attrs.begin(); iter != orig_attrs.end(); ++iter) {
+    const string& name = iter->first;
+    if (name.compare(0, meta_prefix_len, meta_prefix) == 0) {
+      rmattrs[name] = iter->second;
+    }
+  }
+
+  ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, &rmattrs);
+
+done:
+  send_response();
+}
+
 int RGWDeleteObj::verify_permission()
 {
   if (!::verify_permission(s, RGW_PERM_WRITE))
@@ -1208,7 +1258,7 @@ void RGWInitMultipart::execute()
 
     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, s->user.user_id, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true);
+    ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL);
   } while (ret == -EEXIST);
 done:
   send_response();
@@ -1217,17 +1267,13 @@ done:
 static int get_multiparts_info(struct req_state *s, string& meta_oid, map<uint32_t, RGWUploadPartInfo>& parts,
                                RGWAccessControlPolicy& policy, map<string, bufferlist>& attrs)
 {
-  void *handle;
   map<string, bufferlist> parts_map;
   map<string, bufferlist>::iterator iter;
   bufferlist header;
 
   rgw_obj obj(s->bucket, meta_oid, s->object_str, mp_ns);
 
-  int ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, 0, NULL, &attrs, NULL,
-                                      NULL, NULL, NULL, NULL, NULL, NULL, &handle, &s->err);
-  rgwstore->finish_get_obj(&handle);
-
+  int ret = get_obj_attrs(s, obj, attrs);
   if (ret < 0)
     return ret;
 
@@ -1361,7 +1407,7 @@ void RGWCompleteMultipart::execute()
 
   target_obj.init(s->bucket, s->object_str);
   rgwstore->set_atomic(s->obj_ctx, target_obj);
-  ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false);
+  ret = rgwstore->put_obj_meta(s->obj_ctx, s->user.user_id, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL);
   if (ret < 0)
     goto done;
   
index e6bc5e2517b16a0a57296a80366e5bc899f5e05c..e54d2a98849ed00e60ff9185c3ef1fad7cdf6599 100644 (file)
@@ -266,6 +266,23 @@ public:
   virtual void send_response() = 0;
 };
 
+class RGWPutObjMetadata : public RGWOp {
+protected:
+  int ret;
+
+public:
+  RGWPutObjMetadata() {}
+
+  virtual void init(struct req_state *s) {
+    RGWOp::init(s);
+    ret = 0;
+  }
+  int verify_permission();
+  void execute();
+
+  virtual void send_response() = 0;
+};
+
 class RGWDeleteObj : public RGWOp {
 protected:
   int ret;
index 73bfb75f8c7516cfaf094abaaae0a9414dc3cab9..e2ad4d5cde295533743cd007ee5eede3f14e1f15 100644 (file)
@@ -605,7 +605,8 @@ int RGWRados::create_pools(std::string& id, vector<string>& names, vector<int>&
  * Returns: 0 on success, -ERR# otherwise.
  */
 int RGWRados::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj,  uint64_t size,
-                  time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive)
+                  time_t *mtime, map<string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+                  map<string, bufferlist>* rmattrs)
 {
   rgw_bucket bucket;
   std::string oid, key;
@@ -627,6 +628,13 @@ int RGWRados::put_obj_meta(void *ctx, std::string& id, rgw_obj& obj,  uint64_t s
   bufferlist acl_bl;
 
   map<string, bufferlist>::iterator iter;
+  if (rmattrs) {
+    for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) {
+      const string& name = iter->first;
+      op.rmxattr(name.c_str());
+    }
+  }
+
   for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
     const string& name = iter->first;
     bufferlist& bl = iter->second;
index a2413c8309e7edbecb746e506043cc442b195bc3..331d0eb83ca39ef515ab8added4a596f4106b549 100644 (file)
@@ -171,7 +171,8 @@ public:
 
   /** Write/overwrite an object to the bucket storage. */
   virtual int put_obj_meta(void *ctx, std::string& id, rgw_obj& obj, uint64_t size, time_t *mtime,
-              map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive);
+              map<std::string, bufferlist>& attrs, RGWObjCategory category, bool exclusive,
+              map<std::string, bufferlist>* rmattrs);
   virtual int put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
               off_t ofs, size_t len);
   virtual int aio_put_obj_data(void *ctx, std::string& id, rgw_obj& obj, const char *data,
index 178e767d45de2438f9d1b6918fb247c61c398c94..7aeb0d5c195778a8cf1c23bc12cd59795b8111f6 100644 (file)
@@ -66,6 +66,13 @@ public:
   int get_data();
 };
 
+class RGWPutObjMetadata_REST : public RGWPutObjMetadata
+{
+public:
+  RGWPutObjMetadata_REST() {}
+  ~RGWPutObjMetadata_REST() {}
+};
+
 class RGWDeleteObj_REST : public RGWDeleteObj {
 public:
   RGWDeleteObj_REST() {}
index 45155e1abd333563df1cf46348400e75de8dfd89..5706ea2edeb17ea67d3f0c4340b06737f971f7d8 100644 (file)
@@ -247,6 +247,16 @@ void RGWPutObj_REST_SWIFT::send_response()
   flush_formatter_to_req_state(s, s->formatter);
 }
 
+void RGWPutObjMetadata_REST_SWIFT::send_response()
+{
+  if (!ret)
+    ret = STATUS_ACCEPTED;
+  set_req_state_err(s, ret);
+  dump_errno(s);
+  end_header(s);
+  flush_formatter_to_req_state(s, s->formatter);
+}
+
 void RGWDeleteObj_REST_SWIFT::send_response()
 {
   int r = ret;
@@ -376,6 +386,14 @@ RGWOp *RGWHandler_REST_SWIFT::get_delete_op()
   return NULL;
 }
 
+RGWOp *RGWHandler_REST_SWIFT::get_post_op()
+{
+  if (s->object)
+    return new RGWPutObjMetadata_REST_SWIFT;
+
+  return NULL;
+}
+
 int RGWHandler_REST_SWIFT::authorize()
 {
   bool authorized = rgw_verify_os_token(s);
index 3f78c8a3a0f3c8bae3be06d3b6283e17c76bb805..fde210100c196bd1bb7370c53ae4cfebe333c9f9 100644 (file)
@@ -80,6 +80,14 @@ public:
   void send_response();
 };
 
+class RGWPutObjMetadata_REST_SWIFT : public RGWPutObjMetadata_REST {
+public:
+  RGWPutObjMetadata_REST_SWIFT() {}
+  ~RGWPutObjMetadata_REST_SWIFT() {}
+
+  void send_response();
+};
+
 class RGWDeleteObj_REST_SWIFT : public RGWDeleteObj_REST {
 public:
   RGWDeleteObj_REST_SWIFT() {}
@@ -120,7 +128,7 @@ protected:
   RGWOp *get_retrieve_op(bool get_data);
   RGWOp *get_create_op();
   RGWOp *get_delete_op();
-  RGWOp *get_post_op() { return NULL; }
+  RGWOp *get_post_op();
 
 public:
   RGWHandler_REST_SWIFT() : RGWHandler_REST() {}