/** * fc_lport_flogi_fill() - Fill in FLOGI command for request * @lport: The local port the FLOGI is for * @flogi: The FLOGI command * @op: The opcode */ static void fc_lport_flogi_fill(struct fc_lport *lport, struct fc_els_flogi *flogi, unsigned int op) { struct fc_els_csp *sp; struct fc_els_cssp *cp; memset(flogi, 0, sizeof(*flogi)); flogi->fl_cmd = (u8) op; put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); sp = &flogi->fl_csp; sp->sp_hi_ver = 0x20; sp->sp_lo_ver = 0x20; sp->sp_bb_cred = htons(10); /* this gets set by gateway */ sp->sp_bb_data = htons((u16) lport->mfs); cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); if (op != ELS_FLOGI) { sp->sp_features = htons(FC_SP_FT_CIRO); sp->sp_tot_seq = htons(255); /* seq. we accept */ sp->sp_rel_off = htons(0x1f); sp->sp_e_d_tov = htonl(lport->e_d_tov); cp->cp_rdfs = htons((u16) lport->mfs); cp->cp_con_seq = htons(255); cp->cp_open_seq = 1; } }
static unsigned char *do_40bit(unsigned char *dst, uint64_t d1) { uint64_t d2; d2 = d1; /* copy */ d2 >>= 12; /* shift copy */ d1 &= 0xFFFFFFFF00000000ULL; /* eliminate */ d2 &= 0x00000000FFFFFFFFULL; d1 |= d2; /* join */ d2 = d1; /* copy */ d2 >>= 6; /* shift copy */ d1 &= 0xFFFF0000FFFF0000ULL; /* eliminate */ d2 &= 0x0000FFFF0000FFFFULL; d1 |= d2; /* join */ d2 = d1; /* copy */ d2 >>= 3; /* shift copy */ d1 &= 0xFF00FF00FF00FF00ULL; /* eliminate */ d2 &= 0x00FF00FF00FF00FFULL; d1 |= d2; /* join */ d1 >>= 3; /* bring it down */ d1 &= 0x1F1F1F1F1F1F1F1FULL; /* eliminate */ /* convert */ d1 += 0x6161616161616161ULL; d1 -= zapnot(0x4949494949494949ULL, cmpbge(d1, 0x7B7B7B7B7B7B7B7BULL)); /* write out */ put_unaligned_be64(d1, dst); return dst + 8; }
static void nft_byteorder_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { const struct nft_byteorder *priv = nft_expr_priv(expr); u32 *src = ®s->data[priv->sreg]; u32 *dst = ®s->data[priv->dreg]; union { u32 u32; u16 u16; } *s, *d; unsigned int i; s = (void *)src; d = (void *)dst; switch (priv->size) { case 8: { u64 src64; switch (priv->op) { case NFT_BYTEORDER_NTOH: for (i = 0; i < priv->len / 8; i++) { src64 = get_unaligned((u64 *)&src[i]); put_unaligned_be64(src64, &dst[i]); } break; case NFT_BYTEORDER_HTON: for (i = 0; i < priv->len / 8; i++) { src64 = get_unaligned_be64(&src[i]); put_unaligned(src64, (u64 *)&dst[i]); } break; } break; } case 4: switch (priv->op) { case NFT_BYTEORDER_NTOH: for (i = 0; i < priv->len / 4; i++) d[i].u32 = ntohl((__force __be32)s[i].u32); break; case NFT_BYTEORDER_HTON: for (i = 0; i < priv->len / 4; i++) d[i].u32 = (__force __u32)htonl(s[i].u32); break; } break; case 2: switch (priv->op) { case NFT_BYTEORDER_NTOH: for (i = 0; i < priv->len / 2; i++) d[i].u16 = ntohs((__force __be16)s[i].u16); break; case NFT_BYTEORDER_HTON: for (i = 0; i < priv->len / 2; i++) d[i].u16 = (__force __u16)htons(s[i].u16); break; } break; } }
void qedf_fcoe_send_vlan_req(struct qedf_ctx *qedf) { struct sk_buff *skb; char *eth_fr; int fr_len; struct fip_vlan *vlan; #define MY_FIP_ALL_FCF_MACS ((__u8[6]) { 1, 0x10, 0x18, 1, 0, 2 }) static u8 my_fcoe_all_fcfs[ETH_ALEN] = MY_FIP_ALL_FCF_MACS; skb = dev_alloc_skb(sizeof(struct fip_vlan)); if (!skb) return; fr_len = sizeof(*vlan); eth_fr = (char *)skb->data; vlan = (struct fip_vlan *)eth_fr; memset(vlan, 0, sizeof(*vlan)); ether_addr_copy(vlan->eth.h_source, qedf->mac); ether_addr_copy(vlan->eth.h_dest, my_fcoe_all_fcfs); vlan->eth.h_proto = htons(ETH_P_FIP); vlan->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER); vlan->fip.fip_op = htons(FIP_OP_VLAN); vlan->fip.fip_subcode = FIP_SC_VL_REQ; vlan->fip.fip_dl_len = htons(sizeof(vlan->desc) / FIP_BPW); vlan->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC; vlan->desc.mac.fd_desc.fip_dlen = sizeof(vlan->desc.mac) / FIP_BPW; ether_addr_copy(vlan->desc.mac.fd_mac, qedf->mac); vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME; vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW; put_unaligned_be64(qedf->lport->wwnn, &vlan->desc.wwnn.fd_wwn); skb_put(skb, sizeof(*vlan)); skb->protocol = htons(ETH_P_FIP); skb_reset_mac_header(skb); skb_reset_network_header(skb); QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Sending FIP VLAN " "request."); if (atomic_read(&qedf->link_state) != QEDF_LINK_UP) { QEDF_WARN(&(qedf->dbg_ctx), "Cannot send vlan request " "because link is not up.\n"); kfree_skb(skb); return; } qed_ops->ll2->start_xmit(qedf->cdev, skb); }
static void xfs_dir2_sf_put_ino( struct xfs_dir2_sf_hdr *hdr, xfs_dir2_inou_t *to, xfs_ino_t ino) { ASSERT((ino & 0xff00000000000000ULL) == 0); if (hdr->i8count) put_unaligned_be64(ino, &to->i8.i); else put_unaligned_be32(ino, &to->i4.i); }
static void update_seq_access_counters(struct seqAccessDevice *sa, struct priv_lu_ssc *lu_ssc) { put_unaligned_be64(lu_ssc->bytesWritten_I, &sa->writeDataB4Compression); put_unaligned_be64(lu_ssc->bytesWritten_M, &sa->writeDataAfCompression); put_unaligned_be64(lu_ssc->bytesRead_M, &sa->readDataB4Compression); put_unaligned_be64(lu_ssc->bytesRead_I, &sa->readDataAfCompression); /* Values in MBytes */ if (lu_ssc->tapeLoaded == TAPE_LOADED) { put_unaligned_be32(lu_ssc->max_capacity >> 20, &sa->capacity_bop_eod); put_unaligned_be32(lu_ssc->early_warning_position >> 20, &sa->capacity_bop_ew); put_unaligned_be32(lu_ssc->early_warning_sz >> 20, &sa->capacity_ew_leop); put_unaligned_be32(current_tape_offset() >> 20, &sa->capacity_bop_curr); } else {
/** * ecryptfs_write_inode_size_to_header * * Writes the lower file size to the first 8 bytes of the header. * * Returns zero on success; non-zero on error. */ static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) { char *file_size_virt; int rc; file_size_virt = kmalloc(sizeof(u64), GFP_KERNEL); if (!file_size_virt) { rc = -ENOMEM; goto out; } put_unaligned_be64(i_size_read(ecryptfs_inode), file_size_virt); rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0, sizeof(u64)); kfree(file_size_virt); if (rc) printk(KERN_ERR "%s: Error writing file size to header; " "rc = [%d]\n", __func__, rc); out: return rc; }
int sd_zbc_setup_report_cmnd(struct scsi_cmnd *cmd) { struct request *rq = cmd->request; struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t lba, sector = blk_rq_pos(rq); unsigned int nr_bytes = blk_rq_bytes(rq); int ret; WARN_ON(nr_bytes == 0); if (!sd_is_zoned(sdkp)) /* Not a zoned device */ return BLKPREP_KILL; ret = scsi_init_io(cmd); if (ret != BLKPREP_OK) return ret; cmd->cmd_len = 16; memset(cmd->cmnd, 0, cmd->cmd_len); cmd->cmnd[0] = ZBC_IN; cmd->cmnd[1] = ZI_REPORT_ZONES; lba = sectors_to_logical(sdkp->device, sector); put_unaligned_be64(lba, &cmd->cmnd[2]); put_unaligned_be32(nr_bytes, &cmd->cmnd[10]); /* Do partial report for speeding things up */ cmd->cmnd[14] = ZBC_REPORT_ZONE_PARTIAL; cmd->sc_data_direction = DMA_FROM_DEVICE; cmd->sdb.length = nr_bytes; cmd->transfersize = sdkp->device->sector_size; cmd->allowed = 0; /* * Report may return less bytes than requested. Make sure * to report completion on the entire initial request. */ rq->__data_len = nr_bytes; return BLKPREP_OK; }
static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) { ssize_t size; void *xattr_virt; struct dentry *lower_dentry = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; struct inode *lower_inode = lower_dentry->d_inode; int rc; if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { printk(KERN_WARNING "No support for setting xattr in lower filesystem\n"); rc = -ENOSYS; goto out; } xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); if (!xattr_virt) { printk(KERN_ERR "Out of memory whilst attempting to write " "inode size to xattr\n"); rc = -ENOMEM; goto out; } mutex_lock(&lower_inode->i_mutex); size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME, xattr_virt, PAGE_CACHE_SIZE); if (size < 0) size = 8; put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME, xattr_virt, size, 0); mutex_unlock(&lower_inode->i_mutex); if (rc) printk(KERN_ERR "Error whilst attempting to write inode size " "to lower file xattr; rc = [%d]\n", rc); kmem_cache_free(ecryptfs_xattr_cache, xattr_virt); out: return rc; }
/** * Issue a REPORT ZONES scsi command. */ static int sd_zbc_report_zones(struct scsi_disk *sdkp, unsigned char *buf, unsigned int buflen, sector_t lba) { struct scsi_device *sdp = sdkp->device; const int timeout = sdp->request_queue->rq_timeout; struct scsi_sense_hdr sshdr; unsigned char cmd[16]; unsigned int rep_len; int result; memset(cmd, 0, 16); cmd[0] = ZBC_IN; cmd[1] = ZI_REPORT_ZONES; put_unaligned_be64(lba, &cmd[2]); put_unaligned_be32(buflen, &cmd[10]); memset(buf, 0, buflen); result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buf, buflen, &sshdr, timeout, SD_MAX_RETRIES, NULL); if (result) { sd_printk(KERN_ERR, sdkp, "REPORT ZONES lba %llu failed with %d/%d\n", (unsigned long long)lba, host_byte(result), driver_byte(result)); return -EIO; } rep_len = get_unaligned_be32(&buf[0]); if (rep_len < 64) { sd_printk(KERN_ERR, sdkp, "REPORT ZONES report invalid length %u\n", rep_len); return -EIO; } return 0; }
/** * scsi_set_sense_information - set the information field in a * formatted sense data buffer * @buf: Where to build sense data * @buf_len: buffer length * @info: 64-bit information value to be set * * Return value: * 0 on success or EINVAL for invalid sense buffer length **/ int scsi_set_sense_information(u8 *buf, int buf_len, u64 info) { if ((buf[0] & 0x7f) == 0x72) { u8 *ucp, len; len = buf[7]; ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0); if (!ucp) { buf[7] = len + 0xc; ucp = buf + 8 + len; } if (buf_len < len + 0xc) /* Not enough room for info */ return -EINVAL; ucp[0] = 0; ucp[1] = 0xa; ucp[2] = 0x80; /* Valid bit */ ucp[3] = 0; put_unaligned_be64(info, &ucp[4]); } else if ((buf[0] & 0x7f) == 0x70) { /* * Only set the 'VALID' bit if we can represent the value * correctly; otherwise just fill out the lower bytes and * clear the 'VALID' flag. */ if (info <= 0xffffffffUL) buf[0] |= 0x80; else buf[0] &= 0x7f; put_unaligned_be32((u32)info, &buf[3]); } return 0; }
static void skd_prep_discard_cdb(struct skd_scsi_request *scsi_req, struct skd_request_context *skreq, struct page *page, u32 lba, u32 count) { char *buf; unsigned long len; struct request *req; buf = page_address(page); len = SKD_DISCARD_CDB_LENGTH; scsi_req->cdb[0] = UNMAP; scsi_req->cdb[8] = len; put_unaligned_be16(6 + 16, &buf[0]); put_unaligned_be16(16, &buf[2]); put_unaligned_be64(lba, &buf[8]); put_unaligned_be32(count, &buf[16]); req = skreq->req; blk_add_request_payload(req, page, len); }
static void bs_rbd_request(struct scsi_cmd *cmd) { int ret; uint32_t length; int result = SAM_STAT_GOOD; uint8_t key; uint16_t asc; #if 0 /* * This should go in the sense data on error for COMPARE_AND_WRITE, but * there doesn't seem to be any attempt to do so... */ uint32_t info = 0; #endif char *tmpbuf; size_t blocksize; uint64_t offset = cmd->offset; uint32_t tl = cmd->tl; int do_verify = 0; int i; char *ptr; const char *write_buf = NULL; ret = length = 0; key = asc = 0; struct active_rbd *rbd = RBDP(cmd->dev->fd); switch (cmd->scb[0]) { case ORWRITE_16: length = scsi_get_out_length(cmd); tmpbuf = malloc(length); if (!tmpbuf) { result = SAM_STAT_CHECK_CONDITION; key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; break; } ret = rbd_read(rbd->rbd_image, offset, length, tmpbuf); if (ret != length) { set_medium_error(&result, &key, &asc); free(tmpbuf); break; } ptr = scsi_get_out_buffer(cmd); for (i = 0; i < length; i++) ptr[i] |= tmpbuf[i]; free(tmpbuf); write_buf = scsi_get_out_buffer(cmd); goto write; case COMPARE_AND_WRITE: /* Blocks are transferred twice, first the set that * we compare to the existing data, and second the set * to write if the compare was successful. */ length = scsi_get_out_length(cmd) / 2; if (length != cmd->tl) { result = SAM_STAT_CHECK_CONDITION; key = ILLEGAL_REQUEST; asc = ASC_INVALID_FIELD_IN_CDB; break; } tmpbuf = malloc(length); if (!tmpbuf) { result = SAM_STAT_CHECK_CONDITION; key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; break; } ret = rbd_read(rbd->rbd_image, offset, length, tmpbuf); if (ret != length) { set_medium_error(&result, &key, &asc); free(tmpbuf); break; } if (memcmp(scsi_get_out_buffer(cmd), tmpbuf, length)) { uint32_t pos = 0; char *spos = scsi_get_out_buffer(cmd); char *dpos = tmpbuf; /* * Data differed, this is assumed to be 'rare' * so use a much more expensive byte-by-byte * comparasion to find out at which offset the * data differs. */ for (pos = 0; pos < length && *spos++ == *dpos++; pos++) ; #if 0 /* See comment above at declaration */ info = pos; #endif result = SAM_STAT_CHECK_CONDITION; key = MISCOMPARE; asc = ASC_MISCOMPARE_DURING_VERIFY_OPERATION; free(tmpbuf); break; } /* no DPO bit (cache retention advice) support */ free(tmpbuf); write_buf = scsi_get_out_buffer(cmd) + length; goto write; case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: /* TODO */ length = (cmd->scb[0] == SYNCHRONIZE_CACHE) ? 0 : 0; if (cmd->scb[1] & 0x2) { result = SAM_STAT_CHECK_CONDITION; key = ILLEGAL_REQUEST; asc = ASC_INVALID_FIELD_IN_CDB; } else bs_sync_sync_range(cmd, length, &result, &key, &asc); break; case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY_16: do_verify = 1; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: length = scsi_get_out_length(cmd); write_buf = scsi_get_out_buffer(cmd); write: ret = rbd_write(rbd->rbd_image, offset, length, write_buf); if (ret == length) { struct mode_pg *pg; /* * it would be better not to access to pg * directy. */ pg = find_mode_page(cmd->dev, 0x08, 0); if (pg == NULL) { result = SAM_STAT_CHECK_CONDITION; key = ILLEGAL_REQUEST; asc = ASC_INVALID_FIELD_IN_CDB; break; } if (((cmd->scb[0] != WRITE_6) && (cmd->scb[1] & 0x8)) || !(pg->mode_data[0] & 0x04)) bs_sync_sync_range(cmd, length, &result, &key, &asc); } else set_medium_error(&result, &key, &asc); if (do_verify) goto verify; break; case WRITE_SAME: case WRITE_SAME_16: /* WRITE_SAME used to punch hole in file */ if (cmd->scb[1] & 0x08) { ret = rbd_discard(rbd->rbd_image, offset, tl); if (ret != 0) { eprintf("Failed to punch hole for WRITE_SAME" " command\n"); result = SAM_STAT_CHECK_CONDITION; key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; break; } break; } while (tl > 0) { blocksize = 1 << cmd->dev->blk_shift; tmpbuf = scsi_get_out_buffer(cmd); switch (cmd->scb[1] & 0x06) { case 0x02: /* PBDATA==0 LBDATA==1 */ put_unaligned_be32(offset, tmpbuf); break; case 0x04: /* PBDATA==1 LBDATA==0 */ /* physical sector format */ put_unaligned_be64(offset, tmpbuf); break; } ret = rbd_write(rbd->rbd_image, offset, blocksize, tmpbuf); if (ret != blocksize) set_medium_error(&result, &key, &asc); offset += blocksize; tl -= blocksize; } break; case READ_6: case READ_10: case READ_12: case READ_16: length = scsi_get_in_length(cmd); ret = rbd_read(rbd->rbd_image, offset, length, scsi_get_in_buffer(cmd)); if (ret != length) set_medium_error(&result, &key, &asc); break; case PRE_FETCH_10: case PRE_FETCH_16: break; case VERIFY_10: case VERIFY_12: case VERIFY_16: verify: length = scsi_get_out_length(cmd); tmpbuf = malloc(length); if (!tmpbuf) { result = SAM_STAT_CHECK_CONDITION; key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; break; } ret = rbd_read(rbd->rbd_image, offset, length, tmpbuf); if (ret != length) set_medium_error(&result, &key, &asc); else if (memcmp(scsi_get_out_buffer(cmd), tmpbuf, length)) { result = SAM_STAT_CHECK_CONDITION; key = MISCOMPARE; asc = ASC_MISCOMPARE_DURING_VERIFY_OPERATION; } free(tmpbuf); break; case UNMAP: if (!cmd->dev->attrs.thinprovisioning) { result = SAM_STAT_CHECK_CONDITION; key = ILLEGAL_REQUEST; asc = ASC_INVALID_FIELD_IN_CDB; break; } length = scsi_get_out_length(cmd); tmpbuf = scsi_get_out_buffer(cmd); if (length < 8) break; length -= 8; tmpbuf += 8; while (length >= 16) { offset = get_unaligned_be64(&tmpbuf[0]); offset = offset << cmd->dev->blk_shift; tl = get_unaligned_be32(&tmpbuf[8]); tl = tl << cmd->dev->blk_shift; if (offset + tl > cmd->dev->size) { eprintf("UNMAP beyond EOF\n"); result = SAM_STAT_CHECK_CONDITION; key = ILLEGAL_REQUEST; asc = ASC_LBA_OUT_OF_RANGE; break; } if (tl > 0) { if (rbd_discard(rbd->rbd_image, offset, tl) != 0) { eprintf("Failed to punch hole for" " UNMAP at offset:%" PRIu64 " length:%d\n", offset, tl); result = SAM_STAT_CHECK_CONDITION; key = HARDWARE_ERROR; asc = ASC_INTERNAL_TGT_FAILURE; break; } } length -= 16; tmpbuf += 16; } break; default: break; } dprintf("io done %p %x %d %u\n", cmd, cmd->scb[0], ret, length); scsi_set_result(cmd, result); if (result != SAM_STAT_GOOD) { eprintf("io error %p %x %d %d %" PRIu64 ", %m\n", cmd, cmd->scb[0], ret, length, offset); sense_data_build(cmd, key, asc); } }
static int target_xcopy_write_destination( struct se_cmd *ec_cmd, struct xcopy_op *xop, struct se_device *dst_dev, sector_t dst_lba, u32 dst_sectors) { struct xcopy_pt_cmd *xpt_cmd; struct se_cmd *se_cmd; u32 length = (dst_sectors * dst_dev->dev_attrib.block_size); int rc; unsigned char cdb[16]; bool remote_port = (xop->op_origin == XCOL_SOURCE_RECV_OP); xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL); if (!xpt_cmd) { pr_err("Unable to allocate xcopy_pt_cmd\n"); return -ENOMEM; } init_completion(&xpt_cmd->xpt_passthrough_sem); se_cmd = &xpt_cmd->se_cmd; memset(&cdb[0], 0, 16); cdb[0] = WRITE_16; put_unaligned_be64(dst_lba, &cdb[2]); put_unaligned_be32(dst_sectors, &cdb[10]); pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)dst_lba, dst_sectors, length); transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); xop->dst_pt_cmd = xpt_cmd; rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, dst_dev, &cdb[0], remote_port, false); if (rc < 0) { struct se_cmd *src_cmd = &xop->src_pt_cmd->se_cmd; ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; /* * If the failure happened before the t_mem_list hand-off in * target_xcopy_setup_pt_cmd(), Reset memory + clear flag so that * core releases this memory on error during X-COPY WRITE I/O. */ src_cmd->se_cmd_flags &= ~SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; src_cmd->t_data_sg = xop->xop_data_sg; src_cmd->t_data_nents = xop->xop_data_nents; transport_generic_free_cmd(se_cmd, 0); return rc; } rc = target_xcopy_issue_pt_cmd(xpt_cmd); if (rc < 0) { ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; se_cmd->se_cmd_flags &= ~SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; transport_generic_free_cmd(se_cmd, 0); return rc; } return 0; }
static void w8be(uint64_t val, uint64_t *x) { put_unaligned_be64(val, x); }
int main(int argc, char *argv[]) { unsigned char sam_stat; char *progname = argv[0]; char *pcl = NULL; char *mediaType = NULL; char *mediaCapacity = NULL; char *density = NULL; uint64_t size; struct MAM new_mam; char *lib = NULL; int libno = 0; int indx; int rc; char *config = MHVTL_CONFIG_PATH"/device.conf"; FILE *conf; char *b; /* Read from file into this buffer */ char *s; /* Somewhere for sscanf to store results */ if (sizeof(struct MAM) != 1024) { printf("Structure of MAM incorrect size: %d\n", (int)sizeof(struct MAM)); exit(2); } if (argc < 2) { usage(progname); exit(1); } debug = 0; my_id = 0; verbose = 0; wp = 0; while (argc > 0) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'd': if (argc > 1) density = argv[1]; break; case 'l': if (argc > 1) { lib = argv[1]; } else { puts(" More args needed for -l\n"); exit(1); } break; case 'm': if (argc > 1) { pcl = argv[1]; } else { puts(" More args needed for -m\n"); exit(1); } break; case 's': if (argc > 1) { mediaCapacity = argv[1]; } else { puts(" More args needed for -s\n"); exit(1); } break; case 't': if (argc > 1) { mediaType = argv[1]; } else { puts(" More args needed for -t\n"); exit(1); } break; case 'V': printf("%s: version %s\n%s\n\n", progname, MHVTL_VERSION, (char *)largefile_support); break; case 'v': verbose++; break; case 'w': if (argc > 1) { if (!strncasecmp("yes", argv[1], 3)) wp = WRITE_PROTECT_ON; else if (!strncasecmp("on", argv[1], 3)) wp = WRITE_PROTECT_ON; else wp = WRITE_PROTECT_OFF; } else { puts(" More args needed for -m\n"); exit(1); } break; } } argv++; argc--; } if (pcl == NULL) { printf("Please supply a barcode (-b barcode)\n\n"); usage(progname); exit(1); } conf = fopen(config , "r"); if (!conf) { printf("Can not open config file %s : %s", config, strerror(errno)); perror("Can not open config file"); exit(1); } s = zalloc(MALLOC_SZ); if (!s) { perror("Could not allocate memory"); exit(1); } b = zalloc(MALLOC_SZ); if (!b) { perror("Could not allocate memory"); exit(1); } rc = ENOENT; if (lib) { sscanf(lib, "%d", &libno); printf("Looking for PCL: %s in library %d\n", pcl, libno); find_media_home_directory(home_directory, libno); rc = load_tape(pcl, &sam_stat); } else { /* Walk thru all defined libraries looking for media */ while (readline(b, MALLOC_SZ, conf) != NULL) { if (b[0] == '#') /* Ignore comments */ continue; /* If found a library: Attempt to load media * Break out of loop if found. Otherwise try next lib. */ if (sscanf(b, "Library: %d CHANNEL:", &indx)) { find_media_home_directory(home_directory, indx); rc = load_tape(pcl, &sam_stat); if (!rc) break; } } } fclose(conf); free(s); free(b); if (rc) { fprintf(stderr, "PCL %s cannot be dumped, " "load_tape() returned %d\n", pcl, rc); exit(1); } /* Copy media MAM into temp location */ memcpy(&new_mam, &mam, sizeof(mam)); size = 0L; if (mediaCapacity) { sscanf(mediaCapacity, "%" PRId64, &size); printf("New capacity for %s: %ldMB\n", pcl, (unsigned long)size); } if (mediaType) { if (!strncasecmp("clean", mediaType, 5)) { MHVTL_DBG(1, "Setting media type to CLEAN"); new_mam.MediumType = MEDIA_TYPE_CLEAN; new_mam.MediumTypeInformation = 20; } else if (!strncasecmp("data", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to DATA"); new_mam.MediumType = MEDIA_TYPE_DATA; } else if (!strncasecmp("null", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to NULL"); new_mam.MediumType = MEDIA_TYPE_NULL; } else if (!strncasecmp("WORM", mediaType, 4)) { MHVTL_DBG(1, "Setting media type to NULL"); new_mam.MediumType = MEDIA_TYPE_WORM; } else { printf("Unknown media type: %s\n", mediaType); usage(progname); exit(1); } } if (density) { printf("Setting density to %s\n", density); if (set_media_params(&new_mam, density)) { printf("Could not determine media density: %s\n", density); unload_tape(&sam_stat); exit(1); } } if (size) { put_unaligned_be64(size * 1048576, &new_mam.max_capacity); /* This will set incorrect value to start with but next media * Usage, this will be recalculated correctly */ put_unaligned_be64(size * 1048576, &new_mam.remaining_capacity); } switch (wp) { case WRITE_PROTECT_ON: new_mam.Flags |= MAM_FLAGS_MEDIA_WRITE_PROTECT; printf("Setting write-protect for %s\n", pcl); break; case WRITE_PROTECT_OFF: new_mam.Flags &= ~MAM_FLAGS_MEDIA_WRITE_PROTECT; printf("Turning off write-protect for %s\n", pcl); break; } put_unaligned_be64(sizeof(mam.pad), &new_mam.MAMSpaceRemaining); memcpy(&mam, &new_mam, sizeof(mam)); rewriteMAM(&sam_stat); unload_tape(&sam_stat); exit(0); }
int main(int argc, char *argv[]) { unsigned char sam_stat; char *progname = argv[0]; char *pcl = NULL; char *mediaType = NULL; char *mediaCapacity = NULL; char *density = NULL; char *lib = NULL; uint64_t size; int libno; struct stat statb; struct passwd *pw; if (sizeof(struct MAM) != 1024) { printf("Structure of MAM incorrect size: %d\n", (int)sizeof(struct MAM)); exit(2); } if (argc < 2) { usage(progname); exit(1); } while(argc > 0) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'd': if (argc > 1) density = argv[1]; break; case 'l': if (argc > 1) { lib = argv[1]; } else { puts(" More args needed for -l\n"); exit(1); } break; case 'm': if (argc > 1) { pcl = argv[1]; } else { puts(" More args needed for -m\n"); exit(1); } break; case 's': if (argc > 1) { mediaCapacity = argv[1]; } else { puts(" More args needed for -s\n"); exit(1); } break; case 't': if (argc > 1) { mediaType = argv[1]; } else { puts(" More args needed for -t\n"); exit(1); } break; case 'V': printf("%s: version %s\n%s\n\n", progname, MHVTL_VERSION, (char *)largefile_support); break; case 'v': verbose++; break; } } argv++; argc--; } if (pcl == NULL) { printf("Please supply a barcode (-b barcode)\n\n"); usage(progname); exit(1); } if (mediaCapacity == NULL) { printf("Please supply media capacity (-s xx)\n\n"); usage(progname); exit(1); } if (mediaType == NULL) { printf("Please supply cart type (-t data|clean|WORM)\n\n"); usage(progname); exit(1); } if (lib == NULL) { printf("Please supply Library number (-l xx)\n\n"); usage(progname); exit(1); } if (density == NULL) { printf("Please supply media density (-d xx)\n\n"); usage(progname); exit(1); } sscanf(mediaCapacity, "%" PRId64, &size); if (size == 0) size = 8000; sscanf(lib, "%d", &libno); if (!libno) { printf("Invalid library number\n"); exit(1); } find_media_home_directory(home_directory, libno); if (strlen(pcl) > MAX_BARCODE_LEN) { printf("Max barcode length (%d) exceeded\n\n", MAX_BARCODE_LEN); usage(progname); exit(1); } pw = getpwnam(USR); /* Find UID for user 'vtl' */ /* Verify that the MHVTL home directory exists. */ if (stat(home_directory, &statb) < 0 && errno == ENOENT) { umask(0007); if (mkdir(home_directory, 02770) < 0) { printf("Cannot create PCL %s, directory %s:" "Doesn't exist and cannot be created\n", pcl, home_directory); exit(1); } } /* Don't really care if this fails or not.. * But lets try anyway */ if (chown(home_directory, pw->pw_uid, pw->pw_gid)) ; /* Initialize the contents of the MAM to be used for the new PCL. */ memset((uint8_t *)&mam, 0, sizeof(mam)); mam.tape_fmt_version = TAPE_FMT_VERSION; mam.mam_fmt_version = MAM_VERSION; put_unaligned_be64(size * 1048576, &mam.max_capacity); put_unaligned_be64(size * 1048576, &mam.remaining_capacity); put_unaligned_be64(sizeof(mam.pad), &mam.MAMSpaceRemaining); memcpy(&mam.MediumManufacturer, "linuxVTL", 8); memcpy(&mam.ApplicationVendor, "vtl-1.4 ", 8); sprintf((char *)mam.ApplicationVersion, "%d", TAPE_FMT_VERSION); if (! strncmp("clean", mediaType, 5)) { mam.MediumType = MEDIA_TYPE_CLEAN; /* Cleaning cart */ mam.MediumTypeInformation = 20; /* Max cleaning loads */ } else if (! strncmp("WORM", mediaType, 4)) { mam.MediumType = MEDIA_TYPE_WORM; /* WORM cart */ } else { mam.MediumType = MEDIA_TYPE_DATA; /* Normal data cart */ } set_media_params(&mam, density); sprintf((char *)mam.MediumSerialNumber, "%s_%d", pcl, (int)time(NULL)); sprintf((char *)mam.MediumManufactureDate, "%d", (int)time(NULL)); sprintf((char *)mam.Barcode, "%-31s", pcl); /* Create the PCL using the initialized MAM. */ exit(create_tape(pcl, &mam, &sam_stat)); }
static int target_xcopy_read_source( struct se_cmd *ec_cmd, struct xcopy_op *xop, struct se_device *src_dev, sector_t src_lba, u32 src_sectors) { struct xcopy_pt_cmd *xpt_cmd; struct se_cmd *se_cmd; u32 length = (src_sectors * src_dev->dev_attrib.block_size); int rc; unsigned char cdb[16]; bool remote_port = (xop->op_origin == XCOL_DEST_RECV_OP); xpt_cmd = kzalloc(sizeof(struct xcopy_pt_cmd), GFP_KERNEL); if (!xpt_cmd) { pr_err("Unable to allocate xcopy_pt_cmd\n"); return -ENOMEM; } init_completion(&xpt_cmd->xpt_passthrough_sem); se_cmd = &xpt_cmd->se_cmd; memset(&cdb[0], 0, 16); cdb[0] = READ_16; put_unaligned_be64(src_lba, &cdb[2]); put_unaligned_be32(src_sectors, &cdb[10]); pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)src_lba, src_sectors, length); transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); xop->src_pt_cmd = xpt_cmd; rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0], remote_port, true); if (rc < 0) { ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; transport_generic_free_cmd(se_cmd, 0); return rc; } xop->xop_data_sg = se_cmd->t_data_sg; xop->xop_data_nents = se_cmd->t_data_nents; pr_debug("XCOPY-READ: Saved xop->xop_data_sg: %p, num: %u for READ" " memory\n", xop->xop_data_sg, xop->xop_data_nents); rc = target_xcopy_issue_pt_cmd(xpt_cmd); if (rc < 0) { ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; transport_generic_free_cmd(se_cmd, 0); return rc; } /* * Clear off the allocated t_data_sg, that has been saved for * zero-copy WRITE submission reuse in struct xcopy_op.. */ se_cmd->t_data_sg = NULL; se_cmd->t_data_nents = 0; return 0; }