int abb_fread(void *mod_priv, uint64_t src_off, uint64_t src_len, struct elasto_data *dest_data) { int ret; struct op *op; struct apb_fh *apb_fh = mod_priv; ret = az_req_blob_get(&apb_fh->path, false, dest_data, src_off, src_len, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(apb_fh->io_conn, op); if (ret < 0) { goto err_op_free; } ret = 0; err_op_free: op->rsp.data = NULL; op_free(op); err_out: return ret; }
static int apb_fstat_blob(struct apb_fh *apb_fh, struct elasto_fstat *fstat) { int ret; struct op *op; struct az_rsp_blob_prop_get *blob_prop_get_rsp; ret = az_req_blob_prop_get(&apb_fh->path, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(apb_fh->io_conn, op); if (ret < 0) { goto err_op_free; } blob_prop_get_rsp = az_rsp_blob_prop_get(op); if (blob_prop_get_rsp == NULL) { ret = -ENOMEM; goto err_op_free; } if (!blob_prop_get_rsp->is_page) { /* should have been checked on open */ dbg(0, "blob flagged as block in stat for page blob!\n"); ret = -EINVAL; goto err_op_free; } fstat->ent_type = ELASTO_FSTAT_ENT_FILE; fstat->size = blob_prop_get_rsp->len; fstat->blksize = 512; if (blob_prop_get_rsp->lease_status == AOP_LEASE_STATUS_UNLOCKED) { fstat->lease_status = ELASTO_FLEASE_UNLOCKED; } else if (blob_prop_get_rsp->lease_status == AOP_LEASE_STATUS_LOCKED) { fstat->lease_status = ELASTO_FLEASE_LOCKED; } /* flag which values are valid in the stat response */ fstat->field_mask = (ELASTO_FSTAT_FIELD_TYPE | ELASTO_FSTAT_FIELD_SIZE | ELASTO_FSTAT_FIELD_BSIZE | ELASTO_FSTAT_FIELD_LEASE); ret = 0; err_op_free: op_free(op); err_out: return ret; }
static int apb_fstat_acc(struct apb_fh *apb_fh, struct elasto_fstat *fstat) { int ret; struct op *op; struct az_mgmt_rsp_acc_prop_get *acc_prop_get_rsp; if (apb_fh->mgmt_conn == NULL) { dbg(0, "Account stat requires Publish Settings " "credentials\n"); ret = -EINVAL; goto err_out; } ret = az_mgmt_req_acc_prop_get(apb_fh->sub_id, apb_fh->path.acc, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(apb_fh->mgmt_conn, op); if (ret < 0) { goto err_op_free; } acc_prop_get_rsp = az_mgmt_rsp_acc_prop_get(op); if (acc_prop_get_rsp == NULL) { ret = -ENOMEM; goto err_op_free; } fstat->ent_type = ELASTO_FSTAT_ENT_DIR; fstat->size = 0; fstat->blksize = 0; /* Azure only supports leases at a container or blob level */ fstat->lease_status = ELASTO_FLEASE_UNLOCKED; fstat->field_mask = ELASTO_FSTAT_FIELD_TYPE; ret = 0; err_op_free: op_free(op); err_out: return ret; }
static int apb_fstat_ctnr(struct apb_fh *apb_fh, struct elasto_fstat *fstat) { int ret; struct op *op; struct az_rsp_ctnr_prop_get *ctnr_prop_get_rsp; ret = az_req_ctnr_prop_get(&apb_fh->path, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(apb_fh->io_conn, op); if (ret < 0) { goto err_op_free; } ctnr_prop_get_rsp = az_rsp_ctnr_prop_get(op); if (ctnr_prop_get_rsp == NULL) { ret = -ENOMEM; goto err_op_free; } fstat->ent_type = ELASTO_FSTAT_ENT_DIR; fstat->size = 0; fstat->blksize = 0; if (ctnr_prop_get_rsp->lease_status == AOP_LEASE_STATUS_UNLOCKED) { fstat->lease_status = ELASTO_FLEASE_UNLOCKED; } else if (ctnr_prop_get_rsp->lease_status == AOP_LEASE_STATUS_LOCKED) { fstat->lease_status = ELASTO_FLEASE_LOCKED; } fstat->field_mask = (ELASTO_FSTAT_FIELD_TYPE | ELASTO_FSTAT_FIELD_LEASE); ret = 0; err_op_free: op_free(op); err_out: return ret; }
static int s3_fstat_obj(struct s3_fh *s3_fh, struct elasto_fstat *fstat) { int ret; struct op *op; struct s3_rsp_obj_head *obj_head_rsp; ret = s3_req_obj_head(&s3_fh->path, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(s3_fh->conn, op); if (ret < 0) { goto err_op_free; } obj_head_rsp = s3_rsp_obj_head(op); if (obj_head_rsp == NULL) { ret = -ENOMEM; goto err_op_free; } fstat->ent_type = ELASTO_FSTAT_ENT_FILE; fstat->size = obj_head_rsp->len; fstat->blksize = 0; /* leave vacant for now */ fstat->lease_status = ELASTO_FLEASE_UNLOCKED; /* flag which values are valid in the stat response */ fstat->field_mask = (ELASTO_FSTAT_FIELD_TYPE | ELASTO_FSTAT_FIELD_SIZE); ret = 0; err_op_free: op_free(op); err_out: return ret; }
static int s3_fstat_bkt(struct s3_fh *s3_fh, struct elasto_fstat *fstat) { int ret; struct op *op; struct s3_rsp_bkt_loc_get *bkt_loc_get_rsp; ret = s3_req_bkt_loc_get(&s3_fh->path, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(s3_fh->conn, op); if (ret < 0) { goto err_op_free; } bkt_loc_get_rsp = s3_rsp_bkt_loc_get(op); if (bkt_loc_get_rsp == NULL) { ret = -ENOMEM; goto err_op_free; } /* TODO location not packed in fstat yet */ fstat->ent_type = ELASTO_FSTAT_ENT_DIR; fstat->size = 0; fstat->blksize = 0; /* leave vacant for now */ fstat->lease_status = ELASTO_FLEASE_UNLOCKED; fstat->field_mask = ELASTO_FSTAT_FIELD_TYPE; ret = 0; err_op_free: op_free(op); err_out: return ret; }
int abb_fsplice(void *src_mod_priv, uint64_t src_off, void *dest_mod_priv, uint64_t dest_off, uint64_t len) { struct apb_fh *src_apb_fh = src_mod_priv; struct apb_fh *dest_apb_fh = dest_mod_priv; struct op *op; struct elasto_fstat fstat; int ret; if (len == 0) { ret = 0; goto err_out; } if ((src_off != 0) || (dest_off != 0)) { dbg(0, "Azure blob backend doesn't support copies at arbitrary " "offsets\n"); ret = -EINVAL; goto err_out; } /* check source length matches the copy length */ ret = abb_fstat(src_mod_priv, &fstat); if (ret < 0) { goto err_out; } else if ((fstat.field_mask & ELASTO_FSTAT_FIELD_SIZE) == 0) { ret = -EBADF; goto err_out; } if (fstat.size != len) { dbg(0, "Azure blob backend doesn't allow partial copies: " "src_len=%" PRIu64 ", copy_len=%" PRIu64 "\n", fstat.size, len); ret = -EINVAL; goto err_out; } /* * check dest file's current length <= copy len, otherwise overwrite * truncates. */ ret = abb_fstat(dest_mod_priv, &fstat); if (ret < 0) { goto err_out; } else if ((fstat.field_mask & ELASTO_FSTAT_FIELD_SIZE) == 0) { ret = -EBADF; goto err_out; } if (fstat.size > len) { dbg(0, "Azure backend doesn't allow splice overwrites when IO " "len (%" PRIu64 ") < current len (%" PRIu64 ")\n", len, fstat.size); ret = -EINVAL; goto err_out; } ret = az_req_blob_cp(&src_apb_fh->path, &dest_apb_fh->path, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(dest_apb_fh->io_conn, op); if (ret < 0) { goto err_op_free; } ret = 0; err_op_free: op_free(op); err_out: return ret; }
int abb_fwrite(void *mod_priv, uint64_t dest_off, uint64_t dest_len, struct elasto_data *src_data) { int ret; struct op *op; struct elasto_fstat fstat; struct apb_fh *apb_fh = mod_priv; uint32_t max_io; if (dest_len == 0) { ret = 0; goto err_out; } if (dest_off != 0) { dbg(0, "Azure block blobs don't allow writes at arbitrary " "offsets\n"); ret = -EINVAL; goto err_out; } /* check current length <= dest_len, otherwise overwrite truncates */ ret = abb_fstat(mod_priv, &fstat); if (ret < 0) { goto err_out; } if ((fstat.field_mask & ELASTO_FSTAT_FIELD_SIZE) == 0) { ret = -EBADF; goto err_out; } /* * XXX we're overwriting an existing object, so need to retain the * content-type provided at open+create time. */ if ((fstat.field_mask & ELASTO_FSTAT_FIELD_CONTENT_TYPE) == 0) { dbg(0, "Block blob stat content-type missing\n"); ret = -EBADF; goto err_out; } if (fstat.size > dest_len) { dbg(0, "Azure block blobs don't allow overwrites when IO len (%" PRIu64 ") < current len (%" PRIu64 ")\n", dest_len, fstat.size); ret = -EINVAL; goto err_out; } if (apb_fh->io_conn->insecure_http) { max_io = ABB_IO_SIZE_HTTP; } else { max_io = ABB_IO_SIZE_HTTPS; } if (dest_len > max_io) { /* split large IOs into multi-part uploads */ ret = abb_fwrite_multi(apb_fh, dest_off, dest_len, src_data, max_io, fstat.content_type); return ret; } ret = az_req_blob_put(&apb_fh->path, src_data, 0, /* non-page block blob */ fstat.content_type, &op); if (ret < 0) { goto err_out; } ret = elasto_fop_send_recv(apb_fh->io_conn, op); if (ret < 0) { goto err_op_free; } ret = 0; err_op_free: op->req.data = NULL; op_free(op); err_out: return ret; }