public inbox for linux-next@vger.kernel.org 
 help / color / mirror / Atom feed
From: Stephen Rothwell <sfr@canb•auug.org.au>
To: "Martin K. Petersen" <martin.petersen@oracle•com>,
	Jens Axboe <axboe@kernel•dk>
Cc: Douglas Gilbert <dgilbert@interlog•com>,
	Guoqing Jiang <guoqing.jiang@cloud•ionos.com>,
	Linux Kernel Mailing List <linux-kernel@vger•kernel.org>,
	Linux Next Mailing List <linux-next@vger•kernel.org>
Subject: linux-next: manual merge of the scsi-mkp tree with the block tree
Date: Wed, 27 Jan 2021 17:58:05 +1100	[thread overview]
Message-ID: <20210127175805.407b631b@canb.auug.org.au> (raw)

[-- Attachment #1: Type: text/plain, Size: 10820 bytes --]

Hi all,

Today's linux-next merge of the scsi-mkp tree got a conflict in:

  drivers/scsi/sg.c

between commit:

  8eeed0b554b9 ("block: remove unnecessary argument from blk_execute_rq_nowait")

from the block tree and vaious commits from the scsi-mkp tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc drivers/scsi/sg.c
index 4383d93110f8,c5a34bb91335..000000000000
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@@ -437,73 -858,243 +858,242 @@@ sg_rq_state_chg(struct sg_request *srp
  	return 0;
  }
  
- static ssize_t
- sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
+ /*
+  * All writes and submits converge on this function to launch the SCSI
+  * command/request (via blk_execute_rq_nowait). Returns a pointer to a
+  * sg_request object holding the request just issued or a negated errno
+  * value twisted by ERR_PTR.
+  */
+ static struct sg_request *
+ sg_common_write(struct sg_fd *sfp, struct sg_comm_wr_t *cwrp)
  {
- 	Sg_device *sdp;
- 	Sg_fd *sfp;
- 	Sg_request *srp;
- 	int req_pack_id = -1;
- 	sg_io_hdr_t *hp;
- 	struct sg_header *old_hdr;
- 	int retval;
+ 	bool at_head;
+ 	int res = 0;
+ 	int dxfr_len, dir, cmd_len;
+ 	int pack_id = SG_PACK_ID_WILDCARD;
+ 	u32 rq_flags;
+ 	struct sg_device *sdp = sfp->parentdp;
+ 	struct sg_request *srp;
+ 	struct sg_io_hdr *hi_p;
+ 
+ 	hi_p = cwrp->h3p;
+ 	dir = hi_p->dxfer_direction;
+ 	dxfr_len = hi_p->dxfer_len;
+ 	rq_flags = hi_p->flags;
+ 	pack_id = hi_p->pack_id;
+ 	if (dxfr_len >= SZ_256M)
+ 		return ERR_PTR(-EINVAL);
+ 
+ 	srp = sg_setup_req(sfp, dxfr_len, cwrp);
+ 	if (IS_ERR(srp))
+ 		return srp;
+ 	srp->rq_flags = rq_flags;
+ 	srp->pack_id = pack_id;
+ 
+ 	cmd_len = hi_p->cmd_len;
+ 	memcpy(&srp->s_hdr3, hi_p, sizeof(srp->s_hdr3));
+ 	srp->cmd_opcode = cwrp->cmnd[0];/* hold opcode of command for debug */
+ 	SG_LOG(4, sfp, "%s: opcode=0x%02x, cdb_sz=%d, pack_id=%d\n", __func__,
+ 	       (int)cwrp->cmnd[0], cmd_len, pack_id);
+ 
+ 	res = sg_start_req(srp, cwrp->cmnd, cmd_len, dir);
+ 	if (res < 0)		/* probably out of space --> -ENOMEM */
+ 		goto err_out;
+ 	if (unlikely(SG_IS_DETACHING(sdp))) {
+ 		res = -ENODEV;
+ 		goto err_out;
+ 	}
+ 	if (unlikely(test_bit(SG_FRQ_BLK_PUT_REQ, srp->frq_bm) || !srp->rq)) {
+ 		res = -EIDRM;	/* this failure unexpected but observed */
+ 		goto err_out;
+ 	}
+ 	if (xa_get_mark(&sfp->srp_arr, srp->rq_idx, SG_XA_RQ_FREE)) {
+ 		SG_LOG(1, sfp, "%s: ahhh, request erased!!!\n", __func__);
+ 		res = -ENODEV;
+ 		goto err_out;
+ 	}
+ 	srp->rq->timeout = cwrp->timeout;
+ 	kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
+ 	res = sg_rq_state_chg(srp, SG_RS_BUSY, SG_RS_INFLIGHT, false,
+ 			      __func__);
+ 	if (res)
+ 		goto err_out;
+ 	srp->start_ns = ktime_get_boottime_ns();
+ 	srp->duration = 0;
+ 
+ 	if (srp->s_hdr3.interface_id == '\0')
+ 		at_head = true; /* backward compatibility: v1+v2 interfaces */
+ 	else if (test_bit(SG_FFD_Q_AT_TAIL, sfp->ffd_bm))
+ 	/* cmd flags can override sfd setting */
+ 		at_head = !!(srp->rq_flags & SG_FLAG_Q_AT_HEAD);
+ 	else            /* this sfd is defaulting to head */
+ 		at_head = !(srp->rq_flags & SG_FLAG_Q_AT_TAIL);
+ 	if (!test_bit(SG_FRQ_SYNC_INVOC, srp->frq_bm))
+ 		atomic_inc(&sfp->submitted);
 -	blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
 -			      srp->rq, at_head, sg_rq_end_io);
++	blk_execute_rq_nowait(sdp->disk, srp->rq, at_head, sg_rq_end_io);
+ 	return srp;
+ err_out:
+ 	sg_finish_scsi_blk_rq(srp);
+ 	sg_deact_request(sfp, srp);
+ 	return ERR_PTR(res);
+ }
  
