Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}