return fhr;
} /* RGWLibFS::stat_leaf */
+ int RGWLibFS::rename(RGWFileHandle* src_fh, RGWFileHandle* dst_fh,
+ const char *src_name, const char *dst_name)
+
+ {
+ /* XXX initial implementation: try-copy, and delete if copy
+ * succeeds */
+ for (int ix : {0, 1}) {
+ switch (ix) {
+ case 0:
+ {
+ RGWCopyObjRequest req(cct, get_user(), src_fh, dst_fh, src_name,
+ dst_name);
+ int rc = rgwlib.get_fe()->execute_req(&req);
+ if ((rc != 0) ||
+ ((rc = req.get_ret()) != 0)) {
+ return rc;
+ }
+ }
+ break;
+ case 1:
+ {
+ RGWDeleteObjRequest req(cct, get_user(), src_fh->bucket_name(),
+ src_name);
+ int rc = rgwlib.get_fe()->execute_req(&req);
+ if (! rc) {
+ rc = req.get_ret();
+ return rc;
+ }
+ }
+ break;
+ default:
+ abort();
+ } /* switch */
+
+ return -EINVAL;
+ }
+
+ return EINVAL;
+ } /* RGWLibFS::rename */
+
int RGWLibFS::getattr(RGWFileHandle* rgw_fh, struct stat* st)
{
switch(rgw_fh->fh.fh_type) {
struct rgw_file_handle *newdir, const char* new_name,
uint32_t flags)
{
- /* -ENOTSUP */
- return -EINVAL;
+ RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+
+ RGWFileHandle* old_fh = get_rgwfh(olddir);
+ RGWFileHandle* new_fh = get_rgwfh(newdir);
+
+ return -(fs->rename(old_fh, new_fh, old_name, new_name));
}
/*
inline std::string relative_object_name() {
return full_object_name(true /* omit_bucket */);
}
-
+
+ inline std::string format_child_name(const std::string& cbasename) {
+ std::string child_name{relative_object_name()};
+ if ((child_name.size() > 0) &&
+ (child_name.back() != '/'))
+ child_name += "/";
+ child_name += cbasename;
+ return child_name;
+ }
+
inline std::string make_key_name(const char *name) {
std::string key_name{full_object_name()};
if (key_name.length() > 0)
LookupFHResult stat_leaf(RGWFileHandle* parent, const char *path,
uint32_t flags);
+ int rename(RGWFileHandle* old_fh, RGWFileHandle* new_fh,
+ const char *old_name, const char *new_name);
+
/* find existing RGWFileHandle */
RGWFileHandle* lookup_handle(struct rgw_fh_hk fh_hk) {
/*
put object
*/
-
class RGWPutObjRequest : public RGWLibRequest,
public RGWPutObj /* RGWOp */
{
}
}; /* RGWWriteRequest */
+/*
+ copy object
+*/
+class RGWCopyObjRequest : public RGWLibRequest,
+ public RGWCopyObj /* RGWOp */
+{
+public:
+ RGWFileHandle* src_parent;
+ RGWFileHandle* dst_parent;
+ const std::string& src_name;
+ const std::string& dst_name;
+
+ RGWCopyObjRequest(CephContext* _cct, RGWUserInfo *_user,
+ RGWFileHandle* _src_parent, RGWFileHandle* _dst_parent,
+ const std::string& _src_name, const std::string& _dst_name)
+ : RGWLibRequest(_cct, _user), src_parent(_src_parent),
+ dst_parent(_dst_parent), src_name(_src_name), dst_name(_dst_name) {
+ magic = 82;
+ op = this;
+ }
+
+ virtual bool only_bucket() { return true; }
+
+ virtual int op_init() {
+ // assign store, s, and dialect_handler
+ RGWObjectCtx* rados_ctx
+ = static_cast<RGWObjectCtx*>(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;
+ }
+
+ virtual int header_init() {
+
+ struct req_state* s = get_state();
+ s->info.method = "PUT"; // XXX check
+ s->op = OP_PUT;
+
+ src_bucket_name = src_parent->bucket_name();
+ // need s->src_bucket_name?
+ src_object.name = src_parent->format_child_name(src_name);
+ // need s->src_object?
+
+ dest_bucket_name = dst_parent->bucket_name();
+ // need s->bucket.name?
+ dest_object = dst_parent->format_child_name(dst_name);
+ // need s->object_name?
+
+ if (! valid_s3_object_name(dest_object))
+ return -ERR_INVALID_OBJECT_NAME;
+
+#if 0 /* XXX needed? */
+ s->relative_uri = uri;
+ s->info.request_uri = uri; // XXX
+ s->info.effective_uri = uri;
+ s->info.request_params = "";
+ s->info.domain = ""; /* XXX ? */
+#endif
+
+ // woo
+ s->user = user;
+
+ return 0;
+ }
+
+ virtual int get_params() {
+ struct req_state* s = get_state();
+ RGWAccessControlPolicy_S3 s3policy(s->cct);
+ /* we don't have (any) headers, so just create canned ACLs */
+ int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+ dest_policy = s3policy;
+ return ret;
+ }
+
+ virtual void send_response() {}
+ virtual void send_partial_response(off_t ofs) {}
+
+}; /* RGWCopyObjRequest */
+
+
} /* namespace rgw */
#endif /* RGW_FILE_H */