static ssize_t dax_write()

in char/oradax.c [562:640]


static ssize_t dax_write(struct file *f, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	struct dax_ctx *ctx = f->private_data;
	struct dax_command hdr;
	unsigned long ca;
	int i, idx, ret;

	if (ctx->client != NULL)
		return -EINVAL;

	if (count == 0 || count > DAX_MAX_CCBS * sizeof(struct dax_ccb))
		return -EINVAL;

	if (count % sizeof(struct dax_ccb) == 0)
		return dax_ccb_exec(ctx, buf, count, ppos); /* CCB EXEC */

	if (count != sizeof(struct dax_command))
		return -EINVAL;

	/* immediate command */
	if (ctx->owner != current)
		return -EUSERS;

	if (copy_from_user(&hdr, buf, sizeof(hdr)))
		return -EFAULT;

	ca = ctx->ca_buf_ra + hdr.ca_offset;

	switch (hdr.command) {
	case CCB_KILL:
		if (hdr.ca_offset >= DAX_MMAP_LEN) {
			dax_dbg("invalid ca_offset (%d) >= ca_buflen (%d)",
				hdr.ca_offset, DAX_MMAP_LEN);
			return -EINVAL;
		}

		ret = dax_ccb_kill(ca, &ctx->result.kill.action);
		if (ret != 0) {
			dax_dbg("dax_ccb_kill failed (ret=%d)", ret);
			return ret;
		}

		dax_info_dbg("killed (ca_offset %d)", hdr.ca_offset);
		idx = hdr.ca_offset / sizeof(struct dax_cca);
		ctx->ca_buf[idx].status = CCA_STAT_KILLED;
		ctx->ca_buf[idx].err = CCA_ERR_KILLED;
		ctx->client = current;
		return count;

	case CCB_INFO:
		if (hdr.ca_offset >= DAX_MMAP_LEN) {
			dax_dbg("invalid ca_offset (%d) >= ca_buflen (%d)",
				hdr.ca_offset, DAX_MMAP_LEN);
			return -EINVAL;
		}

		ret = dax_ccb_info(ca, &ctx->result.info);
		if (ret != 0) {
			dax_dbg("dax_ccb_info failed (ret=%d)", ret);
			return ret;
		}

		dax_info_dbg("info succeeded on ca_offset %d", hdr.ca_offset);
		ctx->client = current;
		return count;

	case CCB_DEQUEUE:
		for (i = 0; i < DAX_CA_ELEMS; i++) {
			if (ctx->ca_buf[i].status !=
			    CCA_STAT_NOT_COMPLETED)
				dax_unlock_pages(ctx, i, 1);
		}
		return count;

	default:
		return -EINVAL;
	}
}