]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix bucket suspension
authorYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 26 Oct 2011 21:30:26 +0000 (14:30 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 26 Oct 2011 21:30:50 +0000 (14:30 -0700)
src/rgw/rgw_access.h
src/rgw/rgw_admin.cc
src/rgw/rgw_common.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

index 0e421dc22687ebe5b3e66c5fc57c89b1929b443a..204dd38506cce948766654705e224a277cd3e17f 100644 (file)
@@ -128,8 +128,7 @@ public:
   virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool) = 0;
   virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets) { return -ENOTSUP; }
 
-  virtual int disable_buckets(std::vector<rgw_bucket>& buckets) { return -ENOTSUP; }
-  virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid) { return -ENOTSUP; }
+  virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled) { return -ENOTSUP; }
   virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended) {
     *suspended = false;
     return 0;
@@ -271,6 +270,7 @@ public:
   /* The bucket here can either be the bucket name identifier, or the ID
    * in period format: ".123" */
   virtual int get_bucket_info(void *ctx, string& bucket, RGWBucketInfo& info) = 0;
+  virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info) = 0;
 
 
   virtual int remove_temp_objects(string date, string time) {
index e8ae9cc519fbe0b12b4d600187e37ac9524222ed..3747ad72daa34b0ebad7fe30f12161343efcd2cd 100644 (file)
@@ -1218,10 +1218,7 @@ int main(int argc, char **argv)
       RGWBucketEnt obj = iter->second;
       bucket_names.push_back(obj.bucket);
     }
-    if (disable)
-      ret = rgwstore->disable_buckets(bucket_names);
-    else
-      ret = rgwstore->enable_buckets(bucket_names, info.auid);
+    ret = rgwstore->set_buckets_enabled(bucket_names, !disable);
     if (ret < 0) {
       cerr << "ERROR: failed to change pool" << std::endl;
       return 1;
index 8d5c66a928d6618dd80290ec0e962eaf11e56a7c..72c4ed8b93333de8c882344861096214ded29880 100644 (file)
@@ -430,24 +430,34 @@ inline ostream& operator<<(ostream& out, const rgw_bucket b) {
 
 extern rgw_bucket rgw_root_bucket;
 
+enum RGWBucketFlags {
+  BUCKET_SUSPENDED = 0x1,
+};
+
 struct RGWBucketInfo
 {
   rgw_bucket bucket;
   string owner;
+  uint32_t flags;
 
   void encode(bufferlist& bl) const {
-     __u32 ver = 2;
+     __u32 ver = 3;
      ::encode(ver, bl);
      ::encode(bucket, bl);
      ::encode(owner, bl);
+     ::encode(flags, bl);
   }
   void decode(bufferlist::iterator& bl) {
      __u32 ver;
      ::decode(ver, bl);
      ::decode(bucket, bl);
-     if (ver > 1)
+     if (ver >= 2)
        ::decode(owner, bl);
+     if (ver >= 3)
+       ::decode(flags, bl);
   }
+
+  RGWBucketInfo() : flags(0) {}
 };
 WRITE_CLASS_ENCODER(RGWBucketInfo)
 
@@ -545,12 +555,11 @@ struct RGWObjEnt {
   }
 };
 
-/** Store basic data on an object */
+/** Store basic data on bucket */
 struct RGWBucketEnt {
   rgw_bucket bucket;
   size_t size;
   time_t mtime;
-  string etag;
   uint64_t count;
 
   void encode(bufferlist& bl) const {
@@ -583,7 +592,6 @@ struct RGWBucketEnt {
     bucket.clear();
     size = 0;
     mtime = 0;
-    etag = "";
     count = 0;
   }
 };
index 3b9c1d0b85bd438052bc87b2af82b14684a372e7..9f213464ddfddb6fb4911711787aba1112bd15b0 100644 (file)
@@ -667,3 +667,8 @@ int RGWFS::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info)
 {
   return -ENOTSUP;
 }
+
+int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info)
+{
+  return -ENOTSUP;
+}
index ec1957afc1f61221f8749da35c6ba9cb7b05a043..56e2959936a564bd27a703c1b9145f5523d04478 100644 (file)
@@ -63,6 +63,7 @@ public:
   int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs);
 
   virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info);
+  virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info);
 };
 
 #endif
index 2c75cc2f313c8ab131e674275290d1a2c7e02188..7e4507ddbe841db09d5104d4eaf7276b17d226a5 100644 (file)
@@ -172,21 +172,16 @@ static int get_obj_attrs(struct req_state *s, rgw_obj& obj, map<string, bufferli
   return ret;
 }
 
-int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
+static int read_acls(struct req_state *s, RGWBucketInfo& bucket_info, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
 {
   string upload_id;
   url_decode(s->args.get("uploadId"), upload_id);
   string oid = object;
   rgw_obj obj;
 
-  if (!oid.empty()) {
-    bool suspended;
-    int ret = rgwstore->bucket_suspended(bucket, &suspended);
-    if (ret < 0)
-      return ret;
-
-    if (suspended)
-      return -ERR_USER_SUSPENDED;
+  if (bucket_info.flags & BUCKET_SUSPENDED) {
+    dout(0) << "bucket " << bucket_info.bucket.name << " is suspended" << dendl;
+    return -ERR_USER_SUSPENDED;
   }
 
   if (!oid.empty() && !upload_id.empty()) {
@@ -224,7 +219,7 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& b
  * only_bucket: If true, reads the bucket ACL rather than the object ACL.
  * Returns: 0 on success, -ERR# otherwise.
  */
-int read_acls(struct req_state *s, bool only_bucket)
+static int read_acls(struct req_state *s, bool only_bucket)
 {
   int ret = 0;
   string obj_str;
@@ -242,8 +237,8 @@ int read_acls(struct req_state *s, bool only_bucket)
     rgwstore->set_atomic(s->obj_ctx, obj);
   }
 
+  RGWBucketInfo bucket_info;
   if (s->bucket_name_str.size()) {
-    RGWBucketInfo bucket_info;
     ret = rgwstore->get_bucket_info(s->obj_ctx, s->bucket_name_str, bucket_info);
     if (ret < 0) {
       dout(0) << "couldn't get bucket from bucket_name (name=" << s->bucket_name_str << ")" << dendl;
@@ -253,7 +248,7 @@ int read_acls(struct req_state *s, bool only_bucket)
     s->bucket_owner = bucket_info.owner;
   }
 
-  ret = read_acls(s, s->acl, s->bucket, obj_str);
+  ret = read_acls(s, bucket_info, s->acl, s->bucket, obj_str);
 
   return ret;
 }
@@ -926,7 +921,7 @@ int RGWCopyObj::verify_permission()
   src_bucket = bucket_info.bucket;
 
   /* just checking the bucket's permission */
-  ret = read_acls(s, &src_policy, src_bucket, empty_str);
+  ret = read_acls(s, bucket_info, &src_policy, src_bucket, empty_str);
   if (ret < 0)
     return ret;
 
@@ -1008,7 +1003,7 @@ int RGWGetACLs::verify_permission()
 
 void RGWGetACLs::execute()
 {
-  ret = read_acls(s);
+  ret = read_acls(s, false);
 
   if (ret < 0) {
     send_response();
index e54d2a98849ed00e60ff9185c3ef1fad7cdf6599..2e6fe39039cb706939ce8325e94c694cd6f3226f 100644 (file)
@@ -22,13 +22,6 @@ struct req_state;
 
 /** Get the HTTP request metadata */
 extern void get_request_metadata(struct req_state *s, map<string, bufferlist>& attrs);
-/**
- * Get the ACL for an object off of disk. If you hold the req_state, use next
- * method.
- */
-extern int read_acls(RGWAccessControlPolicy *policy, rgw_obj& bucket, string& object);
-/** Get the ACL needed for a request off of disk.*/
-extern int read_acls(struct req_state *s, bool only_bucket = false);
 
 /**
  * Provide the base class for all ops.
index d2c235f0115b6c1637039d95add5c9d1d46596c1..48d15fa1fd446ea17fd343b55c23e7dc90024038 100644 (file)
@@ -939,56 +939,51 @@ int RGWRados::purge_buckets(std::string& id, vector<rgw_bucket>& buckets)
   return ret;
 }
 
-int RGWRados::set_buckets_auid(vector<rgw_bucket>& buckets, uint64_t auid)
+int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
 {
-  librados::IoCtx ctx;
-  vector<librados::PoolAsyncCompletion *> completions;
+  int ret = 0;
 
   vector<rgw_bucket>::iterator iter;
+
   for (iter = buckets.begin(); iter != buckets.end(); ++iter) {
     rgw_bucket& bucket = *iter;
-    int r = open_bucket_ctx(bucket, ctx);
-    if (r < 0)
-      return r;
+    if (enabled)
+      dout(20) << "enabling bucket name=" << bucket.name << dendl;
+    else
+      dout(20) << "disabling bucket name=" << bucket.name << dendl;
 
-    librados::PoolAsyncCompletion *c = librados::Rados::pool_async_create_completion();
-    completions.push_back(c);
-    ctx.set_auid_async(auid, c);
-  }
+    RGWBucketInfo info;
+    int r = get_bucket_info(NULL, bucket.name, info);
+    if (r < 0) {
+      dout(0) << "get_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
+      ret = r;
+      continue;
+    }
+    if (enabled) {
+      info.flags &= ~BUCKET_SUSPENDED;
+    } else {
+      info.flags |= BUCKET_SUSPENDED;
+    }
 
-  vector<librados::PoolAsyncCompletion *>::iterator citer;
-  for (citer = completions.begin(); citer != completions.end(); ++citer) {
-    PoolAsyncCompletion *c = *citer;
-    c->wait();
-    c->release();
+    r = put_bucket_info(bucket.name, info);
+    if (r < 0) {
+      dout(0) << "put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
+      ret = r;
+      continue;
+    }
   }
-
   return 0;
 }
 
-int RGWRados::disable_buckets(vector<rgw_bucket>& buckets)
-{
-  return set_buckets_auid(buckets, RGW_SUSPENDED_USER_AUID);
-}
-
-int RGWRados::enable_buckets(vector<rgw_bucket>& buckets, uint64_t auid)
-{
-  return set_buckets_auid(buckets, auid);
-}
-
 int RGWRados::bucket_suspended(rgw_bucket& bucket, bool *suspended)
 {
-  librados::IoCtx ctx;
-  int r = open_bucket_ctx(bucket, ctx);
-  if (r < 0)
-    return r;
-
-  uint64_t auid;
-  int ret = ctx.get_auid(&auid);
-  if (ret < 0)
+  RGWBucketInfo bucket_info;
+  int ret = rgwstore->get_bucket_info(NULL, bucket.name, bucket_info);
+  if (ret < 0) {
     return ret;
+  }
 
-  *suspended = (auid == RGW_SUSPENDED_USER_AUID);
+  *suspended = ((bucket_info.flags & BUCKET_SUSPENDED) != 0);
   return 0;
 }
 
@@ -1789,6 +1784,7 @@ int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime,
     mtime = ut.sec();
   } catch (buffer::error& err) {
     dout(0) << "ERROR: failed decoding object (obj=" << obj << ") info (either size or mtime), aborting" << dendl;
+    return -EIO;
   }
   if (psize)
     *psize = size;
@@ -1848,6 +1844,18 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
   return 0;
 }
 
+int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info)
+{
+  bufferlist bl;
+
+  ::encode(info, bl);
+
+  string unused;
+
+  int ret = rgw_put_obj(unused, pi_buckets_rados, bucket_name, bl.c_str(), bl.length());
+
+  return ret;
+}
 
 int RGWRados::tmap_get(rgw_obj& obj, bufferlist& header, std::map<string, bufferlist>& m)
 {
index 63379be990a64bb4e82d5528a369d78f04caeaea..2ae5a5d01d1c6208669f996b9d507d48313f16e3 100644 (file)
@@ -239,8 +239,7 @@ public:
   virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool);
   virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets);
 
-  virtual int disable_buckets(std::vector<rgw_bucket>& buckets);
-  virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid);
+  virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled);
   virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended);
 
   /** Delete an object.*/
@@ -309,6 +308,7 @@ public:
   int decode_policy(bufferlist& bl, ACLOwner *owner);
   int get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats);
   virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info);
+  virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info);
 
   int cls_rgw_init_index(rgw_bucket& bucket, string& oid);
   int cls_obj_prepare_op(rgw_bucket& bucket, uint8_t op, string& tag,