- 	/*
- 	 * This could cause a response to be stranded. Close the associated
- 	 * file descriptor to free up any resources being held.
- 	 */
- 	retval = sg_check_file_access(filp, __func__);
- 	if (retval)
- 		return retval;
+ /*
+  * This function is called by wait_event_interruptible in sg_read() and
+  * sg_ctl_ioreceive(). wait_event_interruptible will return if this one
+  * returns true (or an event like a signal (e.g. control-C) occurs).
+  */
  
- 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
- 		return -ENXIO;
- 	SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
- 				      "sg_read: count=%d\n", (int) count));
+ static inline bool
+ sg_get_ready_srp(struct sg_fd *sfp, struct sg_request **srpp, int pack_id)
+ {
+ 	struct sg_request *srp;
  
- 	if (sfp->force_packid)
- 		retval = get_sg_io_pack_id(&req_pack_id, buf, count);
- 	if (retval)
- 		return retval;
+ 	if (unlikely(SG_IS_DETACHING(sfp->parentdp))) {
+ 		*srpp = NULL;
+ 		return true;
+ 	}
+ 	srp = sg_find_srp_by_id(sfp, pack_id);
+ 	*srpp = srp;
+ 	return !!srp;
+ }
  
- 	srp = sg_get_rq_mark(sfp, req_pack_id);
- 	if (!srp) {		/* now wait on packet to arrive */
- 		if (atomic_read(&sdp->detaching))
- 			return -ENODEV;
- 		if (filp->f_flags & O_NONBLOCK)
- 			return -EAGAIN;
- 		retval = wait_event_interruptible(sfp->read_wait,
- 			(atomic_read(&sdp->detaching) ||
- 			(srp = sg_get_rq_mark(sfp, req_pack_id))));
- 		if (atomic_read(&sdp->detaching))
- 			return -ENODEV;
- 		if (retval)
- 			/* -ERESTARTSYS as signal hit process */
- 			return retval;
+ /*
+  * Returns number of bytes copied to user space provided sense buffer or
+  * negated errno value.
+  */
+ static int
+ sg_copy_sense(struct sg_request *srp)
+ {
+ 	int sb_len_ret = 0;
+ 	int scsi_stat;
+ 
+ 	/* If need be, copy the sense buffer to the user space */
+ 	scsi_stat = srp->rq_result & 0xff;
+ 	if ((scsi_stat & SAM_STAT_CHECK_CONDITION) ||
+ 	    (driver_byte(srp->rq_result) & DRIVER_SENSE)) {
+ 		int sb_len = min_t(int, SCSI_SENSE_BUFFERSIZE, srp->sense_len);
+ 		int mx_sb_len = srp->s_hdr3.mx_sb_len;
+ 		u8 *sbp = srp->sense_bp;
+ 		void __user *up = srp->s_hdr3.sbp;
+ 
+ 		srp->sense_bp = NULL;
+ 		if (up && mx_sb_len > 0 && sbp) {
+ 			sb_len = min_t(int, mx_sb_len, sb_len);
+ 			/* Additional sense length field */
+ 			sb_len_ret = 8 + (int)sbp[7];
+ 			sb_len_ret = min_t(int, sb_len_ret, sb_len);
+ 			if (copy_to_user(up, sbp, sb_len_ret))
+ 				sb_len_ret = -EFAULT;
+ 		} else {
+ 			sb_len_ret = 0;
+ 		}
+ 		mempool_free(sbp, sg_sense_pool);
  	}
- 	if (srp->header.interface_id != '\0')
- 		return sg_new_read(sfp, buf, count, srp);
+ 	return sb_len_ret;
+ }
  
- 	hp = &srp->header;
- 	old_hdr = kzalloc(SZ_SG_HEADER, GFP_KERNEL);
- 	if (!old_hdr)
- 		return -ENOMEM;
+ static int
+ sg_rec_state_v3(struct sg_fd *sfp, struct sg_request *srp)
+ {
+ 	int sb_len_wr;
+ 	u32 rq_res = srp->rq_result;
+ 
+ 	sb_len_wr = sg_copy_sense(srp);
+ 	if (sb_len_wr < 0)
+ 		return sb_len_wr;
+ 	if (rq_res & SG_ML_RESULT_MSK)
+ 		srp->rq_info |= SG_INFO_CHECK;
+ 	if (unlikely(SG_IS_DETACHING(sfp->parentdp)))
+ 		srp->rq_info |= SG_INFO_DEVICE_DETACHING;
+ 	return 0;
+ }
+ 
+ static ssize_t
+ sg_receive_v3(struct sg_fd *sfp, struct sg_request *srp, size_t count,
+ 	      void __user *p)
+ {
+ 	int err, err2;
+ 	int rq_result = srp->rq_result;
+ 	struct sg_io_hdr hdr3;
+ 	struct sg_io_hdr *hp = &hdr3;
  
- 	old_hdr->reply_len = (int) hp->timeout;
- 	old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */
- 	old_hdr->pack_id = hp->pack_id;
- 	old_hdr->twelve_byte =
- 	    ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0;
- 	old_hdr->target_status = hp->masked_status;
- 	old_hdr->host_status = hp->host_status;
- 	old_hdr->driver_status = hp->driver_status;
- 	if ((CHECK_CONDITION & hp->masked_status) ||
- 	    (DRIVER_SENSE & hp->driver_status))
- 		memcpy(old_hdr->sense_buffer, srp->sense_b,
- 		       sizeof (old_hdr->sense_buffer));
- 	switch (hp->host_status) {
- 	/* This setup of 'result' is for backward compatibility and is best
- 	   ignored by the user who should use target, host + driver status */
+ 	if (in_compat_syscall()) {
+ 		if (count < sizeof(struct compat_sg_io_hdr)) {
+ 			err = -EINVAL;
+ 			goto err_out;
+ 		}
+ 	} else if (count < SZ_SG_IO_HDR) {
+ 		err = -EINVAL;
+ 		goto err_out;
+ 	}
+ 	SG_LOG(3, sfp, "%s: srp=0x%pK\n", __func__, srp);
+ 	err = sg_rec_state_v3(sfp, srp);
+ 	memset(hp, 0, sizeof(*hp));
+ 	memcpy(hp, &srp->s_hdr3, sizeof(srp->s_hdr3));
+ 	hp->sb_len_wr = srp->sense_len;
+ 	hp->info = srp->rq_info;
+ 	hp->resid = srp->in_resid;
+ 	hp->duration = srp->duration;
+ 	hp->status = rq_result & 0xff;
+ 	hp->masked_status = status_byte(rq_result);
+ 	hp->msg_status = msg_byte(rq_result);
+ 	hp->host_status = host_byte(rq_result);
+ 	hp->driver_status = driver_byte(rq_result);
+ 	err2 = put_sg_io_hdr(hp, p);
+ 	err = err ? err : err2;
+ 	err2 = sg_rq_state_chg(srp, atomic_read(&srp->rq_st), SG_RS_RCV_DONE,
+ 			       false, __func__);
+ 	if (err2)
+ 		err = err ? err : err2;
+ err_out:
+ 	sg_finish_scsi_blk_rq(srp);
+ 	sg_deact_request(sfp, srp);
+ 	return err;
+ }
+ 
+ /*
+  * Completes a v3 request/command. Called from sg_read {v2 or v3},
+  * ioctl(SG_IO) {for v3}, or from ioctl(SG_IORECEIVE) when its
+  * completing a v3 request/command.
+  */
+ static int
+ sg_read_v1v2(void __user *buf, int count, struct sg_fd *sfp,
+ 	     struct sg_request *srp)
+ {
+ 	int res = 0;
+ 	u32 rq_result = srp->rq_result;
+ 	struct sg_header *h2p;
+ 	struct sg_slice_hdr3 *sh3p;
+ 	struct sg_header a_v2hdr;
+ 
+ 	h2p = &a_v2hdr;
+ 	memset(h2p, 0, SZ_SG_HEADER);
+ 	sh3p = &srp->s_hdr3;
+ 	h2p->reply_len = (int)sh3p->timeout;
+ 	h2p->pack_len = h2p->reply_len; /* old, strange behaviour */
+ 	h2p->pack_id = sh3p->pack_id;
+ 	h2p->twelve_byte = (srp->cmd_opcode >= 0xc0 && sh3p->cmd_len == 12);
+ 	h2p->target_status = status_byte(rq_result);
+ 	h2p->host_status = host_byte(rq_result);
+ 	h2p->driver_status = driver_byte(rq_result);
+ 	if ((CHECK_CONDITION & status_byte(rq_result)) ||
+ 	    (DRIVER_SENSE & driver_byte(rq_result))) {
+ 		if (srp->sense_bp) {
+ 			u8 *sbp = srp->sense_bp;
+ 
+ 			srp->sense_bp = NULL;
+ 			memcpy(h2p->sense_buffer, sbp,
+ 			       sizeof(h2p->sense_buffer));
+ 			mempool_free(sbp, sg_sense_pool);
+ 		}
+ 	}
+ 	switch (host_byte(rq_result)) {
+ 	/*
+ 	 * This following setting of 'result' is for backward compatibility
+ 	 * and is best ignored by the user who should use target, host and
+ 	 * driver status.
+ 	 */
  	case DID_OK:
  	case DID_PASSTHROUGH:
  	case DID_SOFT_ERROR:

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

             reply	other threads:[~2021-01-27  6:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-27  6:58 Stephen Rothwell [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-04-18  4:55 linux-next: manual merge of the scsi-mkp tree with the block tree Stephen Rothwell
2024-04-18  5:57 ` Christoph Hellwig
2024-04-26  6:01 ` Stephen Rothwell
2022-02-21 22:06 broonie
2022-03-01  7:29 ` Stephen Rothwell
2022-02-21 21:59 broonie
2022-02-22  5:57 ` Jinpu Wang
2022-03-01  7:31 ` Stephen Rothwell
2019-02-11  4:23 Stephen Rothwell
2017-04-26  5:47 Stephen Rothwell
2016-11-09  2:54 Stephen Rothwell
2016-11-11 19:55 ` Martin K. Petersen
2016-11-17  2:44   ` Stephen Rothwell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210127175805.407b631b@canb.auug.org.au \
    --to=sfr@canb$(echo .)auug.org.au \
    --cc=axboe@kernel$(echo .)dk \
    --cc=dgilbert@interlog$(echo .)com \
    --cc=guoqing.jiang@cloud$(echo .)ionos.com \
    --cc=linux-kernel@vger$(echo .)kernel.org \
    --cc=linux-next@vger$(echo .)kernel.org \
    --cc=martin.petersen@oracle$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox