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;
}
}