/* * user object name -> struct kv_onode -> sheepdog objects -> user data * * onode is a index node that maps name to sheepdog objects which hold the user * data, similar to UNIX inode. We use simple hashing for [name, onode] mapping. */ int kv_create_object(struct http_request *req, const char *account, const char *bucket, const char *name) { char vdi_name[SD_MAX_VDI_LEN]; struct kv_onode *onode; uint32_t bucket_vid, data_vid; int ret; snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket); ret = sd_lookup_vdi(vdi_name, &bucket_vid); if (ret != SD_RES_SUCCESS) return ret; onode = xzalloc(sizeof(*onode)); ret = onode_lookup(onode, bucket_vid, name); if (ret == SD_RES_SUCCESS) { /* For overwrite, we delete old object and then create */ ret = kv_delete_object(account, bucket, name); if (ret != SD_RES_SUCCESS) { sd_err("Failed to delete exists object %s", name); goto out; } } else if (ret != SD_RES_NO_OBJ) goto out; snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s/allocator", account, bucket); ret = sd_lookup_vdi(vdi_name, &data_vid); if (ret != SD_RES_SUCCESS) goto out; memset(onode, 0, sizeof(*onode)); pstrcpy(onode->name, sizeof(onode->name), name); onode->data_vid = data_vid; ret = onode_populate_data(onode, req); if (ret != SD_RES_SUCCESS) { sd_err("failed to write data for %s", name); goto out; } ret = onode_create(onode, bucket_vid); if (ret != SD_RES_SUCCESS) { sd_err("failed to create onode for %s", name); onode_free_data(onode); goto out; } ret = bnode_update(account, bucket, req->data_length, true); if (ret != SD_RES_SUCCESS) { sd_err("failed to update bucket for %s", name); onode_delete(onode); goto out; } out: free(onode); return ret; }
static void swift_delete_object(struct http_request *req, const char *account, const char *container, const char *object) { int ret; ret = kv_delete_object(account, container, object); switch (ret) { case SD_RES_SUCCESS: http_response_header(req, NO_CONTENT); break; case SD_RES_NO_VDI: case SD_RES_NO_OBJ: http_response_header(req, NOT_FOUND); break; default: http_response_header(req, INTERNAL_SERVER_ERROR); break; } }