From: Supriti Singh Date: Mon, 20 Nov 2017 15:08:59 +0000 (+0100) Subject: RGW-NFS: Use rados cluster_stat to report filesystem usage X-Git-Tag: v12.2.6~51^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6ca7920650404ea569778b67b99d1e9554a9f7a4;p=ceph.git RGW-NFS: Use rados cluster_stat to report filesystem usage Partially fixes: http://tracker.ceph.com/issues/22202 Signed-off-by: Supriti Singh (cherry picked from commit 29630cb0e27c08f5dcc38fe48c43f55aeb2d726f) --- diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 38642110f949..2f4daf0e7ffa 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -23,9 +23,9 @@ #include "rgw_auth_s3.h" #include "rgw_user.h" #include "rgw_bucket.h" - #include "rgw_file.h" #include "rgw_lib_frontend.h" +#include "common/errno.h" #include @@ -1487,7 +1487,7 @@ namespace rgw { op_ret = processor->complete(s->obj_size, etag, &mtime, real_time(), attrs, (delete_at ? *delete_at : real_time()), - if_match, if_nomatch); + if_match, if_nomatch); if (op_ret != 0) { /* revert attr updates */ rgw_fh->set_mtime(omtime); @@ -1611,16 +1611,25 @@ int rgw_statfs(struct rgw_fs *rgw_fs, struct rgw_statvfs *vfs_st, uint32_t flags) { RGWLibFS *fs = static_cast(rgw_fs->fs_private); + struct rados_cluster_stat_t stats; + + RGWGetClusterStatReq req(fs->get_context(), fs->get_user(), stats); + int rc = rgwlib.get_fe()->execute_req(&req); + if (rc < 0) { + lderr(fs->get_context()) << "ERROR: getting total cluster usage" + << cpp_strerror(-rc) << dendl; + return rc; + } - /* XXX for now, just publish a huge capacity and - * limited utiliztion */ - vfs_st->f_bsize = 1024*1024 /* 1M */; - vfs_st->f_frsize = 1024; /* minimal allocation unit (who cares) */ - vfs_st->f_blocks = UINT64_MAX; - vfs_st->f_bfree = UINT64_MAX; - vfs_st->f_bavail = UINT64_MAX; - vfs_st->f_files = 1024; /* object count, do we have an est? */ - vfs_st->f_ffree = UINT64_MAX; + //Set block size to 1M. + constexpr uint32_t CEPH_BLOCK_SHIFT = 20; + vfs_st->f_bsize = 1 << CEPH_BLOCK_SHIFT; + vfs_st->f_frsize = 1 << CEPH_BLOCK_SHIFT; + vfs_st->f_blocks = stats.kb >> (CEPH_BLOCK_SHIFT - 10); + vfs_st->f_bfree = stats.kb_avail >> (CEPH_BLOCK_SHIFT - 10); + vfs_st->f_bavail = stats.kb_avail >> (CEPH_BLOCK_SHIFT - 10); + vfs_st->f_files = stats.num_objects; + vfs_st->f_ffree = -1; vfs_st->f_fsid[0] = fs->get_fsid(); vfs_st->f_fsid[1] = fs->get_fsid(); vfs_st->f_flag = 0; @@ -1856,7 +1865,7 @@ int rgw_open(struct rgw_fs *rgw_fs, { RGWFileHandle* rgw_fh = get_rgwfh(fh); - /* XXX + /* XXX * need to track specific opens--at least read opens and * a write open; we need to know when a write open is returned, * that closes a write transaction diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 7b7b8aa4d352..bfb95be737ab 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -2528,6 +2528,49 @@ public: }; /* RGWSetAttrsRequest */ +/* + * Send request to get the rados cluster stats + */ +class RGWGetClusterStatReq : public RGWLibRequest, + public RGWGetClusterStat { +public: + struct rados_cluster_stat_t& stats_req; + RGWGetClusterStatReq(CephContext* _cct,RGWUserInfo *_user, + rados_cluster_stat_t& _stats): + RGWLibRequest(_cct, _user), stats_req(_stats){ + op = this; + } + + int op_init() override { + // assign store, s, and dialect_handler + RGWObjectCtx* rados_ctx + = static_cast(get_state()->obj_ctx); + // framework promises to call op_init after parent init + assert(rados_ctx); + RGWOp::init(rados_ctx->store, get_state(), this); + op = this; // assign self as op: REQUIRED + return 0; + } + + int header_init() override { + struct req_state* s = get_state(); + s->info.method = "GET"; + s->op = OP_GET; + s->user = user; + return 0; + } + + int get_params() override { return 0; } + bool only_bucket() override { return false; } + void send_response() override { + stats_req.kb = stats_op.kb; + stats_req.kb_avail = stats_op.kb_avail; + stats_req.kb_used = stats_op.kb_used; + stats_req.num_objects = stats_op.num_objects; + } +}; /* RGWGetClusterStatReq */ + + } /* namespace rgw */ #endif /* RGW_FILE_H */ diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f20cbd9b862b..14b3f404b1e2 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -7003,3 +7003,10 @@ void RGWDeleteBucketPolicy::execute() return op_ret; }); } + +void RGWGetClusterStat::execute() +{ + op_ret = this->store->get_rados_handle()->cluster_stat(stats_op); +} + + diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 0a127d2a9a46..82ebe53e1922 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -2193,4 +2193,22 @@ public: virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } }; +class RGWGetClusterStat : public RGWOp { +protected: + struct rados_cluster_stat_t stats_op; +public: + RGWGetClusterStat() {} + + void init(RGWRados *store, struct req_state *s, RGWHandler *h) override { + RGWOp::init(store, s, h); + } + int verify_permission() override {return 0;} + virtual void send_response() = 0; + virtual int get_params() = 0; + void execute() override; + virtual const string name() { return "get_cluster_stat"; } +}; + + + #endif /* CEPH_RGW_OP_H */