Re: [PATCH 2/2] target: Fix target_wait_for_sess_cmds breakage with active signals

2018-10-10 Thread Nicholas A. Bellinger
Hello MNC & Co,

On Wed, 2018-10-10 at 11:58 -0500, Mike Christie wrote:
> On 10/09/2018 10:23 PM, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > With the addition of commit 00d909a107 in v4.19-rc, it incorrectly assumes 
> > no
> > signals will be pending for task_struct executing the normal session 
> > shutdown
> > and I/O quiesce code-path.
> > 



> > diff --git a/drivers/target/target_core_transport.c 
> > b/drivers/target/target_core_transport.c
> > index 86c0156..fc3093d2 100644
> > --- a/drivers/target/target_core_transport.c
> > +++ b/drivers/target/target_core_transport.c
> > @@ -2754,7 +2754,7 @@ static void target_release_cmd_kref(struct kref *kref)
> > if (se_sess) {
> > spin_lock_irqsave(_sess->sess_cmd_lock, flags);
> > list_del_init(_cmd->se_cmd_list);
> > -   if (list_empty(_sess->sess_cmd_list))
> > +   if (se_sess->sess_tearing_down && 
> > list_empty(_sess->sess_cmd_list))
> 
> I think there is another issue with 00d909a107 and ibmvscsi_tgt.
> 
> The problem is that ibmvscsi_tgt never called
> target_sess_cmd_list_set_waiting. It only called
> target_wait_for_sess_cmds. So before 00d909a107 there was a bug in that
> driver and target_wait_for_sess_cmds never did what was intended because
> sess_wait_list would always be empty.
> 
> With 00d909a107, we no longer need to call
> target_sess_cmd_list_set_waiting to wait for outstanding commands, so
> for ibmvscsi_tgt will now wait for commands like we wanted. However, the
> commit added a WARN_ON that is hit if target_sess_cmd_list_set_waiting
> is not called, so we could hit that.
> 
> So I think we need to add a target_sess_cmd_list_set_waiting call in
> ibmvscsi_tgt to go along with your patch chunk above and make sure we do
> not trigger the WARN_ON.
> 

Nice catch.  :)

With target_wait_for_sess_cmd() usage pre 00d909a107 doing a list-splice
in target_sess_cmd_list_set_waiting(), this particular usage in
ibmvscsi_tgt has always been list_empty(>sess_wait_list) = true
(eg: no se_cmd I/O is quiesced, because no se_cmd in sess_wait_list)
since commit 712db3eb in 4.9.y code.

That said, ibmvscsi_tgt usage is very similar to vhost/scsi in the
respect individual /sys/kernel/config/target/$FABRIC/$WWN/$TPGT/
endpoints used by VMs do not remove their I_T nexus while the VM is
active.

So AFAICT, ibmvscsi_tgt doesn't strictly need target_sess_wait_for_cmd()
at all if this is true.



Re: [PATCH 2/2] target: Fix target_wait_for_sess_cmds breakage with active signals

2018-10-10 Thread Nicholas A. Bellinger
Hello MNC & Co,

On Wed, 2018-10-10 at 11:58 -0500, Mike Christie wrote:
> On 10/09/2018 10:23 PM, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > With the addition of commit 00d909a107 in v4.19-rc, it incorrectly assumes 
> > no
> > signals will be pending for task_struct executing the normal session 
> > shutdown
> > and I/O quiesce code-path.
> > 



> > diff --git a/drivers/target/target_core_transport.c 
> > b/drivers/target/target_core_transport.c
> > index 86c0156..fc3093d2 100644
> > --- a/drivers/target/target_core_transport.c
> > +++ b/drivers/target/target_core_transport.c
> > @@ -2754,7 +2754,7 @@ static void target_release_cmd_kref(struct kref *kref)
> > if (se_sess) {
> > spin_lock_irqsave(_sess->sess_cmd_lock, flags);
> > list_del_init(_cmd->se_cmd_list);
> > -   if (list_empty(_sess->sess_cmd_list))
> > +   if (se_sess->sess_tearing_down && 
> > list_empty(_sess->sess_cmd_list))
> 
> I think there is another issue with 00d909a107 and ibmvscsi_tgt.
> 
> The problem is that ibmvscsi_tgt never called
> target_sess_cmd_list_set_waiting. It only called
> target_wait_for_sess_cmds. So before 00d909a107 there was a bug in that
> driver and target_wait_for_sess_cmds never did what was intended because
> sess_wait_list would always be empty.
> 
> With 00d909a107, we no longer need to call
> target_sess_cmd_list_set_waiting to wait for outstanding commands, so
> for ibmvscsi_tgt will now wait for commands like we wanted. However, the
> commit added a WARN_ON that is hit if target_sess_cmd_list_set_waiting
> is not called, so we could hit that.
> 
> So I think we need to add a target_sess_cmd_list_set_waiting call in
> ibmvscsi_tgt to go along with your patch chunk above and make sure we do
> not trigger the WARN_ON.
> 

Nice catch.  :)

With target_wait_for_sess_cmd() usage pre 00d909a107 doing a list-splice
in target_sess_cmd_list_set_waiting(), this particular usage in
ibmvscsi_tgt has always been list_empty(>sess_wait_list) = true
(eg: no se_cmd I/O is quiesced, because no se_cmd in sess_wait_list)
since commit 712db3eb in 4.9.y code.

That said, ibmvscsi_tgt usage is very similar to vhost/scsi in the
respect individual /sys/kernel/config/target/$FABRIC/$WWN/$TPGT/
endpoints used by VMs do not remove their I_T nexus while the VM is
active.

So AFAICT, ibmvscsi_tgt doesn't strictly need target_sess_wait_for_cmd()
at all if this is true.



Re: [PATCH 2/2] target: Fix target_wait_for_sess_cmds breakage with active signals

2018-10-10 Thread Nicholas A. Bellinger
Hey Peter & Co,

On Wed, 2018-10-10 at 10:43 +0200, Peter Zijlstra wrote:
> On Wed, Oct 10, 2018 at 03:23:10AM +, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > With the addition of commit 00d909a107 in v4.19-rc, it incorrectly assumes 
> > no
> > signals will be pending for task_struct executing the normal session 
> > shutdown
> > and I/O quiesce code-path.
> > 
> > For example, iscsi-target and iser-target issue SIGINT to all kthreads as
> > part of session shutdown.  This has been the behaviour since day one.
> 
> Not knowing much context here; but does it make sense for those
> kthreads to handle signals, ever? Most kthreads should be fine with
> ignore_signals().
> 

iscsi-target + ib-isert uses SIGINT amongst dedicated rx/tx connection
kthreads to signal connection shutdown, requiring in-flight se_cmd I/O
descriptors to be quiesced before making forward progress to release
se_session.

By the point wait_event_lock_irq_timeout() is called in the example
here, one of the two rx/tx connection kthreads has been stopped, and the
other kthread is still processing shutdown.  So while historically the
pending SIGINTs where not cleared (or ignored) during shutdown at this
point, there is no reason why they could not be ignored for iscsi-target
+ ib-isert.

That said, pre commit 00d909a107 code always used wait_for_completion()
and ignored pending signals.  As-is target_wait_for_sess_cmds() is
called directly from fabric driver code and in one case also from
user-space via configfs_write_file(), so AFAICT it does need
TASK_UNINTERRUPTIBLE.



Re: [PATCH 2/2] target: Fix target_wait_for_sess_cmds breakage with active signals

2018-10-10 Thread Nicholas A. Bellinger
Hey Peter & Co,

On Wed, 2018-10-10 at 10:43 +0200, Peter Zijlstra wrote:
> On Wed, Oct 10, 2018 at 03:23:10AM +, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > With the addition of commit 00d909a107 in v4.19-rc, it incorrectly assumes 
> > no
> > signals will be pending for task_struct executing the normal session 
> > shutdown
> > and I/O quiesce code-path.
> > 
> > For example, iscsi-target and iser-target issue SIGINT to all kthreads as
> > part of session shutdown.  This has been the behaviour since day one.
> 
> Not knowing much context here; but does it make sense for those
> kthreads to handle signals, ever? Most kthreads should be fine with
> ignore_signals().
> 

iscsi-target + ib-isert uses SIGINT amongst dedicated rx/tx connection
kthreads to signal connection shutdown, requiring in-flight se_cmd I/O
descriptors to be quiesced before making forward progress to release
se_session.

By the point wait_event_lock_irq_timeout() is called in the example
here, one of the two rx/tx connection kthreads has been stopped, and the
other kthread is still processing shutdown.  So while historically the
pending SIGINTs where not cleared (or ignored) during shutdown at this
point, there is no reason why they could not be ignored for iscsi-target
+ ib-isert.

That said, pre commit 00d909a107 code always used wait_for_completion()
and ignored pending signals.  As-is target_wait_for_sess_cmds() is
called directly from fabric driver code and in one case also from
user-space via configfs_write_file(), so AFAICT it does need
TASK_UNINTERRUPTIBLE.



[GIT PULL] target updates for v4.16-rc1

2018-02-09 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending updates for v4.16-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

The highlights include:

- Numerous target-core-user improvements related to queue full and timeout 
handling. (MNC)
- Prevent target-core-user corruption when invalid data page is requested. (MNC)
- Add target-core device action configfs attributes to allow user-space to
  trigger events separate from existing attributes exposed to end-users. (MNC)
- Fix iscsi-target NULL pointer dereference 4.6+ regression in CHAP error path.
  (David Disseldorp)
- Avoid target-core backend UNMAP callbacks if range is zero. (Andrei Vagin)
- Fix a iscsi-target 4.14+ regression related multiple PDU logins, that
  was exposed due to removal of TCP prequeue support. (Florian Westphal + MNC)

Also, there is a iser-target bug still being worked on for post -rc1
code to address a long standing issue resulting in persistent
ib_post_send() failures, for RNICs with small max_send_sge.  

Thank you,

--nab

Andrei Vagin (1):
  target: don't call an unmap callback if a range length is zero

David Disseldorp (1):
  target/iscsi: avoid NULL dereference in CHAP auth error path

Florian Westphal (1):
  iscsi-target: make sure to wake up sleeping login worker

Luis de Bethencourt (1):
  tcmu: Fix trailing semicolon

Markus Elfring (7):
  sbp-target: Delete an error message for a failed memory allocation in
three functions
  target: tcm_loop: Delete an error message for a failed memory
allocation in four functions
  target: tcm_loop: Improve a size determination in two functions
  target: tcm_loop: Combine substrings for 26 messages
  target: tcm_loop: Delete two unnecessary variable initialisations in
tcm_loop_issue_tmr()
  target: tcm_loop: Delete an unnecessary return statement in
tcm_loop_submission_work()
  target: tcm_loop: Use seq_puts() in tcm_loop_show_info()

Mike Christie (19):
  tcmu: merge common block release code
  tcmu: split unmap_thread_fn
  tcmu: fix unmap thread race
  tcmu: move expired command completion to unmap thread
  tcmu: remove commands_lock
  tcmu: release blocks for partially setup cmds
  tcmu: simplify scatter_data_area error handling
  tcmu: fix free block calculation
  tcmu: prep queue_cmd_ring to be used by unmap wq
  tcmu: simplify dbi thresh handling
  tcmu: don't block submitting context for block waits
  tcmu: make ring buffer timer configurable
  tcmu: allow max block and global max blocks to be settable
  tcmu: prevent corruption when invalid data page requested
  target: add SAM_STAT_BUSY sense reason
  target_core_user: add cmd id to broken ring message
  target core: add device action configfs files
  tcmu: allow userspace to reset ring
  tcmu: fix cmd user after free

Rasmus Villemoes (1):
  target-core: don't use "const char*" for a buffer that is written to

Varun Prakash (1):
  cxgbit: call neigh_event_send() to update MAC address

Wei Yongjun (1):
  tcmu: fix error return code in tcmu_configure_device()

Xiubo Li (1):
  tcmu: clean up the scatter helper

tangwenji (2):
  tcmu: fix page addr in tcmu_flush_dcache_range
  target: fix destroy device in target_configure_device

 drivers/target/iscsi/cxgbit/cxgbit_cm.c  |   3 +
 drivers/target/iscsi/iscsi_target_auth.c |   3 +-
 drivers/target/iscsi/iscsi_target_nego.c |   3 +
 drivers/target/loopback/tcm_loop.c   | 145 ++---
 drivers/target/sbp/sbp_target.c  |  13 +-
 drivers/target/target_core_configfs.c|   6 +
 drivers/target/target_core_device.c  |   4 +-
 drivers/target/target_core_fabric_lib.c  |   6 +-
 drivers/target/target_core_internal.h|   3 +-
 drivers/target/target_core_pr.c  |   4 +-
 drivers/target/target_core_sbc.c |   8 +-
 drivers/target/target_core_transport.c   |   3 +
 drivers/target/target_core_user.c| 983 ++-
 include/target/target_core_backend.h |   1 +
 include/target/target_core_base.h|   2 +
 15 files changed, 798 insertions(+), 389 deletions(-)



[GIT PULL] target updates for v4.16-rc1

2018-02-09 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending updates for v4.16-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

The highlights include:

- Numerous target-core-user improvements related to queue full and timeout 
handling. (MNC)
- Prevent target-core-user corruption when invalid data page is requested. (MNC)
- Add target-core device action configfs attributes to allow user-space to
  trigger events separate from existing attributes exposed to end-users. (MNC)
- Fix iscsi-target NULL pointer dereference 4.6+ regression in CHAP error path.
  (David Disseldorp)
- Avoid target-core backend UNMAP callbacks if range is zero. (Andrei Vagin)
- Fix a iscsi-target 4.14+ regression related multiple PDU logins, that
  was exposed due to removal of TCP prequeue support. (Florian Westphal + MNC)

Also, there is a iser-target bug still being worked on for post -rc1
code to address a long standing issue resulting in persistent
ib_post_send() failures, for RNICs with small max_send_sge.  

Thank you,

--nab

Andrei Vagin (1):
  target: don't call an unmap callback if a range length is zero

David Disseldorp (1):
  target/iscsi: avoid NULL dereference in CHAP auth error path

Florian Westphal (1):
  iscsi-target: make sure to wake up sleeping login worker

Luis de Bethencourt (1):
  tcmu: Fix trailing semicolon

Markus Elfring (7):
  sbp-target: Delete an error message for a failed memory allocation in
three functions
  target: tcm_loop: Delete an error message for a failed memory
allocation in four functions
  target: tcm_loop: Improve a size determination in two functions
  target: tcm_loop: Combine substrings for 26 messages
  target: tcm_loop: Delete two unnecessary variable initialisations in
tcm_loop_issue_tmr()
  target: tcm_loop: Delete an unnecessary return statement in
tcm_loop_submission_work()
  target: tcm_loop: Use seq_puts() in tcm_loop_show_info()

Mike Christie (19):
  tcmu: merge common block release code
  tcmu: split unmap_thread_fn
  tcmu: fix unmap thread race
  tcmu: move expired command completion to unmap thread
  tcmu: remove commands_lock
  tcmu: release blocks for partially setup cmds
  tcmu: simplify scatter_data_area error handling
  tcmu: fix free block calculation
  tcmu: prep queue_cmd_ring to be used by unmap wq
  tcmu: simplify dbi thresh handling
  tcmu: don't block submitting context for block waits
  tcmu: make ring buffer timer configurable
  tcmu: allow max block and global max blocks to be settable
  tcmu: prevent corruption when invalid data page requested
  target: add SAM_STAT_BUSY sense reason
  target_core_user: add cmd id to broken ring message
  target core: add device action configfs files
  tcmu: allow userspace to reset ring
  tcmu: fix cmd user after free

Rasmus Villemoes (1):
  target-core: don't use "const char*" for a buffer that is written to

Varun Prakash (1):
  cxgbit: call neigh_event_send() to update MAC address

Wei Yongjun (1):
  tcmu: fix error return code in tcmu_configure_device()

Xiubo Li (1):
  tcmu: clean up the scatter helper

tangwenji (2):
  tcmu: fix page addr in tcmu_flush_dcache_range
  target: fix destroy device in target_configure_device

 drivers/target/iscsi/cxgbit/cxgbit_cm.c  |   3 +
 drivers/target/iscsi/iscsi_target_auth.c |   3 +-
 drivers/target/iscsi/iscsi_target_nego.c |   3 +
 drivers/target/loopback/tcm_loop.c   | 145 ++---
 drivers/target/sbp/sbp_target.c  |  13 +-
 drivers/target/target_core_configfs.c|   6 +
 drivers/target/target_core_device.c  |   4 +-
 drivers/target/target_core_fabric_lib.c  |   6 +-
 drivers/target/target_core_internal.h|   3 +-
 drivers/target/target_core_pr.c  |   4 +-
 drivers/target/target_core_sbc.c |   8 +-
 drivers/target/target_core_transport.c   |   3 +
 drivers/target/target_core_user.c| 983 ++-
 include/target/target_core_backend.h |   1 +
 include/target/target_core_base.h|   2 +
 15 files changed, 798 insertions(+), 389 deletions(-)



Re: [PATCH] tcmu: Fix trailing semicolon

2018-01-18 Thread Nicholas A. Bellinger
On Tue, 2018-01-16 at 10:25 -0600, Michael Christie wrote:
> On 01/16/2018 09:34 AM, Luis de Bethencourt wrote:
> > The trailing semicolon is an empty statement that does no operation.
> > It is completely stripped out by the compiler. Removing it since it doesn't 
> > do
> > anything.
> > 
> > Signed-off-by: Luis de Bethencourt 
> > ---
> > 
> > Hi,
> > 
> > After fixing the same thing in drivers/staging/rtl8723bs/, Joe Perches
> > suggested I fix it treewide [0].
> > 
> > Best regards 
> > Luis
> > 
> > 
> > [0] 
> > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-January/115410.html
> > [1] 
> > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-January/115390.html
> > 
> >  drivers/target/target_core_user.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 

Applied.  Thanks Luis + MNC.



Re: [PATCH] tcmu: Fix trailing semicolon

2018-01-18 Thread Nicholas A. Bellinger
On Tue, 2018-01-16 at 10:25 -0600, Michael Christie wrote:
> On 01/16/2018 09:34 AM, Luis de Bethencourt wrote:
> > The trailing semicolon is an empty statement that does no operation.
> > It is completely stripped out by the compiler. Removing it since it doesn't 
> > do
> > anything.
> > 
> > Signed-off-by: Luis de Bethencourt 
> > ---
> > 
> > Hi,
> > 
> > After fixing the same thing in drivers/staging/rtl8723bs/, Joe Perches
> > suggested I fix it treewide [0].
> > 
> > Best regards 
> > Luis
> > 
> > 
> > [0] 
> > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-January/115410.html
> > [1] 
> > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-January/115390.html
> > 
> >  drivers/target/target_core_user.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 

Applied.  Thanks Luis + MNC.



Re: [PATCH] target-core: don't use "const char*" for a buffer that is written to

2018-01-12 Thread Nicholas A. Bellinger
Hi Rasmus,

Apologies for the delayed follow-up on this.

On Tue, 2017-11-21 at 01:12 +0100, Rasmus Villemoes wrote:
> From: Rasmus Villemoes 
> 
> iscsi_parse_pr_out_transport_id launders the const away via a call to
> strstr(), and then modifies the buffer (writing a nul byte) through
> the return value. It's cleaner to be honest and simply declare the
> parameter as "char*", fixing up the call chain, and allowing us to
> drop the cast in the return statement.
> 
> Amusingly, the two current callers found it necessary to cast a
> non-const pointer to a const.
> 
> Signed-off-by: Rasmus Villemoes 
> ---
>  drivers/target/target_core_fabric_lib.c | 6 +++---
>  drivers/target/target_core_internal.h   | 2 +-
>  drivers/target/target_core_pr.c | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 

Looks fine.  Applied.

Thank you.




Re: [PATCH] target-core: don't use "const char*" for a buffer that is written to

2018-01-12 Thread Nicholas A. Bellinger
Hi Rasmus,

Apologies for the delayed follow-up on this.

On Tue, 2017-11-21 at 01:12 +0100, Rasmus Villemoes wrote:
> From: Rasmus Villemoes 
> 
> iscsi_parse_pr_out_transport_id launders the const away via a call to
> strstr(), and then modifies the buffer (writing a nul byte) through
> the return value. It's cleaner to be honest and simply declare the
> parameter as "char*", fixing up the call chain, and allowing us to
> drop the cast in the return statement.
> 
> Amusingly, the two current callers found it necessary to cast a
> non-const pointer to a const.
> 
> Signed-off-by: Rasmus Villemoes 
> ---
>  drivers/target/target_core_fabric_lib.c | 6 +++---
>  drivers/target/target_core_internal.h   | 2 +-
>  drivers/target/target_core_pr.c | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 

Looks fine.  Applied.

Thank you.




Re: [PATCH] target: don't call an unmap callback if a range length is zero

2018-01-12 Thread Nicholas A. Bellinger
Hi Andrei,

Apologies for the delayed follow up.

On Wed, 2017-12-13 at 13:55 -0800, Andrei Vagin wrote:
> If a length of a range is zero, it means there is nothing to unmap
> and we can skip this range.
> 
> Here is one more reason, why we have to skip such ranges.  An unmap
> callback calls file_operations->fallocate(), but the man page for the
> fallocate syscall says that fallocate(fd, mode, offset, let) returns
> EINVAL, if len is zero. It means that file_operations->fallocate() isn't
> obligated to handle zero ranges too.
> 
> Signed-off-by: Andrei Vagin 
> ---
>  drivers/target/target_core_sbc.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 

Applied.

Thank you.



Re: [PATCH] target: don't call an unmap callback if a range length is zero

2018-01-12 Thread Nicholas A. Bellinger
Hi Andrei,

Apologies for the delayed follow up.

On Wed, 2017-12-13 at 13:55 -0800, Andrei Vagin wrote:
> If a length of a range is zero, it means there is nothing to unmap
> and we can skip this range.
> 
> Here is one more reason, why we have to skip such ranges.  An unmap
> callback calls file_operations->fallocate(), but the man page for the
> fallocate syscall says that fallocate(fd, mode, offset, let) returns
> EINVAL, if len is zero. It means that file_operations->fallocate() isn't
> obligated to handle zero ranges too.
> 
> Signed-off-by: Andrei Vagin 
> ---
>  drivers/target/target_core_sbc.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 

Applied.

Thank you.



[GIT PULL] target updates for v4.15-rc1

2017-11-23 Thread Nicholas A. Bellinger
Hello Linus,

Here are the target-pending updates for v4.15-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

This series is predominantly bug-fixes, with a few small improvements
that have been outstanding over the last release cycle.

As usual, the associated bug-fixes have CC' tags for stable.

Also, things have been particularly quiet wrt new developments the last
months, with most folks continuing to focus on stability atop 4.x stable
kernels for their respective production configurations.

Also at this point, the stable trees have been synced up with mainline.
This will continue to be a priority, as production users tend to run
exclusively atop stable kernels, a few releases behind mainline.

The highlights include:

 - target: Fix PR PREEMPT_AND_ABORT null pointer dereference regression
   in v4.11+ (tangwenji)
 - target/user: Fix OOPs during removing TCMU device (Xiubo Li + Zhang Zhuoyu)
 - target/user: Add netlink command reply supported option for each device
(Kenjiro Nakayama)
 - cxgbit: Abort the TCP connection in case of data out timeout (Varun Prakash)
 - target: Fix PR/ALUA file path truncation (David Disseldorp)
 - target/user: Fix double se_cmd completion during ->cmd_time_out (Mike 
Christie)
 - target: Fix QUEUE_FULL + SCSI task attribute handling in 4.1+ (Bryant Ly + 
nab)
 - target: Fix quiese during transport_write_pending_qf endless loop (nab)
 - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK in 3.14+
   (Don White + nab)

Thank you,

--nab

Bart Van Assche (9):
  target: Move a declaration of a global variable into a header file
  target: Suppress gcc 7 fallthrough warnings
  target: Inline transport_put_cmd()
  target/iscsi: Define OFFLOAD_BUF_SIZE once
  target/iscsi: Use min() in iscsit_dump_data_payload() instead of
open-coding it
  target/iscsi: Fix endianness in an error message
  target/iscsi: Modify iscsit_do_crypto_hash_buf() prototype
  target/iscsi: Fix a race condition in iscsit_add_reject_from_cmd()
  target/iscsi: Detect conn_cmd_list corruption early

Dan Carpenter (2):
  tcmu: Fix some memory corruption
  tcmu: Add a missing unlock on an error path

David Disseldorp (2):
  target: fix PR state file path truncation
  target: fix ALUA state file path truncation

Jiang Yi (1):
  target/file: Do not return error for UNMAP if length is zero

Kenjiro Nakayama (2):
  target/tcmu: Use macro to call container_of in tcmu_cmd_time_out_show
  target: Add netlink command reply supported option for each device

Markus Elfring (1):
  iSCSI-target: Use common error handling code in
iscsi_decode_text_input()

Mike Christie (2):
  target: return SAM_STAT_TASK_SET_FULL for TCM_OUT_OF_RESOURCES
  tcmu: fix double se_cmd completion

Nicholas Bellinger (6):
  target: Fix QUEUE_FULL + SCSI task attribute handling
  target: Fix caw_sem leak in transport_generic_request_failure
  target: Fix quiese during transport_write_pending_qf endless loop
  target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
  iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
  iscsi-target: Fix non-immediate TMR reference leak

Varun Prakash (1):
  cxgbit: Abort the TCP connection in case of data out timeout

Xiubo Li (1):
  tcmu: fix crash when removing the tcmu device

tangwenji (8):
  target: fix null pointer regression in core_tmr_drain_tmr_list
  target: fix buffer offset in core_scsi3_pri_read_full_status
  target: fix double unmap data sg in
core_scsi3_emulate_pro_register_and_move()
  target: add sense code INSUFFICIENT REGISTRATION RESOURCES
  target: fix match_token option in target_core_configfs.c
  target:fix condition return in core_pr_dump_initiator_port()
  iscsi-target: fix memory leak in lio_target_tiqn_addtpg()
  iscsi-target: fix memory leak in iscsit_release_discovery_tpg()

 drivers/target/iscsi/cxgbit/cxgbit.h |   2 +
 drivers/target/iscsi/cxgbit/cxgbit_cm.c  |  45 +
 drivers/target/iscsi/cxgbit/cxgbit_ddp.c |   8 +
 drivers/target/iscsi/cxgbit/cxgbit_main.c|   1 +
 drivers/target/iscsi/iscsi_target.c  |  80 -
 drivers/target/iscsi/iscsi_target_configfs.c |   3 +-
 drivers/target/iscsi/iscsi_target_erl1.c |   7 +-
 drivers/target/iscsi/iscsi_target_parameters.c   |  39 ++---
 drivers/target/iscsi/iscsi_target_seq_pdu_list.c |   2 -
 drivers/target/iscsi/iscsi_target_tpg.c  |   7 +-
 drivers/target/iscsi/iscsi_target_util.c |   4 +
 drivers/target/target_core_alua.c|  51 +++---
 drivers/target/target_core_alua.h|   9 -
 drivers/target/target_core_configfs.c|  14 +-
 drivers/target/target_core_fabric_configfs.c |   2 -
 drivers/target/target_core_file.c|   4 +
 drivers/target/target_core_internal.h|   1 +
 drivers/target/target_core_pr.c  |  41 ++---
 drivers/

[GIT PULL] target updates for v4.15-rc1

2017-11-23 Thread Nicholas A. Bellinger
Hello Linus,

Here are the target-pending updates for v4.15-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

This series is predominantly bug-fixes, with a few small improvements
that have been outstanding over the last release cycle.

As usual, the associated bug-fixes have CC' tags for stable.

Also, things have been particularly quiet wrt new developments the last
months, with most folks continuing to focus on stability atop 4.x stable
kernels for their respective production configurations.

Also at this point, the stable trees have been synced up with mainline.
This will continue to be a priority, as production users tend to run
exclusively atop stable kernels, a few releases behind mainline.

The highlights include:

 - target: Fix PR PREEMPT_AND_ABORT null pointer dereference regression
   in v4.11+ (tangwenji)
 - target/user: Fix OOPs during removing TCMU device (Xiubo Li + Zhang Zhuoyu)
 - target/user: Add netlink command reply supported option for each device
(Kenjiro Nakayama)
 - cxgbit: Abort the TCP connection in case of data out timeout (Varun Prakash)
 - target: Fix PR/ALUA file path truncation (David Disseldorp)
 - target/user: Fix double se_cmd completion during ->cmd_time_out (Mike 
Christie)
 - target: Fix QUEUE_FULL + SCSI task attribute handling in 4.1+ (Bryant Ly + 
nab)
 - target: Fix quiese during transport_write_pending_qf endless loop (nab)
 - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK in 3.14+
   (Don White + nab)

Thank you,

--nab

Bart Van Assche (9):
  target: Move a declaration of a global variable into a header file
  target: Suppress gcc 7 fallthrough warnings
  target: Inline transport_put_cmd()
  target/iscsi: Define OFFLOAD_BUF_SIZE once
  target/iscsi: Use min() in iscsit_dump_data_payload() instead of
open-coding it
  target/iscsi: Fix endianness in an error message
  target/iscsi: Modify iscsit_do_crypto_hash_buf() prototype
  target/iscsi: Fix a race condition in iscsit_add_reject_from_cmd()
  target/iscsi: Detect conn_cmd_list corruption early

Dan Carpenter (2):
  tcmu: Fix some memory corruption
  tcmu: Add a missing unlock on an error path

David Disseldorp (2):
  target: fix PR state file path truncation
  target: fix ALUA state file path truncation

Jiang Yi (1):
  target/file: Do not return error for UNMAP if length is zero

Kenjiro Nakayama (2):
  target/tcmu: Use macro to call container_of in tcmu_cmd_time_out_show
  target: Add netlink command reply supported option for each device

Markus Elfring (1):
  iSCSI-target: Use common error handling code in
iscsi_decode_text_input()

Mike Christie (2):
  target: return SAM_STAT_TASK_SET_FULL for TCM_OUT_OF_RESOURCES
  tcmu: fix double se_cmd completion

Nicholas Bellinger (6):
  target: Fix QUEUE_FULL + SCSI task attribute handling
  target: Fix caw_sem leak in transport_generic_request_failure
  target: Fix quiese during transport_write_pending_qf endless loop
  target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
  iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
  iscsi-target: Fix non-immediate TMR reference leak

Varun Prakash (1):
  cxgbit: Abort the TCP connection in case of data out timeout

Xiubo Li (1):
  tcmu: fix crash when removing the tcmu device

tangwenji (8):
  target: fix null pointer regression in core_tmr_drain_tmr_list
  target: fix buffer offset in core_scsi3_pri_read_full_status
  target: fix double unmap data sg in
core_scsi3_emulate_pro_register_and_move()
  target: add sense code INSUFFICIENT REGISTRATION RESOURCES
  target: fix match_token option in target_core_configfs.c
  target:fix condition return in core_pr_dump_initiator_port()
  iscsi-target: fix memory leak in lio_target_tiqn_addtpg()
  iscsi-target: fix memory leak in iscsit_release_discovery_tpg()

 drivers/target/iscsi/cxgbit/cxgbit.h |   2 +
 drivers/target/iscsi/cxgbit/cxgbit_cm.c  |  45 +
 drivers/target/iscsi/cxgbit/cxgbit_ddp.c |   8 +
 drivers/target/iscsi/cxgbit/cxgbit_main.c|   1 +
 drivers/target/iscsi/iscsi_target.c  |  80 -
 drivers/target/iscsi/iscsi_target_configfs.c |   3 +-
 drivers/target/iscsi/iscsi_target_erl1.c |   7 +-
 drivers/target/iscsi/iscsi_target_parameters.c   |  39 ++---
 drivers/target/iscsi/iscsi_target_seq_pdu_list.c |   2 -
 drivers/target/iscsi/iscsi_target_tpg.c  |   7 +-
 drivers/target/iscsi/iscsi_target_util.c |   4 +
 drivers/target/target_core_alua.c|  51 +++---
 drivers/target/target_core_alua.h|   9 -
 drivers/target/target_core_configfs.c|  14 +-
 drivers/target/target_core_fabric_configfs.c |   2 -
 drivers/target/target_core_file.c|   4 +
 drivers/target/target_core_internal.h|   1 +
 drivers/target/target_core_pr.c  |  41 ++---
 drivers/

[PATCH 0/6] target fixes for v4.15-rc1

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Hi all,

Here are the outstanding target bugfixes in queue for v4.15-rc1
code.

Patch #1 addresses a long standing bug wrt to QUEUE_FULL and
SCSI task attribute handling, that results in SCSI task related
counters getting updated multiple times during QUEUE_FULL.

It primarly effects hosts using ORDERED tasks, which depend upon
these counters to know when to delay incoming tasks.

Patch #2 is for a recent v4.11+ regression, which during ABORT
of COMPARE_AND_WRITE can result in se_device->cam_sem getting
leaked due to se_cmd->transport_complete_callback() being
skipped.

Patch #3 addresses a possible end-less loop during QUEUE_FULL +
TFO->write_pending() failure, allowing se_cmd quiese to properly
complete the outstanding descriptor when requested.

Patch #4 addresses a use-after-tree that was hit in the field,
involving pre-backend execution se_cmd exceptions + subsequent
ABORT_TASK for a matching tag.

Patch #5 + #6 address a iscsi-target TMR related memory and
se_cmd->cmd_kref reference leaks respectively.

We've been testing #4, #5, and #6 internally on v4.1.y stable
code, and have not run into additional regressions.

The rest are straight-forward.

Please review.

--nab

Nicholas Bellinger (6):
  target: Fix QUEUE_FULL + SCSI task attribute handling
  target: Fix caw_sem leak in transport_generic_request_failure
  target: Fix quiese during transport_write_pending_qf endless loop
  target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
  iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
  iscsi-target: Fix non-immediate TMR reference leak

 drivers/target/iscsi/iscsi_target.c| 30 ++
 drivers/target/target_core_tmr.c   |  9 +
 drivers/target/target_core_transport.c | 26 +++---
 include/target/target_core_base.h  |  1 +
 4 files changed, 47 insertions(+), 19 deletions(-)

-- 
1.9.1



[PATCH 6/6] iscsi-target: Fix non-immediate TMR reference leak

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a se_cmd->cmd_kref reference leak that can
occur when a non immediate TMR is proceeded our of command
sequence number order, and CMDSN_LOWER_THAN_EXP is returned
by iscsit_sequence_cmd().

To address this bug, call target_put_sess_cmd() during this
special case following what iscsit_process_scsi_cmd() does
upon CMDSN_LOWER_THAN_EXP.

Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 048d422..3b7bb58 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -2094,12 +2094,14 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
-   if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
+   if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) {
out_of_order_cmdsn = 1;
-   else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+   } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+   target_put_sess_cmd(>se_cmd);
return 0;
-   else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+   } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
return -1;
+   }
}
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
-- 
1.9.1



[PATCH 1/6] target: Fix QUEUE_FULL + SCSI task attribute handling

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a bug during QUEUE_FULL where transport_complete_qf()
calls transport_complete_task_attr() after it's already been invoked
by target_complete_ok_work() or transport_generic_request_failure()
during initial completion, preceeding QUEUE_FULL.

This will result in se_device->simple_cmds, se_device->dev_cur_ordered_id
and/or se_device->dev_ordered_sync being updated multiple times for
a single se_cmd.

To address this bug, clear SCF_TASK_ATTR_SET after the first call
to transport_complete_task_attr(), and avoid updating SCSI task
attribute related counters for any subsequent calls.

Also, when a se_cmd is deferred due to ordered tags and executed
via target_restart_delayed_cmds(), set CMD_T_SENT before execution
matching what target_execute_cmd() does.

Cc: Michael Cyr <mike...@linux.vnet.ibm.com>
Cc: Bryant G. Ly <bryan...@linux.vnet.ibm.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_transport.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 473d652..c33d1e9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2011,6 +2011,8 @@ static void target_restart_delayed_cmds(struct se_device 
*dev)
list_del(>se_delayed_node);
spin_unlock(>delayed_cmd_lock);
 
+   cmd->transport_state |= CMD_T_SENT;
+
__target_execute_cmd(cmd, true);
 
if (cmd->sam_task_attr == TCM_ORDERED_TAG)
@@ -2046,6 +2048,8 @@ static void transport_complete_task_attr(struct se_cmd 
*cmd)
pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n",
 dev->dev_cur_ordered_id);
}
+   cmd->se_cmd_flags &= ~SCF_TASK_ATTR_SET;
+
 restart:
target_restart_delayed_cmds(dev);
 }
-- 
1.9.1



[PATCH 0/6] target fixes for v4.15-rc1

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Hi all,

Here are the outstanding target bugfixes in queue for v4.15-rc1
code.

Patch #1 addresses a long standing bug wrt to QUEUE_FULL and
SCSI task attribute handling, that results in SCSI task related
counters getting updated multiple times during QUEUE_FULL.

It primarly effects hosts using ORDERED tasks, which depend upon
these counters to know when to delay incoming tasks.

Patch #2 is for a recent v4.11+ regression, which during ABORT
of COMPARE_AND_WRITE can result in se_device->cam_sem getting
leaked due to se_cmd->transport_complete_callback() being
skipped.

Patch #3 addresses a possible end-less loop during QUEUE_FULL +
TFO->write_pending() failure, allowing se_cmd quiese to properly
complete the outstanding descriptor when requested.

Patch #4 addresses a use-after-tree that was hit in the field,
involving pre-backend execution se_cmd exceptions + subsequent
ABORT_TASK for a matching tag.

Patch #5 + #6 address a iscsi-target TMR related memory and
se_cmd->cmd_kref reference leaks respectively.

We've been testing #4, #5, and #6 internally on v4.1.y stable
code, and have not run into additional regressions.

The rest are straight-forward.

Please review.

--nab

Nicholas Bellinger (6):
  target: Fix QUEUE_FULL + SCSI task attribute handling
  target: Fix caw_sem leak in transport_generic_request_failure
  target: Fix quiese during transport_write_pending_qf endless loop
  target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
  iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
  iscsi-target: Fix non-immediate TMR reference leak

 drivers/target/iscsi/iscsi_target.c| 30 ++
 drivers/target/target_core_tmr.c   |  9 +
 drivers/target/target_core_transport.c | 26 +++---
 include/target/target_core_base.h  |  1 +
 4 files changed, 47 insertions(+), 19 deletions(-)

-- 
1.9.1



[PATCH 6/6] iscsi-target: Fix non-immediate TMR reference leak

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a se_cmd->cmd_kref reference leak that can
occur when a non immediate TMR is proceeded our of command
sequence number order, and CMDSN_LOWER_THAN_EXP is returned
by iscsit_sequence_cmd().

To address this bug, call target_put_sess_cmd() during this
special case following what iscsit_process_scsi_cmd() does
upon CMDSN_LOWER_THAN_EXP.

Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 048d422..3b7bb58 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -2094,12 +2094,14 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
-   if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
+   if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) {
out_of_order_cmdsn = 1;
-   else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+   } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+   target_put_sess_cmd(>se_cmd);
return 0;
-   else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+   } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
return -1;
+   }
}
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
-- 
1.9.1



[PATCH 1/6] target: Fix QUEUE_FULL + SCSI task attribute handling

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a bug during QUEUE_FULL where transport_complete_qf()
calls transport_complete_task_attr() after it's already been invoked
by target_complete_ok_work() or transport_generic_request_failure()
during initial completion, preceeding QUEUE_FULL.

This will result in se_device->simple_cmds, se_device->dev_cur_ordered_id
and/or se_device->dev_ordered_sync being updated multiple times for
a single se_cmd.

To address this bug, clear SCF_TASK_ATTR_SET after the first call
to transport_complete_task_attr(), and avoid updating SCSI task
attribute related counters for any subsequent calls.

Also, when a se_cmd is deferred due to ordered tags and executed
via target_restart_delayed_cmds(), set CMD_T_SENT before execution
matching what target_execute_cmd() does.

Cc: Michael Cyr 
Cc: Bryant G. Ly 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_transport.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 473d652..c33d1e9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2011,6 +2011,8 @@ static void target_restart_delayed_cmds(struct se_device 
*dev)
list_del(>se_delayed_node);
spin_unlock(>delayed_cmd_lock);
 
+   cmd->transport_state |= CMD_T_SENT;
+
__target_execute_cmd(cmd, true);
 
if (cmd->sam_task_attr == TCM_ORDERED_TAG)
@@ -2046,6 +2048,8 @@ static void transport_complete_task_attr(struct se_cmd 
*cmd)
pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n",
 dev->dev_cur_ordered_id);
}
+   cmd->se_cmd_flags &= ~SCF_TASK_ATTR_SET;
+
 restart:
target_restart_delayed_cmds(dev);
 }
-- 
1.9.1



[PATCH 4/6] target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes bug where early se_cmd exceptions that occur
before backend execution can result in use-after-free if/when
a subsequent ABORT_TASK occurs for the same tag.

Since an early se_cmd exception will have had se_cmd added to
se_session->sess_cmd_list via target_get_sess_cmd(), it will
not have CMD_T_COMPLETE set by the usual target_complete_cmd()
backend completion path.

This causes a subsequent ABORT_TASK + __target_check_io_state()
to signal ABORT_TASK should proceed.  As core_tmr_abort_task()
executes, it will bring the outstanding se_cmd->cmd_kref count
down to zero releasing se_cmd, after se_cmd has already been
queued with error status into fabric driver response path code.

To address this bug, introduce a CMD_T_PRE_EXECUTE bit that is
set at target_get_sess_cmd() time, and cleared immediately before
backend driver dispatch in target_execute_cmd() once CMD_T_ACTIVE
is set.

Then, check CMD_T_PRE_EXECUTE within __target_check_io_state() to
determine when an early exception has occured, and avoid aborting
this se_cmd since it will have already been queued into fabric
driver response path code.

Reported-by: Donald White <d...@datera.io>
Cc: Donald White <d...@datera.io>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_tmr.c   | 9 +
 drivers/target/target_core_transport.c | 2 ++
 include/target/target_core_base.h  | 1 +
 3 files changed, 12 insertions(+)

diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 61909b2..9c7bc1c 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -133,6 +133,15 @@ static bool __target_check_io_state(struct se_cmd *se_cmd,
spin_unlock(_cmd->t_state_lock);
return false;
}
+   if (se_cmd->transport_state & CMD_T_PRE_EXECUTE) {
+   if (se_cmd->scsi_status) {
+   pr_debug("Attempted to abort io tag: %llu early failure"
+" status: 0x%02x\n", se_cmd->tag,
+se_cmd->scsi_status);
+   spin_unlock(_cmd->t_state_lock);
+   return false;
+   }
+   }
if (sess->sess_tearing_down || se_cmd->cmd_wait_set) {
pr_debug("Attempted to abort io tag: %llu already shutdown,"
" skipping\n", se_cmd->tag);
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 0e89db8..58caacd 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1975,6 +1975,7 @@ void target_execute_cmd(struct se_cmd *cmd)
}
 
cmd->t_state = TRANSPORT_PROCESSING;
+   cmd->transport_state &= ~CMD_T_PRE_EXECUTE;
cmd->transport_state |= CMD_T_ACTIVE | CMD_T_SENT;
spin_unlock_irq(>t_state_lock);
 
@@ -2667,6 +2668,7 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool 
ack_kref)
ret = -ESHUTDOWN;
goto out;
}
+   se_cmd->transport_state |= CMD_T_PRE_EXECUTE;
list_add_tail(_cmd->se_cmd_list, _sess->sess_cmd_list);
 out:
spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index d3139a9..ccf501b 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -490,6 +490,7 @@ struct se_cmd {
 #define CMD_T_STOP (1 << 5)
 #define CMD_T_TAS  (1 << 10)
 #define CMD_T_FABRIC_STOP  (1 << 11)
+#define CMD_T_PRE_EXECUTE  (1 << 12)
spinlock_t  t_state_lock;
struct kref cmd_kref;
struct completion   t_transport_stop_comp;
-- 
1.9.1



[PATCH 4/6] target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes bug where early se_cmd exceptions that occur
before backend execution can result in use-after-free if/when
a subsequent ABORT_TASK occurs for the same tag.

Since an early se_cmd exception will have had se_cmd added to
se_session->sess_cmd_list via target_get_sess_cmd(), it will
not have CMD_T_COMPLETE set by the usual target_complete_cmd()
backend completion path.

This causes a subsequent ABORT_TASK + __target_check_io_state()
to signal ABORT_TASK should proceed.  As core_tmr_abort_task()
executes, it will bring the outstanding se_cmd->cmd_kref count
down to zero releasing se_cmd, after se_cmd has already been
queued with error status into fabric driver response path code.

To address this bug, introduce a CMD_T_PRE_EXECUTE bit that is
set at target_get_sess_cmd() time, and cleared immediately before
backend driver dispatch in target_execute_cmd() once CMD_T_ACTIVE
is set.

Then, check CMD_T_PRE_EXECUTE within __target_check_io_state() to
determine when an early exception has occured, and avoid aborting
this se_cmd since it will have already been queued into fabric
driver response path code.

Reported-by: Donald White 
Cc: Donald White 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_tmr.c   | 9 +
 drivers/target/target_core_transport.c | 2 ++
 include/target/target_core_base.h  | 1 +
 3 files changed, 12 insertions(+)

diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 61909b2..9c7bc1c 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -133,6 +133,15 @@ static bool __target_check_io_state(struct se_cmd *se_cmd,
spin_unlock(_cmd->t_state_lock);
return false;
}
+   if (se_cmd->transport_state & CMD_T_PRE_EXECUTE) {
+   if (se_cmd->scsi_status) {
+   pr_debug("Attempted to abort io tag: %llu early failure"
+" status: 0x%02x\n", se_cmd->tag,
+se_cmd->scsi_status);
+   spin_unlock(_cmd->t_state_lock);
+   return false;
+   }
+   }
if (sess->sess_tearing_down || se_cmd->cmd_wait_set) {
pr_debug("Attempted to abort io tag: %llu already shutdown,"
" skipping\n", se_cmd->tag);
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 0e89db8..58caacd 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1975,6 +1975,7 @@ void target_execute_cmd(struct se_cmd *cmd)
}
 
cmd->t_state = TRANSPORT_PROCESSING;
+   cmd->transport_state &= ~CMD_T_PRE_EXECUTE;
cmd->transport_state |= CMD_T_ACTIVE | CMD_T_SENT;
spin_unlock_irq(>t_state_lock);
 
@@ -2667,6 +2668,7 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool 
ack_kref)
ret = -ESHUTDOWN;
goto out;
}
+   se_cmd->transport_state |= CMD_T_PRE_EXECUTE;
list_add_tail(_cmd->se_cmd_list, _sess->sess_cmd_list);
 out:
spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index d3139a9..ccf501b 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -490,6 +490,7 @@ struct se_cmd {
 #define CMD_T_STOP (1 << 5)
 #define CMD_T_TAS  (1 << 10)
 #define CMD_T_FABRIC_STOP  (1 << 11)
+#define CMD_T_PRE_EXECUTE  (1 << 12)
spinlock_t  t_state_lock;
struct kref cmd_kref;
struct completion   t_transport_stop_comp;
-- 
1.9.1



[PATCH 5/6] iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Since commit 59b6986dbf fixed a potential NULL pointer dereference
by allocating a se_tmr_req for ISCSI_TM_FUNC_TASK_REASSIGN, the
se_tmr_req is currently leaked by iscsit_free_cmd() because no
iscsi_cmd->se_cmd.se_tfo was associated.

To address this, treat ISCSI_TM_FUNC_TASK_REASSIGN like any other
TMR and call transport_init_se_cmd() + target_get_sess_cmd() to
setup iscsi_cmd->se_cmd.se_tfo with se_cmd->cmd_kref of 2.

This will ensure normal release operation once se_cmd->cmd_kref
reaches zero and target_release_cmd_kref() is invoked, se_tmr_req
will be released via existing target_free_cmd_mem() and
core_tmr_release_req() code.

Reported-by: Donald White <d...@datera.io>
Cc: Donald White <d...@datera.io>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 541f66a..048d422 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1955,7 +1955,6 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
struct iscsi_tmr_req *tmr_req;
struct iscsi_tm *hdr;
int out_of_order_cmdsn = 0, ret;
-   bool sess_ref = false;
u8 function, tcm_function = TMR_UNKNOWN;
 
hdr = (struct iscsi_tm *) buf;
@@ -1988,22 +1987,23 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 
cmd->data_direction = DMA_NONE;
cmd->tmr_req = kzalloc(sizeof(*cmd->tmr_req), GFP_KERNEL);
-   if (!cmd->tmr_req)
+   if (!cmd->tmr_req) {
return iscsit_add_reject_cmd(cmd,
 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
 buf);
+   }
+
+   transport_init_se_cmd(>se_cmd, _ops,
+ conn->sess->se_sess, 0, DMA_NONE,
+ TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
+
+   target_get_sess_cmd(>se_cmd, true);
 
/*
 * TASK_REASSIGN for ERL=2 / connection stays inside of
 * LIO-Target $FABRIC_MOD
 */
if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
-   transport_init_se_cmd(>se_cmd, _ops,
- conn->sess->se_sess, 0, DMA_NONE,
- TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
-
-   target_get_sess_cmd(>se_cmd, true);
-   sess_ref = true;
tcm_function = iscsit_convert_tmf(function);
if (tcm_function == TMR_UNKNOWN) {
pr_err("Unknown iSCSI TMR Function:"
@@ -2119,12 +2119,8 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 * For connection recovery, this is also the default action for
 * TMR TASK_REASSIGN.
 */
-   if (sess_ref) {
-   pr_debug("Handle TMR, using sess_ref=true check\n");
-   target_put_sess_cmd(>se_cmd);
-   }
-
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
+   target_put_sess_cmd(>se_cmd);
return 0;
 }
 EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
-- 
1.9.1



[PATCH 3/6] target: Fix quiese during transport_write_pending_qf endless loop

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a potential end-less loop during QUEUE_FULL,
where cmd->se_tfo->write_pending() callback fails repeatedly
but __transport_wait_for_tasks() has already been invoked to
quiese the outstanding se_cmd descriptor.

To address this bug, this patch adds a CMD_T_STOP|CMD_T_ABORTED
check within transport_write_pending_qf() and invokes the
existing se_cmd->t_transport_stop_comp to signal quiese
completion back to __transport_wait_for_tasks().

Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Bryant G. Ly <bryan...@linux.vnet.ibm.com>
Cc: Michael Cyr <mike...@linux.vnet.ibm.com>
Cc: Potnuri Bharat Teja <bha...@chelsio.com>
Cc: Sagi Grimberg <s...@grimberg.me>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_transport.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index d02218c..0e89db8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2560,7 +2560,20 @@ void transport_kunmap_data_sg(struct se_cmd *cmd)
 
 static void transport_write_pending_qf(struct se_cmd *cmd)
 {
+   unsigned long flags;
int ret;
+   bool stop;
+
+   spin_lock_irqsave(>t_state_lock, flags);
+   stop = (cmd->transport_state & (CMD_T_STOP | CMD_T_ABORTED));
+   spin_unlock_irqrestore(>t_state_lock, flags);
+
+   if (stop) {
+   pr_debug("%s:%d CMD_T_STOP|CMD_T_ABORTED for ITT: 0x%08llx\n",
+   __func__, __LINE__, cmd->tag);
+   complete_all(>t_transport_stop_comp);
+   return;
+   }
 
ret = cmd->se_tfo->write_pending(cmd);
if (ret) {
-- 
1.9.1



[PATCH 2/6] target: Fix caw_sem leak in transport_generic_request_failure

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

With the recent addition of transport_check_aborted_status() within
transport_generic_request_failure() to avoid sending a SCSI status
exception after CMD_T_ABORTED w/ TAS=1 has occured, it introduced
a COMPARE_AND_WRITE early failure regression.

Namely when COMPARE_AND_WRITE fails and se_device->caw_sem has
been taken by sbc_compare_and_write(), if the new check for
transport_check_aborted_status() returns true and exits,
cmd->transport_complete_callback() -> compare_and_write_post()
is skipped never releasing se_device->caw_sem.

This regression was originally introduced by:

  commit e3b88ee95b4e4bf3e9729a4695d695b9c7c296c8
  Author: Bart Van Assche <bart.vanass...@sandisk.com>
  Date:   Tue Feb 14 16:25:45 2017 -0800

  target: Fix handling of aborted failed commands

To address this bug, move the transport_check_aborted_status()
call after transport_complete_task_attr() and
cmd->transport_complete_callback().

Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Bart Van Assche <bart.vanass...@sandisk.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_transport.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index c33d1e9..d02218c 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1729,9 +1729,6 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 {
int ret = 0, post_ret = 0;
 
-   if (transport_check_aborted_status(cmd, 1))
-   return;
-
pr_debug("-[ Storage Engine Exception; sense_reason %d\n",
 sense_reason);
target_show_cmd("-[ ", cmd);
@@ -1740,6 +1737,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 * For SAM Task Attribute emulation for failed struct se_cmd
 */
transport_complete_task_attr(cmd);
+
/*
 * Handle special case for COMPARE_AND_WRITE failure, where the
 * callback is expected to drop the per device ->caw_sem.
@@ -1748,6 +1746,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 cmd->transport_complete_callback)
cmd->transport_complete_callback(cmd, false, _ret);
 
+   if (transport_check_aborted_status(cmd, 1))
+   return;
+
switch (sense_reason) {
case TCM_NON_EXISTENT_LUN:
case TCM_UNSUPPORTED_SCSI_OPCODE:
-- 
1.9.1



[PATCH 3/6] target: Fix quiese during transport_write_pending_qf endless loop

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a potential end-less loop during QUEUE_FULL,
where cmd->se_tfo->write_pending() callback fails repeatedly
but __transport_wait_for_tasks() has already been invoked to
quiese the outstanding se_cmd descriptor.

To address this bug, this patch adds a CMD_T_STOP|CMD_T_ABORTED
check within transport_write_pending_qf() and invokes the
existing se_cmd->t_transport_stop_comp to signal quiese
completion back to __transport_wait_for_tasks().

Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Bryant G. Ly 
Cc: Michael Cyr 
Cc: Potnuri Bharat Teja 
Cc: Sagi Grimberg 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_transport.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index d02218c..0e89db8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2560,7 +2560,20 @@ void transport_kunmap_data_sg(struct se_cmd *cmd)
 
 static void transport_write_pending_qf(struct se_cmd *cmd)
 {
+   unsigned long flags;
int ret;
+   bool stop;
+
+   spin_lock_irqsave(>t_state_lock, flags);
+   stop = (cmd->transport_state & (CMD_T_STOP | CMD_T_ABORTED));
+   spin_unlock_irqrestore(>t_state_lock, flags);
+
+   if (stop) {
+   pr_debug("%s:%d CMD_T_STOP|CMD_T_ABORTED for ITT: 0x%08llx\n",
+   __func__, __LINE__, cmd->tag);
+   complete_all(>t_transport_stop_comp);
+   return;
+   }
 
ret = cmd->se_tfo->write_pending(cmd);
if (ret) {
-- 
1.9.1



[PATCH 2/6] target: Fix caw_sem leak in transport_generic_request_failure

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

With the recent addition of transport_check_aborted_status() within
transport_generic_request_failure() to avoid sending a SCSI status
exception after CMD_T_ABORTED w/ TAS=1 has occured, it introduced
a COMPARE_AND_WRITE early failure regression.

Namely when COMPARE_AND_WRITE fails and se_device->caw_sem has
been taken by sbc_compare_and_write(), if the new check for
transport_check_aborted_status() returns true and exits,
cmd->transport_complete_callback() -> compare_and_write_post()
is skipped never releasing se_device->caw_sem.

This regression was originally introduced by:

  commit e3b88ee95b4e4bf3e9729a4695d695b9c7c296c8
  Author: Bart Van Assche 
  Date:   Tue Feb 14 16:25:45 2017 -0800

  target: Fix handling of aborted failed commands

To address this bug, move the transport_check_aborted_status()
call after transport_complete_task_attr() and
cmd->transport_complete_callback().

Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Bart Van Assche 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_transport.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index c33d1e9..d02218c 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1729,9 +1729,6 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 {
int ret = 0, post_ret = 0;
 
-   if (transport_check_aborted_status(cmd, 1))
-   return;
-
pr_debug("-[ Storage Engine Exception; sense_reason %d\n",
 sense_reason);
target_show_cmd("-[ ", cmd);
@@ -1740,6 +1737,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 * For SAM Task Attribute emulation for failed struct se_cmd
 */
transport_complete_task_attr(cmd);
+
/*
 * Handle special case for COMPARE_AND_WRITE failure, where the
 * callback is expected to drop the per device ->caw_sem.
@@ -1748,6 +1746,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 cmd->transport_complete_callback)
cmd->transport_complete_callback(cmd, false, _ret);
 
+   if (transport_check_aborted_status(cmd, 1))
+   return;
+
switch (sense_reason) {
case TCM_NON_EXISTENT_LUN:
case TCM_UNSUPPORTED_SCSI_OPCODE:
-- 
1.9.1



[PATCH 5/6] iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref

2017-11-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Since commit 59b6986dbf fixed a potential NULL pointer dereference
by allocating a se_tmr_req for ISCSI_TM_FUNC_TASK_REASSIGN, the
se_tmr_req is currently leaked by iscsit_free_cmd() because no
iscsi_cmd->se_cmd.se_tfo was associated.

To address this, treat ISCSI_TM_FUNC_TASK_REASSIGN like any other
TMR and call transport_init_se_cmd() + target_get_sess_cmd() to
setup iscsi_cmd->se_cmd.se_tfo with se_cmd->cmd_kref of 2.

This will ensure normal release operation once se_cmd->cmd_kref
reaches zero and target_release_cmd_kref() is invoked, se_tmr_req
will be released via existing target_free_cmd_mem() and
core_tmr_release_req() code.

Reported-by: Donald White 
Cc: Donald White 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 541f66a..048d422 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1955,7 +1955,6 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
struct iscsi_tmr_req *tmr_req;
struct iscsi_tm *hdr;
int out_of_order_cmdsn = 0, ret;
-   bool sess_ref = false;
u8 function, tcm_function = TMR_UNKNOWN;
 
hdr = (struct iscsi_tm *) buf;
@@ -1988,22 +1987,23 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 
cmd->data_direction = DMA_NONE;
cmd->tmr_req = kzalloc(sizeof(*cmd->tmr_req), GFP_KERNEL);
-   if (!cmd->tmr_req)
+   if (!cmd->tmr_req) {
return iscsit_add_reject_cmd(cmd,
 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
 buf);
+   }
+
+   transport_init_se_cmd(>se_cmd, _ops,
+ conn->sess->se_sess, 0, DMA_NONE,
+ TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
+
+   target_get_sess_cmd(>se_cmd, true);
 
/*
 * TASK_REASSIGN for ERL=2 / connection stays inside of
 * LIO-Target $FABRIC_MOD
 */
if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
-   transport_init_se_cmd(>se_cmd, _ops,
- conn->sess->se_sess, 0, DMA_NONE,
- TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
-
-   target_get_sess_cmd(>se_cmd, true);
-   sess_ref = true;
tcm_function = iscsit_convert_tmf(function);
if (tcm_function == TMR_UNKNOWN) {
pr_err("Unknown iSCSI TMR Function:"
@@ -2119,12 +2119,8 @@ static enum tcm_tmreq_table iscsit_convert_tmf(u8 
iscsi_tmf)
 * For connection recovery, this is also the default action for
 * TMR TASK_REASSIGN.
 */
-   if (sess_ref) {
-   pr_debug("Handle TMR, using sess_ref=true check\n");
-   target_put_sess_cmd(>se_cmd);
-   }
-
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
+   target_put_sess_cmd(>se_cmd);
return 0;
 }
 EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
-- 
1.9.1



[GIT PULL] target fixes for v4.13-rc5

2017-08-12 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending fixes for v4.13-rc5.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master

The highlights include:

- Fix iscsi-target payload memory leak during ISCSI_FLAG_TEXT_CONTINUE
  (Varun Prakash)
- Fix tcm_qla2xxx incorrect use of tcm_qla2xxx_free_cmd during ABORT
  (Pascal de Bruijn + Himanshu Madhani + nab)
- Fix iscsi-target long-standing issue with parallel delete of a single
  network portal across multiple target instances (Gary Guo + nab)
- Fix target dynamic se_node GPF during uncached shutdown regression
  (Justin Maggard + nab)

Thank you,

--nab

Bryant G. Ly (1):
  tcmu: free old string on reconfig

Nicholas Bellinger (3):
  qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)
  iscsi-target: Fix iscsi_np reset hung task during parallel delete
  target: Fix node_acl demo-mode + uncached dynamic shutdown regression

Varun Prakash (4):
  cxgbit: add missing __kfree_skb()
  iscsi-target: fix memory leak in iscsit_setup_text_cmd()
  iscsi-target: fix invalid flags in text response
  cxgbit: fix sg_nents calculation

Xiubo Li (1):
  tcmu: Fix possible to/from address overflow when doing the memcpy

 drivers/scsi/qla2xxx/tcm_qla2xxx.c  | 30 -
 drivers/target/iscsi/cxgbit/cxgbit_cm.c | 16 +++
 drivers/target/iscsi/cxgbit/cxgbit_target.c | 12 +++-
 drivers/target/iscsi/iscsi_target.c |  6 --
 drivers/target/iscsi/iscsi_target_login.c   |  7 +--
 drivers/target/target_core_tpg.c|  4 ++--
 drivers/target/target_core_transport.c  |  4 ++--
 drivers/target/target_core_user.c   | 13 +++--
 include/target/iscsi/iscsi_target_core.h|  1 +
 9 files changed, 40 insertions(+), 53 deletions(-)



[GIT PULL] target fixes for v4.13-rc5

2017-08-12 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending fixes for v4.13-rc5.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master

The highlights include:

- Fix iscsi-target payload memory leak during ISCSI_FLAG_TEXT_CONTINUE
  (Varun Prakash)
- Fix tcm_qla2xxx incorrect use of tcm_qla2xxx_free_cmd during ABORT
  (Pascal de Bruijn + Himanshu Madhani + nab)
- Fix iscsi-target long-standing issue with parallel delete of a single
  network portal across multiple target instances (Gary Guo + nab)
- Fix target dynamic se_node GPF during uncached shutdown regression
  (Justin Maggard + nab)

Thank you,

--nab

Bryant G. Ly (1):
  tcmu: free old string on reconfig

Nicholas Bellinger (3):
  qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)
  iscsi-target: Fix iscsi_np reset hung task during parallel delete
  target: Fix node_acl demo-mode + uncached dynamic shutdown regression

Varun Prakash (4):
  cxgbit: add missing __kfree_skb()
  iscsi-target: fix memory leak in iscsit_setup_text_cmd()
  iscsi-target: fix invalid flags in text response
  cxgbit: fix sg_nents calculation

Xiubo Li (1):
  tcmu: Fix possible to/from address overflow when doing the memcpy

 drivers/scsi/qla2xxx/tcm_qla2xxx.c  | 30 -
 drivers/target/iscsi/cxgbit/cxgbit_cm.c | 16 +++
 drivers/target/iscsi/cxgbit/cxgbit_target.c | 12 +++-
 drivers/target/iscsi/iscsi_target.c |  6 --
 drivers/target/iscsi/iscsi_target_login.c   |  7 +--
 drivers/target/target_core_tpg.c|  4 ++--
 drivers/target/target_core_transport.c  |  4 ++--
 drivers/target/target_core_user.c   | 13 +++--
 include/target/iscsi/iscsi_target_core.h|  1 +
 9 files changed, 40 insertions(+), 53 deletions(-)



[PATCH] iscsi-target: Fix iscsi_np reset hung task during parallel delete

2017-08-06 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a bug associated with iscsit_reset_np_thread()
that can occur during parallel configfs rmdir of a single iscsi_np
used across multiple iscsi-target instances, that would result in
hung task(s) similar to below where configfs rmdir process context
was blocked indefinately waiting for iscsi_np->np_restart_comp
to finish:

[ 6726.112076] INFO: task dcp_proxy_node_:15550 blocked for more than 120 
seconds.
[ 6726.119440]   Tainted: GW  O 4.1.26-3321 #2
[ 6726.125045] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
[ 6726.132927] dcp_proxy_node_ D 8803f202bc88 0 15550  1 0x
[ 6726.140058]  8803f202bc88 88085c64d960 88083b3b1ad0 
88087fffeb08
[ 6726.147593]  8803f202c000 7fff 88083f459c28 
88083b3b1ad0
[ 6726.155132]  88035373c100 8803f202bca8 8168ced2 
8803f202bcb8
[ 6726.162667] Call Trace:
[ 6726.165150]  [] schedule+0x32/0x80
[ 6726.170156]  [] schedule_timeout+0x214/0x290
[ 6726.176030]  [] ? __send_signal+0x52/0x4a0
[ 6726.181728]  [] wait_for_completion+0x96/0x100
[ 6726.187774]  [] ? wake_up_state+0x10/0x10
[ 6726.193395]  [] iscsit_reset_np_thread+0x62/0xe0 
[iscsi_target_mod]
[ 6726.201278]  [] iscsit_tpg_disable_portal_group+0x96/0x190 
[iscsi_target_mod]
[ 6726.210033]  [] lio_target_tpg_store_enable+0x4f/0xc0 
[iscsi_target_mod]
[ 6726.218351]  [] configfs_write_file+0xaa/0x110
[ 6726.224392]  [] vfs_write+0xa4/0x1b0
[ 6726.229576]  [] SyS_write+0x41/0xb0
[ 6726.234659]  [] system_call_fastpath+0x12/0x71

It would happen because each iscsit_reset_np_thread() sets state
to ISCSI_NP_THREAD_RESET, sends SIGINT, and then blocks waiting
for completion on iscsi_np->np_restart_comp.

However, if iscsi_np was active processing a login request and
more than a single iscsit_reset_np_thread() caller to the same
iscsi_np was blocked on iscsi_np->np_restart_comp, iscsi_np
kthread process context in __iscsi_target_login_thread() would
flush pending signals and only perform a single completion of
np->np_restart_comp before going back to sleep within transport
specific iscsit_transport->iscsi_accept_np code.

To address this bug, add a iscsi_np->np_reset_count and update
__iscsi_target_login_thread() to keep completing np->np_restart_comp
until ->np_reset_count has reached zero.

Reported-by: Gary Guo <g...@datera.io>
Tested-by: Gary Guo <g...@datera.io>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.de>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target.c   | 1 +
 drivers/target/iscsi/iscsi_target_login.c | 7 +--
 include/target/iscsi/iscsi_target_core.h  | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 12803de..5001261 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
return 0;
}
np->np_thread_state = ISCSI_NP_THREAD_RESET;
+   atomic_inc(>np_reset_count);
 
if (np->np_thread) {
spin_unlock_bh(>np_thread_lock);
diff --git a/drivers/target/iscsi/iscsi_target_login.c 
b/drivers/target/iscsi/iscsi_target_login.c
index e9bdc8b..dc13afb 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np 
*np)
flush_signals(current);
 
spin_lock_bh(>np_thread_lock);
-   if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+   if (atomic_dec_if_positive(>np_reset_count) >= 0) {
np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
+   spin_unlock_bh(>np_thread_lock);
complete(>np_restart_comp);
+   return 1;
} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
spin_unlock_bh(>np_thread_lock);
goto exit;
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np 
*np)
goto exit;
} else if (rc < 0) {
spin_lock_bh(>np_thread_lock);
-   if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+   if (atomic_dec_if_positive(>np_reset_count) >= 0) {
+   np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
spin_unlock_bh(>np_thread_lock);
complete(>np_restart_comp);
iscsit_put_transport(conn->conn_transport);
diff --git a/include/target/iscsi/iscsi_target_core.h 
b/include/target/iscsi/iscsi_target_core.h
index 0ca1fb0..fb87d32 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ 

[PATCH] iscsi-target: Fix iscsi_np reset hung task during parallel delete

2017-08-06 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a bug associated with iscsit_reset_np_thread()
that can occur during parallel configfs rmdir of a single iscsi_np
used across multiple iscsi-target instances, that would result in
hung task(s) similar to below where configfs rmdir process context
was blocked indefinately waiting for iscsi_np->np_restart_comp
to finish:

[ 6726.112076] INFO: task dcp_proxy_node_:15550 blocked for more than 120 
seconds.
[ 6726.119440]   Tainted: GW  O 4.1.26-3321 #2
[ 6726.125045] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this 
message.
[ 6726.132927] dcp_proxy_node_ D 8803f202bc88 0 15550  1 0x
[ 6726.140058]  8803f202bc88 88085c64d960 88083b3b1ad0 
88087fffeb08
[ 6726.147593]  8803f202c000 7fff 88083f459c28 
88083b3b1ad0
[ 6726.155132]  88035373c100 8803f202bca8 8168ced2 
8803f202bcb8
[ 6726.162667] Call Trace:
[ 6726.165150]  [] schedule+0x32/0x80
[ 6726.170156]  [] schedule_timeout+0x214/0x290
[ 6726.176030]  [] ? __send_signal+0x52/0x4a0
[ 6726.181728]  [] wait_for_completion+0x96/0x100
[ 6726.187774]  [] ? wake_up_state+0x10/0x10
[ 6726.193395]  [] iscsit_reset_np_thread+0x62/0xe0 
[iscsi_target_mod]
[ 6726.201278]  [] iscsit_tpg_disable_portal_group+0x96/0x190 
[iscsi_target_mod]
[ 6726.210033]  [] lio_target_tpg_store_enable+0x4f/0xc0 
[iscsi_target_mod]
[ 6726.218351]  [] configfs_write_file+0xaa/0x110
[ 6726.224392]  [] vfs_write+0xa4/0x1b0
[ 6726.229576]  [] SyS_write+0x41/0xb0
[ 6726.234659]  [] system_call_fastpath+0x12/0x71

It would happen because each iscsit_reset_np_thread() sets state
to ISCSI_NP_THREAD_RESET, sends SIGINT, and then blocks waiting
for completion on iscsi_np->np_restart_comp.

However, if iscsi_np was active processing a login request and
more than a single iscsit_reset_np_thread() caller to the same
iscsi_np was blocked on iscsi_np->np_restart_comp, iscsi_np
kthread process context in __iscsi_target_login_thread() would
flush pending signals and only perform a single completion of
np->np_restart_comp before going back to sleep within transport
specific iscsit_transport->iscsi_accept_np code.

To address this bug, add a iscsi_np->np_reset_count and update
__iscsi_target_login_thread() to keep completing np->np_restart_comp
until ->np_reset_count has reached zero.

Reported-by: Gary Guo 
Tested-by: Gary Guo 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target.c   | 1 +
 drivers/target/iscsi/iscsi_target_login.c | 7 +--
 include/target/iscsi/iscsi_target_core.h  | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 12803de..5001261 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
return 0;
}
np->np_thread_state = ISCSI_NP_THREAD_RESET;
+   atomic_inc(>np_reset_count);
 
if (np->np_thread) {
spin_unlock_bh(>np_thread_lock);
diff --git a/drivers/target/iscsi/iscsi_target_login.c 
b/drivers/target/iscsi/iscsi_target_login.c
index e9bdc8b..dc13afb 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np 
*np)
flush_signals(current);
 
spin_lock_bh(>np_thread_lock);
-   if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+   if (atomic_dec_if_positive(>np_reset_count) >= 0) {
np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
+   spin_unlock_bh(>np_thread_lock);
complete(>np_restart_comp);
+   return 1;
} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
spin_unlock_bh(>np_thread_lock);
goto exit;
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np 
*np)
goto exit;
} else if (rc < 0) {
spin_lock_bh(>np_thread_lock);
-   if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+   if (atomic_dec_if_positive(>np_reset_count) >= 0) {
+   np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
spin_unlock_bh(>np_thread_lock);
complete(>np_restart_comp);
iscsit_put_transport(conn->conn_transport);
diff --git a/include/target/iscsi/iscsi_target_core.h 
b/include/target/iscsi/iscsi_target_core.h
index 0ca1fb0..fb87d32 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -786,6 +786,7 @@ struct iscsi_np {
int np_sock_type;
  

[PATCH] qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)

2017-07-30 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch drops two incorrect usages of tcm_qla2xxx_free_cmd()
during TMR ABORT within tcm_qla2xxx_handle_data_work() and
tcm_qla2xxx_aborted_task(), which where attempting to dispatch
into workqueue context to do tcm_qla2xxx_complete_free() and
subsequently invoke transport_generic_free_cmd().

This is incorrect because during TMR ABORT target-core will
drop the outstanding se_cmd->cmd_kref references once it has
quiesced the se_cmd via transport_wait_for_tasks(), and in
the case of qla2xxx it should not attempt to do it's own
transport_generic_free_cmd() once the abort has occured.

As reported by Pascal, this was originally manifesting as a
BUG_ON(cmd->cmd_in_wq) in qlt_free_cmd() during TMR ABORT,
with a LIO backend that had sufficently high enough WRITE
latency to trigger a host side TMR ABORT_TASK.

(v2: Drop the qla_tgt_cmd->write_pending_abort_comp changes,
 as they will be addressed in a seperate series)

Reported-by: Pascal de Bruijn <p.debru...@unilogic.nl>
Tested-by: Pascal de Bruijn <p.debru...@unilogic.nl>
Cc: Pascal de Bruijn <p.debru...@unilogic.nl>
Reported-by: Lukasz Engel <lukasz.en...@softax.pl>
Cc: Lukasz Engel <lukasz.en...@softax.pl>
Acked-by: Himanshu Madhani <himanshu.madh...@cavium.com>
Cc: Quinn Tran <quinn.t...@cavium.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 30 --
 1 file changed, 30 deletions(-)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index b20da0d..3f82ea1 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, 
struct qla_tgt_cmd *cmd,
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
-   unsigned long flags;
 
/*
 * Ensure that the complete FCP WRITE payload has been received.
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct 
work_struct *work)
 */
cmd->cmd_in_wq = 0;
 
-   spin_lock_irqsave(>cmd_lock, flags);
-   cmd->data_work = 1;
-   if (cmd->aborted) {
-   cmd->data_work_free = 1;
-   spin_unlock_irqrestore(>cmd_lock, flags);
-
-   tcm_qla2xxx_free_cmd(cmd);
-   return;
-   }
-   spin_unlock_irqrestore(>cmd_lock, flags);
-
cmd->qpair->tgt_counters.qla_core_ret_ctio++;
if (!cmd->write_data_transferred) {
/*
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd 
*se_cmd)
qlt_xmit_tm_rsp(mcmd);
 }
 
-#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
struct qla_tgt_cmd *cmd = container_of(se_cmd,
struct qla_tgt_cmd, se_cmd);
-   unsigned long flags;
 
if (qlt_abort_cmd(cmd))
return;
-
-   spin_lock_irqsave(>cmd_lock, flags);
-   if ((cmd->state == QLA_TGT_STATE_NEW)||
-   ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
-   DATA_WORK_NOT_FREE(cmd))) {
-   cmd->data_work_free = 1;
-   spin_unlock_irqrestore(>cmd_lock, flags);
-   /*
-* cmd has not reached fw, Use this trigger to free it.
-*/
-   tcm_qla2xxx_free_cmd(cmd);
-   return;
-   }
-   spin_unlock_irqrestore(>cmd_lock, flags);
-   return;
-
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
-- 
1.9.1



[PATCH] qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)

2017-07-30 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch drops two incorrect usages of tcm_qla2xxx_free_cmd()
during TMR ABORT within tcm_qla2xxx_handle_data_work() and
tcm_qla2xxx_aborted_task(), which where attempting to dispatch
into workqueue context to do tcm_qla2xxx_complete_free() and
subsequently invoke transport_generic_free_cmd().

This is incorrect because during TMR ABORT target-core will
drop the outstanding se_cmd->cmd_kref references once it has
quiesced the se_cmd via transport_wait_for_tasks(), and in
the case of qla2xxx it should not attempt to do it's own
transport_generic_free_cmd() once the abort has occured.

As reported by Pascal, this was originally manifesting as a
BUG_ON(cmd->cmd_in_wq) in qlt_free_cmd() during TMR ABORT,
with a LIO backend that had sufficently high enough WRITE
latency to trigger a host side TMR ABORT_TASK.

(v2: Drop the qla_tgt_cmd->write_pending_abort_comp changes,
 as they will be addressed in a seperate series)

Reported-by: Pascal de Bruijn 
Tested-by: Pascal de Bruijn 
Cc: Pascal de Bruijn 
Reported-by: Lukasz Engel 
Cc: Lukasz Engel 
Acked-by: Himanshu Madhani 
Cc: Quinn Tran 
Signed-off-by: Nicholas Bellinger 
---
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 30 --
 1 file changed, 30 deletions(-)

diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index b20da0d..3f82ea1 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, 
struct qla_tgt_cmd *cmd,
 static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
 {
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
-   unsigned long flags;
 
/*
 * Ensure that the complete FCP WRITE payload has been received.
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct 
work_struct *work)
 */
cmd->cmd_in_wq = 0;
 
-   spin_lock_irqsave(>cmd_lock, flags);
-   cmd->data_work = 1;
-   if (cmd->aborted) {
-   cmd->data_work_free = 1;
-   spin_unlock_irqrestore(>cmd_lock, flags);
-
-   tcm_qla2xxx_free_cmd(cmd);
-   return;
-   }
-   spin_unlock_irqrestore(>cmd_lock, flags);
-
cmd->qpair->tgt_counters.qla_core_ret_ctio++;
if (!cmd->write_data_transferred) {
/*
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd 
*se_cmd)
qlt_xmit_tm_rsp(mcmd);
 }
 
-#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
 static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
 {
struct qla_tgt_cmd *cmd = container_of(se_cmd,
struct qla_tgt_cmd, se_cmd);
-   unsigned long flags;
 
if (qlt_abort_cmd(cmd))
return;
-
-   spin_lock_irqsave(>cmd_lock, flags);
-   if ((cmd->state == QLA_TGT_STATE_NEW)||
-   ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
-   DATA_WORK_NOT_FREE(cmd))) {
-   cmd->data_work_free = 1;
-   spin_unlock_irqrestore(>cmd_lock, flags);
-   /*
-* cmd has not reached fw, Use this trigger to free it.
-*/
-   tcm_qla2xxx_free_cmd(cmd);
-   return;
-   }
-   spin_unlock_irqrestore(>cmd_lock, flags);
-   return;
-
 }
 
 static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
-- 
1.9.1



[GIT PULL] target updates for v4.13-rc1

2017-07-13 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending updates for v4.13-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

Note there is a qla2xxx conflict with scsi.git as reported by SFR, which
should be straight-forward to resolve:

https://lkml.org/lkml/2017/6/28/45

Note there was two additional qla2xxx conflicts with scsi.git:

https://lkml.org/lkml/2017/7/3/22
https://lkml.org/lkml/2017/7/3/23

However, the patch that caused these has since been reverted:

  55dd8cf Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR 
ABORT"

as it caused other problems, so these conflicts can be ignored.

Attached is v4.13-rc1-resolution.diff if there are any questions wrt to
how the resolution should look.  Adding Himanshu + Quinn CC'.

That said, it's been usually busy for summer, with most of the efforts
centered around TCMU developments and various target-core + fabric
driver bug fixing activities.  Not particularly large in terms of LoC,
but lots of smaller patches from many different folks.

The highlights include:

- ibmvscsis logical partition manager support (Michael Cyr + Bryant Ly)
- Convert target/iblock WRITE_SAME to blkdev_issue_zeroout (hch + nab)
- Add support for TMR percpu LUN reference counting (nab)
- Fix a potential deadlock between EXTENDED_COPY and iscsi shutdown (Bart)
- Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce (Jiang Yi)
- Fix TMCU module removal (Xiubo Li)
- Fix iser-target OOPs during login failure (Andrea Righi + Sagi)
- Breakup target-core free_device backend driver callback (mnc)
- Perform TCMU add/delete/reconfig synchronously (mnc)
- Fix TCMU  multiple UIO open/close sequences (mnc)
- Fix TCMU CHECK_CONDITION sense handling (mnc)
- Fix target-core SAM_STAT_BUSY + TASK_SET_FULL handling (mnc + nab)
- Introduce TYPE_ZBC support in PSCSI (Damien Le Moal)
- Fix possible TCMU memory leak + OOPs when recalculating cmd base size
  (Xiubo Li + Bryant Ly + Damien Le Moal + mnc)
- Add login_keys_workaround attribute for non RFC initiators
  (Robert LeBlanc + Arun Easi + nab)

Thank you,

--nab

Bart Van Assche (17):
  target: Use symbolic value for WRITE_VERIFY_16
  target: Remove se_device.dev_list
  target: Fix transport_init_se_cmd()
  target: Use {get,put}_unaligned_be*() instead of open coding these
functions
  target: Fix a deadlock between the XCOPY code and iSCSI session
shutdown
  IB/srpt: Make a debug statement in srpt_abort_cmd() more informative
  xen/scsiback: Fix a TMR related use-after-free
  xen/scsiback: Replace a waitqueue and a counter by a completion
  xen/scsiback: Make TMF processing slightly faster
  target: Introduce a function that shows the command state
  target/tcm_loop: Merge struct tcm_loop_cmd and struct tcm_loop_tmr
  target/tcm_loop: Replace a waitqueue and a counter by a completion
  target/tcm_loop: Use target_submit_tmr() instead of open-coding this
function
  target/tcm_loop: Make TMF processing slightly faster
  target/iscsi: Remove second argument of __iscsit_free_cmd()
  target/iscsi: Simplify iscsit_free_cmd()
  target/iscsi: Remove dead code from iscsit_process_scsi_cmd()

Bryant G. Ly (7):
  ibmvscsis: Use tpgt passed in by user
  tcmu: Support emulate_write_cache
  tcmu: Add netlink for device reconfiguration
  tcmu: Make dev_size configurable via userspace
  tcmu: Make dev_config configurable
  tcmu: Add Type of reconfig into netlink
  tcmu: Fix dev_config_store

Byungchul Park (1):
  vhost/scsi: Don't reinvent the wheel but use existing llist API

Colin Ian King (2):
  tcmu: make array tcmu_attrib_attrs static const
  target: make device_mutex and device_list static

Damien Le Moal (2):
  target: Use macro for WRITE_VERIFY_32 operation codes
  target: pscsi: Introduce TYPE_ZBC support

Gustavo A. R. Silva (1):
  target: remove dead code

Jiang Yi (2):
  target: reject COMPARE_AND_WRITE if emulate_caw is not set
  target: Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce

Michael Cyr (1):
  ibmvscsis: Enable Logical Partition Migration Support

Mike Christie (17):
  tcmu: reconfigure netlink attr changes
  target: break up free_device callback
  target: use idr for se_device dev index
  target: add helper to find se_device by dev_index
  tcmu: perfom device add, del and reconfig synchronously
  target: add helper to iterate over devices
  xcopy: loop over devices using idr helper
  target: remove g_device_list
  tcmu: drop configured check in destroy
  tcmu: fix multiple uio open/close sequences
  target: do not require a transport_complete for
SCF_TRANSPORT_TASK_SENSE
  target: add helper to copy sense to se_cmd buffer
  tcmu: fix sense handling during completion
  pscsi: finish cmd processing from pscsi_req_done
  target: remove transport_complete
  target: fix SAM_STAT_BUSY/TASK_SET_FULL handling
  target: export lio pgr/alua support as device attr

Nicholas Bellinger (12):
  target/iblock: Convert WRITE_SAME to blkdev_iss

[GIT PULL] target updates for v4.13-rc1

2017-07-13 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending updates for v4.13-rc1.  Please go ahead and
pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git for-next

Note there is a qla2xxx conflict with scsi.git as reported by SFR, which
should be straight-forward to resolve:

https://lkml.org/lkml/2017/6/28/45

Note there was two additional qla2xxx conflicts with scsi.git:

https://lkml.org/lkml/2017/7/3/22
https://lkml.org/lkml/2017/7/3/23

However, the patch that caused these has since been reverted:

  55dd8cf Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR 
ABORT"

as it caused other problems, so these conflicts can be ignored.

Attached is v4.13-rc1-resolution.diff if there are any questions wrt to
how the resolution should look.  Adding Himanshu + Quinn CC'.

That said, it's been usually busy for summer, with most of the efforts
centered around TCMU developments and various target-core + fabric
driver bug fixing activities.  Not particularly large in terms of LoC,
but lots of smaller patches from many different folks.

The highlights include:

- ibmvscsis logical partition manager support (Michael Cyr + Bryant Ly)
- Convert target/iblock WRITE_SAME to blkdev_issue_zeroout (hch + nab)
- Add support for TMR percpu LUN reference counting (nab)
- Fix a potential deadlock between EXTENDED_COPY and iscsi shutdown (Bart)
- Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce (Jiang Yi)
- Fix TMCU module removal (Xiubo Li)
- Fix iser-target OOPs during login failure (Andrea Righi + Sagi)
- Breakup target-core free_device backend driver callback (mnc)
- Perform TCMU add/delete/reconfig synchronously (mnc)
- Fix TCMU  multiple UIO open/close sequences (mnc)
- Fix TCMU CHECK_CONDITION sense handling (mnc)
- Fix target-core SAM_STAT_BUSY + TASK_SET_FULL handling (mnc + nab)
- Introduce TYPE_ZBC support in PSCSI (Damien Le Moal)
- Fix possible TCMU memory leak + OOPs when recalculating cmd base size
  (Xiubo Li + Bryant Ly + Damien Le Moal + mnc)
- Add login_keys_workaround attribute for non RFC initiators
  (Robert LeBlanc + Arun Easi + nab)

Thank you,

--nab

Bart Van Assche (17):
  target: Use symbolic value for WRITE_VERIFY_16
  target: Remove se_device.dev_list
  target: Fix transport_init_se_cmd()
  target: Use {get,put}_unaligned_be*() instead of open coding these
functions
  target: Fix a deadlock between the XCOPY code and iSCSI session
shutdown
  IB/srpt: Make a debug statement in srpt_abort_cmd() more informative
  xen/scsiback: Fix a TMR related use-after-free
  xen/scsiback: Replace a waitqueue and a counter by a completion
  xen/scsiback: Make TMF processing slightly faster
  target: Introduce a function that shows the command state
  target/tcm_loop: Merge struct tcm_loop_cmd and struct tcm_loop_tmr
  target/tcm_loop: Replace a waitqueue and a counter by a completion
  target/tcm_loop: Use target_submit_tmr() instead of open-coding this
function
  target/tcm_loop: Make TMF processing slightly faster
  target/iscsi: Remove second argument of __iscsit_free_cmd()
  target/iscsi: Simplify iscsit_free_cmd()
  target/iscsi: Remove dead code from iscsit_process_scsi_cmd()

Bryant G. Ly (7):
  ibmvscsis: Use tpgt passed in by user
  tcmu: Support emulate_write_cache
  tcmu: Add netlink for device reconfiguration
  tcmu: Make dev_size configurable via userspace
  tcmu: Make dev_config configurable
  tcmu: Add Type of reconfig into netlink
  tcmu: Fix dev_config_store

Byungchul Park (1):
  vhost/scsi: Don't reinvent the wheel but use existing llist API

Colin Ian King (2):
  tcmu: make array tcmu_attrib_attrs static const
  target: make device_mutex and device_list static

Damien Le Moal (2):
  target: Use macro for WRITE_VERIFY_32 operation codes
  target: pscsi: Introduce TYPE_ZBC support

Gustavo A. R. Silva (1):
  target: remove dead code

Jiang Yi (2):
  target: reject COMPARE_AND_WRITE if emulate_caw is not set
  target: Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce

Michael Cyr (1):
  ibmvscsis: Enable Logical Partition Migration Support

Mike Christie (17):
  tcmu: reconfigure netlink attr changes
  target: break up free_device callback
  target: use idr for se_device dev index
  target: add helper to find se_device by dev_index
  tcmu: perfom device add, del and reconfig synchronously
  target: add helper to iterate over devices
  xcopy: loop over devices using idr helper
  target: remove g_device_list
  tcmu: drop configured check in destroy
  tcmu: fix multiple uio open/close sequences
  target: do not require a transport_complete for
SCF_TRANSPORT_TASK_SENSE
  target: add helper to copy sense to se_cmd buffer
  tcmu: fix sense handling during completion
  pscsi: finish cmd processing from pscsi_req_done
  target: remove transport_complete
  target: fix SAM_STAT_BUSY/TASK_SET_FULL handling
  target: export lio pgr/alua support as device attr

Nicholas Bellinger (12):
  target/iblock: Convert WRITE_SAME to blkdev_iss

Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-07-13 Thread Nicholas A. Bellinger
On Tue, 2017-07-11 at 16:17 +, Bart Van Assche wrote:
> On Tue, 2017-07-11 at 00:22 -0700, Nicholas A. Bellinger wrote:
> > So rejecting this case as already done in commit abb85a9b51 is the
> > correct approach for >= v4.3.y.
> 
> Hello Nic,
> 
> I hope that you agree that the current target_cmd_size_check() implementation
> is complicated and ugly. Patch 30/33 of the patch series I referred to in my
> e-mail removes a significant number of lines of code from that function. So
> my patch series not only makes target_cmd_size_check() easier to maintain and
> to verify but it makes that function also faster. Hence please reconsider the
> approach from my patch series. For patch 30/33, see also
> https://www.spinics.net/lists/target-devel/msg15384.html.

For reference, here is the patch your advocating:

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index c28e3b58150b..6cd49fe578a7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1164,23 +1164,6 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int 
size)
" %u does not match SCSI CDB Length: %u for SAM Opcode:"
" 0x%02x\n", cmd->se_tfo->get_fabric_name(),
cmd->data_length, size, cmd->t_task_cdb[0]);
-
-   if (cmd->data_direction == DMA_TO_DEVICE &&
-   cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
-   pr_err("Rejecting underflow/overflow WRITE data\n");
-   return TCM_INVALID_CDB_FIELD;
-   }
-   /*
-* Reject READ_* or WRITE_* with overflow/underflow for
-* type SCF_SCSI_DATA_CDB.
-*/
-   if (dev->dev_attrib.block_size != 512)  {
-   pr_err("Failing OVERFLOW/UNDERFLOW for LBA op"
-   " CDB on non 512-byte sector setup subsystem"
-   " plugin: %s\n", dev->transport->name);
-   /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */
-   return TCM_INVALID_CDB_FIELD;
-   }
/*
 * For the overflow case keep the existing fabric provided
 * ->data_length.  Otherwise for the underflow case, reset

The original code is not 'complicated' or 'ugly', and the proposed
change doesn't make anything 'faster' nor removes a 'significant' number
of LoC.

So no, I don't buy any of that line of reasoning.  ;-)

It comes down to two items.  First, if SCF_SCSI_DATA_CDBs with
underflow/overflow will be allowed, and second the block_size != 512
check.

For the former, I've still never seen a host environment in the wild
over the last 15 years that generates underflow/overflow for DATA CDBs
with an LBA.  So I'm reluctant to randomly allow this for all cases and
fabrics, considering no host environment actually requires it.

That said, I do understand libiscsi generates this for WRITE_VERIFY, but
I'm still undecided if that's a good enough a reason to enable it for
all cases in upstream.

For the latter item, it's fine to drop the legacy block_size != 512
check, and I'll take a patch for that separate from the other bit.



Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-07-13 Thread Nicholas A. Bellinger
On Tue, 2017-07-11 at 16:17 +, Bart Van Assche wrote:
> On Tue, 2017-07-11 at 00:22 -0700, Nicholas A. Bellinger wrote:
> > So rejecting this case as already done in commit abb85a9b51 is the
> > correct approach for >= v4.3.y.
> 
> Hello Nic,
> 
> I hope that you agree that the current target_cmd_size_check() implementation
> is complicated and ugly. Patch 30/33 of the patch series I referred to in my
> e-mail removes a significant number of lines of code from that function. So
> my patch series not only makes target_cmd_size_check() easier to maintain and
> to verify but it makes that function also faster. Hence please reconsider the
> approach from my patch series. For patch 30/33, see also
> https://www.spinics.net/lists/target-devel/msg15384.html.

For reference, here is the patch your advocating:

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index c28e3b58150b..6cd49fe578a7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1164,23 +1164,6 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int 
size)
" %u does not match SCSI CDB Length: %u for SAM Opcode:"
" 0x%02x\n", cmd->se_tfo->get_fabric_name(),
cmd->data_length, size, cmd->t_task_cdb[0]);
-
-   if (cmd->data_direction == DMA_TO_DEVICE &&
-   cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
-   pr_err("Rejecting underflow/overflow WRITE data\n");
-   return TCM_INVALID_CDB_FIELD;
-   }
-   /*
-* Reject READ_* or WRITE_* with overflow/underflow for
-* type SCF_SCSI_DATA_CDB.
-*/
-   if (dev->dev_attrib.block_size != 512)  {
-   pr_err("Failing OVERFLOW/UNDERFLOW for LBA op"
-   " CDB on non 512-byte sector setup subsystem"
-   " plugin: %s\n", dev->transport->name);
-   /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */
-   return TCM_INVALID_CDB_FIELD;
-   }
/*
 * For the overflow case keep the existing fabric provided
 * ->data_length.  Otherwise for the underflow case, reset

The original code is not 'complicated' or 'ugly', and the proposed
change doesn't make anything 'faster' nor removes a 'significant' number
of LoC.

So no, I don't buy any of that line of reasoning.  ;-)

It comes down to two items.  First, if SCF_SCSI_DATA_CDBs with
underflow/overflow will be allowed, and second the block_size != 512
check.

For the former, I've still never seen a host environment in the wild
over the last 15 years that generates underflow/overflow for DATA CDBs
with an LBA.  So I'm reluctant to randomly allow this for all cases and
fabrics, considering no host environment actually requires it.

That said, I do understand libiscsi generates this for WRITE_VERIFY, but
I'm still undecided if that's a good enough a reason to enable it for
all cases in upstream.

For the latter item, it's fine to drop the legacy block_size != 512
check, and I'll take a patch for that separate from the other bit.



Re: [PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-11 Thread Nicholas A. Bellinger
On Tue, 2017-07-11 at 23:38 +, Bart Van Assche wrote:
> On Fri, 2017-07-07 at 22:24 +0000, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger <n...@linux-iscsi.org>
> > 
> > This patch re-introduces part of a long standing login workaround that
> > was recently dropped by:
> > 
> >   commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
> >   Author: Nicholas Bellinger <n...@linux-iscsi.org>
> >   Date:   Sun Apr 2 13:36:44 2017 -0700
> > 
> >   iscsi-target: Drop work-around for legacy GlobalSAN initiator
> > 
> > Namely, the workaround for FirstBurstLength ended up being required by
> > Mellanox Flexboot PXE boot ROMs as reported by Robert.
> > 
> > So this patch re-adds the work-around for FirstBurstLength within
> > iscsi_check_proposer_for_optional_reply(), and makes the key optional
> > to respond when the initiator does not propose, nor respond to it.
> > 
> > Also as requested by Arun, this patch introduces a new TPG attribute
> > named 'login_keys_workaround' that controls the use of both the
> > FirstBurstLength workaround, as well as the two other existing
> > workarounds for gPXE iSCSI boot client.
> > 
> > By default, the workaround is enabled with login_keys_workaround=1,
> > since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
> > MSFT initiator already proposes FirstBurstLength, so it's uneffected
> > by this re-adding this part of the original work-around.
> 
> Hello Nick,
> 
> The new configfs attribute ("login_keys_workaround") may confuse users - for
> someone who has not followed this e-mail thread it can take a long time
> before they figure out that they need to set this configfs attribute.

It's enabled by default, so there is nothing a user has to explicitly
change in order all hosts to 'just work'.

The only reason the attribute was added was by request of Arun, so if
some future initiator doesn't proposed the keys controlled by the
work-around, and still attempts to respond they can at least get
something working w/o code change.

>  Have
> you considered to let the iSCSI target driver figure out whether or not that
> variable has to be set, e.g. by looking up the initiator IQN in a list?
> 

Given InitiatorName is end user configurable, trying to do a workaround
based on IQN regexs is error prone, at best.

Also, since the FirstBurstLength work-around this patch re-adds had
already been in place for the better part of 8 years, the risk of
interopt issues is almost non existent.



Re: [PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-11 Thread Nicholas A. Bellinger
On Tue, 2017-07-11 at 23:38 +, Bart Van Assche wrote:
> On Fri, 2017-07-07 at 22:24 +0000, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > This patch re-introduces part of a long standing login workaround that
> > was recently dropped by:
> > 
> >   commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
> >   Author: Nicholas Bellinger 
> >   Date:   Sun Apr 2 13:36:44 2017 -0700
> > 
> >   iscsi-target: Drop work-around for legacy GlobalSAN initiator
> > 
> > Namely, the workaround for FirstBurstLength ended up being required by
> > Mellanox Flexboot PXE boot ROMs as reported by Robert.
> > 
> > So this patch re-adds the work-around for FirstBurstLength within
> > iscsi_check_proposer_for_optional_reply(), and makes the key optional
> > to respond when the initiator does not propose, nor respond to it.
> > 
> > Also as requested by Arun, this patch introduces a new TPG attribute
> > named 'login_keys_workaround' that controls the use of both the
> > FirstBurstLength workaround, as well as the two other existing
> > workarounds for gPXE iSCSI boot client.
> > 
> > By default, the workaround is enabled with login_keys_workaround=1,
> > since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
> > MSFT initiator already proposes FirstBurstLength, so it's uneffected
> > by this re-adding this part of the original work-around.
> 
> Hello Nick,
> 
> The new configfs attribute ("login_keys_workaround") may confuse users - for
> someone who has not followed this e-mail thread it can take a long time
> before they figure out that they need to set this configfs attribute.

It's enabled by default, so there is nothing a user has to explicitly
change in order all hosts to 'just work'.

The only reason the attribute was added was by request of Arun, so if
some future initiator doesn't proposed the keys controlled by the
work-around, and still attempts to respond they can at least get
something working w/o code change.

>  Have
> you considered to let the iSCSI target driver figure out whether or not that
> variable has to be set, e.g. by looking up the initiator IQN in a list?
> 

Given InitiatorName is end user configurable, trying to do a workaround
based on IQN regexs is error prone, at best.

Also, since the FirstBurstLength work-around this patch re-adds had
already been in place for the better part of 8 years, the risk of
interopt issues is almost non existent.



Re: [PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-11 Thread Nicholas A. Bellinger
Hey Robert,

Any chance to test this with your Flexboot PXE setup..?

Please give this a spin ASAP to verify it addresses the regression you
reported earlier, wrt FirstBurstLength not being proposed nor responded
to using Flexboot PXE.

Thank you.

On Fri, 2017-07-07 at 22:24 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <n...@linux-iscsi.org>
> 
> This patch re-introduces part of a long standing login workaround that
> was recently dropped by:
> 
>   commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
>   Author: Nicholas Bellinger <n...@linux-iscsi.org>
>   Date:   Sun Apr 2 13:36:44 2017 -0700
> 
>   iscsi-target: Drop work-around for legacy GlobalSAN initiator
> 
> Namely, the workaround for FirstBurstLength ended up being required by
> Mellanox Flexboot PXE boot ROMs as reported by Robert.
> 
> So this patch re-adds the work-around for FirstBurstLength within
> iscsi_check_proposer_for_optional_reply(), and makes the key optional
> to respond when the initiator does not propose, nor respond to it.
> 
> Also as requested by Arun, this patch introduces a new TPG attribute
> named 'login_keys_workaround' that controls the use of both the
> FirstBurstLength workaround, as well as the two other existing
> workarounds for gPXE iSCSI boot client.
> 
> By default, the workaround is enabled with login_keys_workaround=1,
> since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
> MSFT initiator already proposes FirstBurstLength, so it's uneffected
> by this re-adding this part of the original work-around.
> 
> Reported-by: Robert LeBlanc <rob...@leblancnet.us>
> Cc: Robert LeBlanc <rob...@leblancnet.us>
> Cc: Arun Easi <arun.e...@cavium.com>
> Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
> ---
>  drivers/target/iscsi/iscsi_target_configfs.c   |  2 ++
>  drivers/target/iscsi/iscsi_target_nego.c   |  6 ++--
>  drivers/target/iscsi/iscsi_target_parameters.c | 41 
> ++
>  drivers/target/iscsi/iscsi_target_parameters.h |  2 +-
>  drivers/target/iscsi/iscsi_target_tpg.c| 19 
>  drivers/target/iscsi/iscsi_target_tpg.h|  1 +
>  include/target/iscsi/iscsi_target_core.h   |  9 ++
>  7 files changed, 64 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
> b/drivers/target/iscsi/iscsi_target_configfs.c
> index 535a8e0..0dd4c45 100644
> --- a/drivers/target/iscsi/iscsi_target_configfs.c
> +++ b/drivers/target/iscsi/iscsi_target_configfs.c
> @@ -781,6 +781,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
> *se_nacl,
>  DEF_TPG_ATTRIB(t10_pi);
>  DEF_TPG_ATTRIB(fabric_prot_type);
>  DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
> +DEF_TPG_ATTRIB(login_keys_workaround);
>  
>  static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
>   _tpg_attrib_attr_authentication,
> @@ -796,6 +797,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
> *se_nacl,
>   _tpg_attrib_attr_t10_pi,
>   _tpg_attrib_attr_fabric_prot_type,
>   _tpg_attrib_attr_tpg_enabled_sendtargets,
> + _tpg_attrib_attr_login_keys_workaround,
>   NULL,
>  };
>  
> diff --git a/drivers/target/iscsi/iscsi_target_nego.c 
> b/drivers/target/iscsi/iscsi_target_nego.c
> index 96df63f..7a6751f 100644
> --- a/drivers/target/iscsi/iscsi_target_nego.c
> +++ b/drivers/target/iscsi/iscsi_target_nego.c
> @@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero(
>   SENDER_TARGET,
>   login->rsp_buf,
>   >rsp_length,
> - conn->param_list);
> + conn->param_list,
> + conn->tpg->tpg_attrib.login_keys_workaround);
>   if (ret < 0)
>   return -1;
>  
> @@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn 
> *conn, struct iscsi_log
>   SENDER_TARGET,
>   login->rsp_buf,
>   >rsp_length,
> - conn->param_list);
> + conn->param_list,
> + conn->tpg->tpg_attrib.login_keys_workaround);
>   if (ret < 0) {
>   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
>   ISCSI_LOGIN_STATUS_INIT_ERR);
> diff --git a/drivers/target/iscsi/iscsi_target_parameters.c 
> b/drivers/target/iscsi/iscsi_target_parameters.c
> index fce6276..caab104 100644
> --- a/drivers/target/iscsi/iscsi_target_parameters.c
> +++ b/drivers/target/iscsi/iscsi_target_parameters.c
> @@ -765,7 +765,8 @@ static int iscsi_check_for_aut

Re: [PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-11 Thread Nicholas A. Bellinger
Hey Robert,

Any chance to test this with your Flexboot PXE setup..?

Please give this a spin ASAP to verify it addresses the regression you
reported earlier, wrt FirstBurstLength not being proposed nor responded
to using Flexboot PXE.

Thank you.

On Fri, 2017-07-07 at 22:24 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger 
> 
> This patch re-introduces part of a long standing login workaround that
> was recently dropped by:
> 
>   commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
>   Author: Nicholas Bellinger 
>   Date:   Sun Apr 2 13:36:44 2017 -0700
> 
>   iscsi-target: Drop work-around for legacy GlobalSAN initiator
> 
> Namely, the workaround for FirstBurstLength ended up being required by
> Mellanox Flexboot PXE boot ROMs as reported by Robert.
> 
> So this patch re-adds the work-around for FirstBurstLength within
> iscsi_check_proposer_for_optional_reply(), and makes the key optional
> to respond when the initiator does not propose, nor respond to it.
> 
> Also as requested by Arun, this patch introduces a new TPG attribute
> named 'login_keys_workaround' that controls the use of both the
> FirstBurstLength workaround, as well as the two other existing
> workarounds for gPXE iSCSI boot client.
> 
> By default, the workaround is enabled with login_keys_workaround=1,
> since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
> MSFT initiator already proposes FirstBurstLength, so it's uneffected
> by this re-adding this part of the original work-around.
> 
> Reported-by: Robert LeBlanc 
> Cc: Robert LeBlanc 
> Cc: Arun Easi 
> Signed-off-by: Nicholas Bellinger 
> ---
>  drivers/target/iscsi/iscsi_target_configfs.c   |  2 ++
>  drivers/target/iscsi/iscsi_target_nego.c   |  6 ++--
>  drivers/target/iscsi/iscsi_target_parameters.c | 41 
> ++
>  drivers/target/iscsi/iscsi_target_parameters.h |  2 +-
>  drivers/target/iscsi/iscsi_target_tpg.c| 19 
>  drivers/target/iscsi/iscsi_target_tpg.h|  1 +
>  include/target/iscsi/iscsi_target_core.h   |  9 ++
>  7 files changed, 64 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
> b/drivers/target/iscsi/iscsi_target_configfs.c
> index 535a8e0..0dd4c45 100644
> --- a/drivers/target/iscsi/iscsi_target_configfs.c
> +++ b/drivers/target/iscsi/iscsi_target_configfs.c
> @@ -781,6 +781,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
> *se_nacl,
>  DEF_TPG_ATTRIB(t10_pi);
>  DEF_TPG_ATTRIB(fabric_prot_type);
>  DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
> +DEF_TPG_ATTRIB(login_keys_workaround);
>  
>  static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
>   _tpg_attrib_attr_authentication,
> @@ -796,6 +797,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
> *se_nacl,
>   _tpg_attrib_attr_t10_pi,
>   _tpg_attrib_attr_fabric_prot_type,
>   _tpg_attrib_attr_tpg_enabled_sendtargets,
> + _tpg_attrib_attr_login_keys_workaround,
>   NULL,
>  };
>  
> diff --git a/drivers/target/iscsi/iscsi_target_nego.c 
> b/drivers/target/iscsi/iscsi_target_nego.c
> index 96df63f..7a6751f 100644
> --- a/drivers/target/iscsi/iscsi_target_nego.c
> +++ b/drivers/target/iscsi/iscsi_target_nego.c
> @@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero(
>   SENDER_TARGET,
>   login->rsp_buf,
>   >rsp_length,
> - conn->param_list);
> + conn->param_list,
> + conn->tpg->tpg_attrib.login_keys_workaround);
>   if (ret < 0)
>   return -1;
>  
> @@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn 
> *conn, struct iscsi_log
>   SENDER_TARGET,
>   login->rsp_buf,
>   >rsp_length,
> - conn->param_list);
> + conn->param_list,
> + conn->tpg->tpg_attrib.login_keys_workaround);
>   if (ret < 0) {
>   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
>   ISCSI_LOGIN_STATUS_INIT_ERR);
> diff --git a/drivers/target/iscsi/iscsi_target_parameters.c 
> b/drivers/target/iscsi/iscsi_target_parameters.c
> index fce6276..caab104 100644
> --- a/drivers/target/iscsi/iscsi_target_parameters.c
> +++ b/drivers/target/iscsi/iscsi_target_parameters.c
> @@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char *key)
>   return 0;
>  }
>  
> -static void iscsi_check_proposer_for_optional_reply(struct iscsi_param 
> *param)
> +static void i

Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-07-11 Thread Nicholas A. Bellinger
Hi Bart,

On Thu, 2017-06-08 at 23:55 -0700, Nicholas A. Bellinger wrote:
> On Thu, 2017-06-08 at 15:37 +, Bart Van Assche wrote:
> > On Thu, 2017-06-08 at 04:21 +, Nicholas A. Bellinger wrote:
> > > + /*
> > > +  * Check for underflow case where both EDTL and immediate data payload
> > > +  * exceeds what is presented by CDB's TRANSFER LENGTH, and what has
> > > +  * already been set in target_cmd_size_check() as se_cmd->data_length.
> > > +  *
> > > +  * For this special case, fail the command and dump the immediate data
> > > +  * payload.
> > > +  */
> > > + if (cmd->first_burst_len > cmd->se_cmd.data_length) {
> > > + cmd->sense_reason = TCM_INVALID_CDB_FIELD;
> > > + goto after_immediate_data;
> > > + }
> > 
> > A quote from the iSCSI RFC (https://tools.ietf.org/html/rfc5048):
> > 
> >If SPDTL < EDTL for a task, iSCSI Underflow MUST be signaled in the
> >SCSI Response PDU as specified in [RFC3720].  The Residual Count MUST
> >be set to the numerical value of (EDTL - SPDTL).
> > 
> > Sorry but I don't think that sending TCM_INVALID_CDB_FIELD back to the
> > initiator is compliant with the iSCSI RFC.
> 
> Alas, the nuance of what this patch actually does was missed when you
> cut the context.
> 
> First, a bit of history.  LIO has rejected underflow for all WRITEs for
> the first ~12.5 years of RFC-3720, and in the context of iscsi-target
> mode there has never been a single host environment that ever once
> cared.
> 
> Since Roland's patch to allow underflow for control CDBs in v4.3+ opened
> this discussion for control CDBs with a WRITE payload in order to make
> MSFT/FCP cert for PERSISTENT_RESERVE_OUT happy, the question has become
> what control CDB WRITE underflow cases should we allow..?
> 
> The point with this patch is when a host is sending a underflow with a
> iscsi immediate data payload that exceeds SCSI transfer length, it's a
> bogus request with a garbage payload.  It's a garbage payload because
> the SCSI CDB itself obviously doesn't want anything to do it.
> 
> I'm very dubious of any host environment who's trying to do this for any
> CDB, and expects achieve expected results.
> 
> Of course, since v4.3+ normal overflow where SCSI transfer length
> matches the iscsi immediate data payload just works with or without this
> patch.
> 
> So to that extent, I'm going to push this patch as a defensive fix for
> v4.3+, to let those imaginary iscsi host environments know they being
> very, very naughty.
> 
> >  Please note that a fix that is
> > compliant with the iSCSI RFC is present in the following patch series: 
> > [PATCH
> > 00/33] SCSI target driver patches for kernel v4.13, 23 May 2017
> > (https://www.spinics.net/lists/target-devel/msg15370.html).
> 
> So I might still consider this as a v4.13-rc item for control CDB
> underflow, but no way as stable material.
> 
> Also, there is certainly no way I'm going to allow a patch to randomly
> enable underflow/overflow for all WRITE non control CDBs tree-wide
> across all fabric drivers, because 1) no host environments actually care
> about this, and 2) it's still dangerous to do for all fabrics without
> some serious auditing.

After further consideration, I've decided against allowing iscsi-target
underflow with a immediate data payload larger than SCSI transfer
length.

Any host environment that attempts to send an underflow with a immediate
data payload larger than SCSI transfer length, expects the target to
automatically truncate immediate data, and still return GOOD status is
completely bogus.  Any host that attempts this is buggy, and needs to be
fixed.

This is because for the last ~12 years of RFC-3720:

  - There has never been a host environment in the wild that exhibits 
this behavior.
  - There has never been a conformance suite which expects this 
behavior.

So rejecting this case as already done in commit abb85a9b51 is the
correct approach for >= v4.3.y.

Of course, the typical underflow scenario which Roland's v4.3.y commit
enabled, underflow where immediate data matches the SCSI transfer length
is supported for control CDBs.

That said, thanks for high-lighting this particular corner case, so it
could be fixed in >= v4.3.y.



Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-07-11 Thread Nicholas A. Bellinger
Hi Bart,

On Thu, 2017-06-08 at 23:55 -0700, Nicholas A. Bellinger wrote:
> On Thu, 2017-06-08 at 15:37 +, Bart Van Assche wrote:
> > On Thu, 2017-06-08 at 04:21 +, Nicholas A. Bellinger wrote:
> > > + /*
> > > +  * Check for underflow case where both EDTL and immediate data payload
> > > +  * exceeds what is presented by CDB's TRANSFER LENGTH, and what has
> > > +  * already been set in target_cmd_size_check() as se_cmd->data_length.
> > > +  *
> > > +  * For this special case, fail the command and dump the immediate data
> > > +  * payload.
> > > +  */
> > > + if (cmd->first_burst_len > cmd->se_cmd.data_length) {
> > > + cmd->sense_reason = TCM_INVALID_CDB_FIELD;
> > > + goto after_immediate_data;
> > > + }
> > 
> > A quote from the iSCSI RFC (https://tools.ietf.org/html/rfc5048):
> > 
> >If SPDTL < EDTL for a task, iSCSI Underflow MUST be signaled in the
> >SCSI Response PDU as specified in [RFC3720].  The Residual Count MUST
> >be set to the numerical value of (EDTL - SPDTL).
> > 
> > Sorry but I don't think that sending TCM_INVALID_CDB_FIELD back to the
> > initiator is compliant with the iSCSI RFC.
> 
> Alas, the nuance of what this patch actually does was missed when you
> cut the context.
> 
> First, a bit of history.  LIO has rejected underflow for all WRITEs for
> the first ~12.5 years of RFC-3720, and in the context of iscsi-target
> mode there has never been a single host environment that ever once
> cared.
> 
> Since Roland's patch to allow underflow for control CDBs in v4.3+ opened
> this discussion for control CDBs with a WRITE payload in order to make
> MSFT/FCP cert for PERSISTENT_RESERVE_OUT happy, the question has become
> what control CDB WRITE underflow cases should we allow..?
> 
> The point with this patch is when a host is sending a underflow with a
> iscsi immediate data payload that exceeds SCSI transfer length, it's a
> bogus request with a garbage payload.  It's a garbage payload because
> the SCSI CDB itself obviously doesn't want anything to do it.
> 
> I'm very dubious of any host environment who's trying to do this for any
> CDB, and expects achieve expected results.
> 
> Of course, since v4.3+ normal overflow where SCSI transfer length
> matches the iscsi immediate data payload just works with or without this
> patch.
> 
> So to that extent, I'm going to push this patch as a defensive fix for
> v4.3+, to let those imaginary iscsi host environments know they being
> very, very naughty.
> 
> >  Please note that a fix that is
> > compliant with the iSCSI RFC is present in the following patch series: 
> > [PATCH
> > 00/33] SCSI target driver patches for kernel v4.13, 23 May 2017
> > (https://www.spinics.net/lists/target-devel/msg15370.html).
> 
> So I might still consider this as a v4.13-rc item for control CDB
> underflow, but no way as stable material.
> 
> Also, there is certainly no way I'm going to allow a patch to randomly
> enable underflow/overflow for all WRITE non control CDBs tree-wide
> across all fabric drivers, because 1) no host environments actually care
> about this, and 2) it's still dangerous to do for all fabrics without
> some serious auditing.

After further consideration, I've decided against allowing iscsi-target
underflow with a immediate data payload larger than SCSI transfer
length.

Any host environment that attempts to send an underflow with a immediate
data payload larger than SCSI transfer length, expects the target to
automatically truncate immediate data, and still return GOOD status is
completely bogus.  Any host that attempts this is buggy, and needs to be
fixed.

This is because for the last ~12 years of RFC-3720:

  - There has never been a host environment in the wild that exhibits 
this behavior.
  - There has never been a conformance suite which expects this 
behavior.

So rejecting this case as already done in commit abb85a9b51 is the
correct approach for >= v4.3.y.

Of course, the typical underflow scenario which Roland's v4.3.y commit
enabled, underflow where immediate data matches the SCSI transfer length
is supported for control CDBs.

That said, thanks for high-lighting this particular corner case, so it
could be fixed in >= v4.3.y.



[PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch re-introduces part of a long standing login workaround that
was recently dropped by:

  commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
  Author: Nicholas Bellinger <n...@linux-iscsi.org>
  Date:   Sun Apr 2 13:36:44 2017 -0700

  iscsi-target: Drop work-around for legacy GlobalSAN initiator

Namely, the workaround for FirstBurstLength ended up being required by
Mellanox Flexboot PXE boot ROMs as reported by Robert.

So this patch re-adds the work-around for FirstBurstLength within
iscsi_check_proposer_for_optional_reply(), and makes the key optional
to respond when the initiator does not propose, nor respond to it.

Also as requested by Arun, this patch introduces a new TPG attribute
named 'login_keys_workaround' that controls the use of both the
FirstBurstLength workaround, as well as the two other existing
workarounds for gPXE iSCSI boot client.

By default, the workaround is enabled with login_keys_workaround=1,
since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
MSFT initiator already proposes FirstBurstLength, so it's uneffected
by this re-adding this part of the original work-around.

Reported-by: Robert LeBlanc <rob...@leblancnet.us>
Cc: Robert LeBlanc <rob...@leblancnet.us>
Cc: Arun Easi <arun.e...@cavium.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target_configfs.c   |  2 ++
 drivers/target/iscsi/iscsi_target_nego.c   |  6 ++--
 drivers/target/iscsi/iscsi_target_parameters.c | 41 ++
 drivers/target/iscsi/iscsi_target_parameters.h |  2 +-
 drivers/target/iscsi/iscsi_target_tpg.c| 19 
 drivers/target/iscsi/iscsi_target_tpg.h|  1 +
 include/target/iscsi/iscsi_target_core.h   |  9 ++
 7 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
b/drivers/target/iscsi/iscsi_target_configfs.c
index 535a8e0..0dd4c45 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -781,6 +781,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
*se_nacl,
 DEF_TPG_ATTRIB(t10_pi);
 DEF_TPG_ATTRIB(fabric_prot_type);
 DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
+DEF_TPG_ATTRIB(login_keys_workaround);
 
 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
_tpg_attrib_attr_authentication,
@@ -796,6 +797,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
*se_nacl,
_tpg_attrib_attr_t10_pi,
_tpg_attrib_attr_fabric_prot_type,
_tpg_attrib_attr_tpg_enabled_sendtargets,
+   _tpg_attrib_attr_login_keys_workaround,
NULL,
 };
 
diff --git a/drivers/target/iscsi/iscsi_target_nego.c 
b/drivers/target/iscsi/iscsi_target_nego.c
index 96df63f..7a6751f 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero(
SENDER_TARGET,
login->rsp_buf,
>rsp_length,
-   conn->param_list);
+   conn->param_list,
+   conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0)
return -1;
 
@@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn 
*conn, struct iscsi_log
SENDER_TARGET,
login->rsp_buf,
>rsp_length,
-   conn->param_list);
+   conn->param_list,
+   conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0) {
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
ISCSI_LOGIN_STATUS_INIT_ERR);
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c 
b/drivers/target/iscsi/iscsi_target_parameters.c
index fce6276..caab104 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char *key)
return 0;
 }
 
-static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
+static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param,
+   bool keys_workaround)
 {
if (IS_TYPE_BOOL_AND(param)) {
if (!strcmp(param->value, NO))
@@ -773,19 +774,31 @@ static void 
iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
} else if (IS_TYPE_BOOL_OR(param)) {
if (!strcmp(param->value, YES))
SET_PSTATE_REPLY_OPTIONAL(param);
-/*
- * Required for gPXE iSCSI boot client
- */
-   if (!strcmp(

[PATCH] iscsi-target: Add login_keys_workaround attribute for non RFC initiators

2017-07-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch re-introduces part of a long standing login workaround that
was recently dropped by:

  commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
  Author: Nicholas Bellinger 
  Date:   Sun Apr 2 13:36:44 2017 -0700

  iscsi-target: Drop work-around for legacy GlobalSAN initiator

Namely, the workaround for FirstBurstLength ended up being required by
Mellanox Flexboot PXE boot ROMs as reported by Robert.

So this patch re-adds the work-around for FirstBurstLength within
iscsi_check_proposer_for_optional_reply(), and makes the key optional
to respond when the initiator does not propose, nor respond to it.

Also as requested by Arun, this patch introduces a new TPG attribute
named 'login_keys_workaround' that controls the use of both the
FirstBurstLength workaround, as well as the two other existing
workarounds for gPXE iSCSI boot client.

By default, the workaround is enabled with login_keys_workaround=1,
since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
MSFT initiator already proposes FirstBurstLength, so it's uneffected
by this re-adding this part of the original work-around.

Reported-by: Robert LeBlanc 
Cc: Robert LeBlanc 
Cc: Arun Easi 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target_configfs.c   |  2 ++
 drivers/target/iscsi/iscsi_target_nego.c   |  6 ++--
 drivers/target/iscsi/iscsi_target_parameters.c | 41 ++
 drivers/target/iscsi/iscsi_target_parameters.h |  2 +-
 drivers/target/iscsi/iscsi_target_tpg.c| 19 
 drivers/target/iscsi/iscsi_target_tpg.h|  1 +
 include/target/iscsi/iscsi_target_core.h   |  9 ++
 7 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
b/drivers/target/iscsi/iscsi_target_configfs.c
index 535a8e0..0dd4c45 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -781,6 +781,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
*se_nacl,
 DEF_TPG_ATTRIB(t10_pi);
 DEF_TPG_ATTRIB(fabric_prot_type);
 DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
+DEF_TPG_ATTRIB(login_keys_workaround);
 
 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
_tpg_attrib_attr_authentication,
@@ -796,6 +797,7 @@ static int lio_target_init_nodeacl(struct se_node_acl 
*se_nacl,
_tpg_attrib_attr_t10_pi,
_tpg_attrib_attr_fabric_prot_type,
_tpg_attrib_attr_tpg_enabled_sendtargets,
+   _tpg_attrib_attr_login_keys_workaround,
NULL,
 };
 
diff --git a/drivers/target/iscsi/iscsi_target_nego.c 
b/drivers/target/iscsi/iscsi_target_nego.c
index 96df63f..7a6751f 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero(
SENDER_TARGET,
login->rsp_buf,
>rsp_length,
-   conn->param_list);
+   conn->param_list,
+   conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0)
return -1;
 
@@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn 
*conn, struct iscsi_log
SENDER_TARGET,
login->rsp_buf,
>rsp_length,
-   conn->param_list);
+   conn->param_list,
+   conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0) {
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
ISCSI_LOGIN_STATUS_INIT_ERR);
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c 
b/drivers/target/iscsi/iscsi_target_parameters.c
index fce6276..caab104 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char *key)
return 0;
 }
 
-static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
+static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param,
+   bool keys_workaround)
 {
if (IS_TYPE_BOOL_AND(param)) {
if (!strcmp(param->value, NO))
@@ -773,19 +774,31 @@ static void 
iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
} else if (IS_TYPE_BOOL_OR(param)) {
if (!strcmp(param->value, YES))
SET_PSTATE_REPLY_OPTIONAL(param);
-/*
- * Required for gPXE iSCSI boot client
- */
-   if (!strcmp(param->name, IMMEDIATEDATA))
-   SET_PSTATE_REPLY_OPTIONAL(param);
+
+   if (keys_workaround) {
+   /*
+  

Re: [PATCH] target: make device_mutex and device_list static

2017-07-06 Thread Nicholas A. Bellinger
On Wed, 2017-07-05 at 13:15 -0500, Mike Christie wrote:
> On 07/04/2017 03:44 AM, Colin King wrote:
> > From: Colin Ian King 
> > 
> > Variables device_mutex and device_list static are local to the source,
> > so make them static.
> > 
> > Cleans up sparse warnings:
> > "symbol 'device_list' was not declared. Should it be static?"
> > "symbol 'device_mutex' was not declared. Should it be static?"
> > 
> > Signed-off-by: Colin Ian King 
> > ---
> >  drivers/target/target_core_device.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/target/target_core_device.c 
> > b/drivers/target/target_core_device.c
> > index 3ae8fbf01bdf..bbcef3bc66c8 100644
> > --- a/drivers/target/target_core_device.c
> > +++ b/drivers/target/target_core_device.c
> > @@ -49,8 +49,8 @@
> >  #include "target_core_pr.h"
> >  #include "target_core_ua.h"
> >  
> > -DEFINE_MUTEX(device_mutex);
> > -LIST_HEAD(device_list);
> > +static DEFINE_MUTEX(device_mutex);
> > +static LIST_HEAD(device_list);
> >  static DEFINE_IDR(devices_idr);
> >  
> >  static struct se_hba *lun0_hba;
> > 
> 
> My fault. Thanks.
> 
> Reviewed-by: Mike Christie 

Applied.

Thanks Colin + MNC.



Re: [PATCH] target: make device_mutex and device_list static

2017-07-06 Thread Nicholas A. Bellinger
On Wed, 2017-07-05 at 13:15 -0500, Mike Christie wrote:
> On 07/04/2017 03:44 AM, Colin King wrote:
> > From: Colin Ian King 
> > 
> > Variables device_mutex and device_list static are local to the source,
> > so make them static.
> > 
> > Cleans up sparse warnings:
> > "symbol 'device_list' was not declared. Should it be static?"
> > "symbol 'device_mutex' was not declared. Should it be static?"
> > 
> > Signed-off-by: Colin Ian King 
> > ---
> >  drivers/target/target_core_device.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/target/target_core_device.c 
> > b/drivers/target/target_core_device.c
> > index 3ae8fbf01bdf..bbcef3bc66c8 100644
> > --- a/drivers/target/target_core_device.c
> > +++ b/drivers/target/target_core_device.c
> > @@ -49,8 +49,8 @@
> >  #include "target_core_pr.h"
> >  #include "target_core_ua.h"
> >  
> > -DEFINE_MUTEX(device_mutex);
> > -LIST_HEAD(device_list);
> > +static DEFINE_MUTEX(device_mutex);
> > +static LIST_HEAD(device_list);
> >  static DEFINE_IDR(devices_idr);
> >  
> >  static struct se_hba *lun0_hba;
> > 
> 
> My fault. Thanks.
> 
> Reviewed-by: Mike Christie 

Applied.

Thanks Colin + MNC.



Re: [kernel-hardening] Re: [PATCH v4 06/13] iscsi: ensure RNG is seeded before use

2017-06-30 Thread Nicholas A. Bellinger
On Mon, 2017-06-26 at 19:38 +0200, Stephan Müller wrote:
> Am Montag, 26. Juni 2017, 03:23:09 CEST schrieb Nicholas A. Bellinger:
> 
> Hi Nicholas,
> 
> > Hi Stephan, Lee & Jason,
> > 
> > (Adding target-devel CC')
> > 
> > Apologies for coming late to the discussion.  Comments below.
> > 
> > On Sun, 2017-06-18 at 10:04 +0200, Stephan Müller wrote:
> > > Am Samstag, 17. Juni 2017, 05:45:57 CEST schrieb Lee Duncan:
> > > 
> > > Hi Lee,
> > > 
> > > > In your testing, how long might a process have to wait? Are we talking
> > > > seconds? Longer? What about timeouts?
> > > 
> > > In current kernels (starting with 4.8) this timeout should clear within a
> > > few seconds after boot.
> > > 
> > > In older kernels (pre 4.8), my KVM takes up to 90 seconds to reach that
> > > seeding point. I have heard that on IBM System Z this trigger point
> > > requires minutes to be reached.
> > 
> > I share the same concern as Lee wrt to introducing latency into the
> > existing iscsi-target login sequence.
> > 
> > Namely in the use-cases where a single node is supporting ~1K unique
> > iscsi-target IQNs, and fail-over + re-balancing of IQNs where 100s of
> > login attempts are expected to occur in parallel.
> > 
> > If environments exist that require non trivial amounts of time for RNG
> > seeding to be ready for iscsi-target usage, then enforcing this
> > requirement at iscsi login time can open up problems, especially when
> > iscsi host environments may be sensitive to login timeouts, I/O
> > timeouts, et al.
> > 
> > That said, I'd prefer to simply wait for RNG to be seeded at modprobe
> > iscsi_target_mod time, instead of trying to enforce randomness during
> > login.
> > 
> > This way, those of use who have distributed storage platforms can know
> > to avoid putting a node into a state to accept iscsi-target IQN export
> > migration, before modprobe iscsi_target_mod has successfully loaded and
> > RNG seeding has been confirmed.
> > 
> > WDYT..?
> 
> We may have a chicken and egg problem when the wait is at the modprobe time. 
> Assume the modprobe happens during initramfs time to get access to the root 
> file system. In this case, you entire boot process will lock up for an 
> indefinite amount of time. The reason is that in order to obtain events 
> detected by the RNG, devices need to be initialized and working. Such devices 
> commonly start working after the the root partition is mounted as it contains 
> all drivers, all configuration information etc.
> 
> Note, during the development of my /dev/random implementation, I added the 
> getrandom-like blocking behavior to /dev/urandom (which is the equivalent to 
> Jason's patch except that it applies to user space). The boot process locked 
> up since systemd wanted data from /dev/urandom while it processed the 
> initramfs. As it did not get any, the boot process did not commence that 
> could 
> deliver new events to be picked up by the RNG.
> 
> As I do not have such an iscsi system, I cannot test Jason's patch. But maybe 
> the mentioned chicken-and-egg problem I mentioned above is already visible 
> with the current patch as it will lead to a blocking of the mounting of the 
> root partition in case the root partition is on an iscsi target.

AFAIK, there are no distro initramfs dependencies for iscsi_target_mod,
and every environment I've ever seen loads iscsi_target_mod after
switching to the real rootfs.

For an iscsi initiator that might not been the case, especially if the
rootfs is running atop a iscsi LUN.

But at least for iscsi-target mode, any blocking during modprobe waiting
for RNG seeding would happen outside of initramfs.



Re: [kernel-hardening] Re: [PATCH v4 06/13] iscsi: ensure RNG is seeded before use

2017-06-30 Thread Nicholas A. Bellinger
On Mon, 2017-06-26 at 19:38 +0200, Stephan Müller wrote:
> Am Montag, 26. Juni 2017, 03:23:09 CEST schrieb Nicholas A. Bellinger:
> 
> Hi Nicholas,
> 
> > Hi Stephan, Lee & Jason,
> > 
> > (Adding target-devel CC')
> > 
> > Apologies for coming late to the discussion.  Comments below.
> > 
> > On Sun, 2017-06-18 at 10:04 +0200, Stephan Müller wrote:
> > > Am Samstag, 17. Juni 2017, 05:45:57 CEST schrieb Lee Duncan:
> > > 
> > > Hi Lee,
> > > 
> > > > In your testing, how long might a process have to wait? Are we talking
> > > > seconds? Longer? What about timeouts?
> > > 
> > > In current kernels (starting with 4.8) this timeout should clear within a
> > > few seconds after boot.
> > > 
> > > In older kernels (pre 4.8), my KVM takes up to 90 seconds to reach that
> > > seeding point. I have heard that on IBM System Z this trigger point
> > > requires minutes to be reached.
> > 
> > I share the same concern as Lee wrt to introducing latency into the
> > existing iscsi-target login sequence.
> > 
> > Namely in the use-cases where a single node is supporting ~1K unique
> > iscsi-target IQNs, and fail-over + re-balancing of IQNs where 100s of
> > login attempts are expected to occur in parallel.
> > 
> > If environments exist that require non trivial amounts of time for RNG
> > seeding to be ready for iscsi-target usage, then enforcing this
> > requirement at iscsi login time can open up problems, especially when
> > iscsi host environments may be sensitive to login timeouts, I/O
> > timeouts, et al.
> > 
> > That said, I'd prefer to simply wait for RNG to be seeded at modprobe
> > iscsi_target_mod time, instead of trying to enforce randomness during
> > login.
> > 
> > This way, those of use who have distributed storage platforms can know
> > to avoid putting a node into a state to accept iscsi-target IQN export
> > migration, before modprobe iscsi_target_mod has successfully loaded and
> > RNG seeding has been confirmed.
> > 
> > WDYT..?
> 
> We may have a chicken and egg problem when the wait is at the modprobe time. 
> Assume the modprobe happens during initramfs time to get access to the root 
> file system. In this case, you entire boot process will lock up for an 
> indefinite amount of time. The reason is that in order to obtain events 
> detected by the RNG, devices need to be initialized and working. Such devices 
> commonly start working after the the root partition is mounted as it contains 
> all drivers, all configuration information etc.
> 
> Note, during the development of my /dev/random implementation, I added the 
> getrandom-like blocking behavior to /dev/urandom (which is the equivalent to 
> Jason's patch except that it applies to user space). The boot process locked 
> up since systemd wanted data from /dev/urandom while it processed the 
> initramfs. As it did not get any, the boot process did not commence that 
> could 
> deliver new events to be picked up by the RNG.
> 
> As I do not have such an iscsi system, I cannot test Jason's patch. But maybe 
> the mentioned chicken-and-egg problem I mentioned above is already visible 
> with the current patch as it will lead to a blocking of the mounting of the 
> root partition in case the root partition is on an iscsi target.

AFAIK, there are no distro initramfs dependencies for iscsi_target_mod,
and every environment I've ever seen loads iscsi_target_mod after
switching to the real rootfs.

For an iscsi initiator that might not been the case, especially if the
rootfs is running atop a iscsi LUN.

But at least for iscsi-target mode, any blocking during modprobe waiting
for RNG seeding would happen outside of initramfs.



Re: [PATCH] ib_isert: prevent NULL pointer dereference in isert_login_recv_done()

2017-06-29 Thread Nicholas A. Bellinger
On Thu, 2017-06-29 at 11:28 +0300, Sagi Grimberg wrote:
> >> Can you test just the one liner fix below?
> >>
>  @@ -1452,7 +1452,7 @@
>    isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
>    {
>   struct isert_conn *isert_conn = wc->qp->qp_context;
>  -struct ib_device *ib_dev = isert_conn->cm_id->device;
>  +struct ib_device *ib_dev = isert_conn->device->ib_device;
>   if (unlikely(wc->status != IB_WC_SUCCESS)) {
>   isert_print_wc(wc, "login recv");
> > 
> > I'll test also this one-liner fix as soon as I can.
> > 
> > But I can say that I'm pretty sure it will work as well, because all the
> > previous NULL pointer dereferences that we've got in the past happened
> > all 100% in isert_login_recv_done(). The other cases are probably a safe
> > precaution, but they can't really happen.
> 
> Agree, I'd prefer to start with a surgical fix before moving forward.

Sounds fine.  The single line fix above in isert_login_recv_done() has
been queued up in target-pending/for-next with Andrea's Tested-by and
your Reviewed-by:

https://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git/commit/?h=for-next=702c0f17403765cc5aa1c18f6ea6eb549c1bac9b

Please let me know if there are any other issues wrt the surgical fix.



Re: [PATCH] ib_isert: prevent NULL pointer dereference in isert_login_recv_done()

2017-06-29 Thread Nicholas A. Bellinger
On Thu, 2017-06-29 at 11:28 +0300, Sagi Grimberg wrote:
> >> Can you test just the one liner fix below?
> >>
>  @@ -1452,7 +1452,7 @@
>    isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
>    {
>   struct isert_conn *isert_conn = wc->qp->qp_context;
>  -struct ib_device *ib_dev = isert_conn->cm_id->device;
>  +struct ib_device *ib_dev = isert_conn->device->ib_device;
>   if (unlikely(wc->status != IB_WC_SUCCESS)) {
>   isert_print_wc(wc, "login recv");
> > 
> > I'll test also this one-liner fix as soon as I can.
> > 
> > But I can say that I'm pretty sure it will work as well, because all the
> > previous NULL pointer dereferences that we've got in the past happened
> > all 100% in isert_login_recv_done(). The other cases are probably a safe
> > precaution, but they can't really happen.
> 
> Agree, I'd prefer to start with a surgical fix before moving forward.

Sounds fine.  The single line fix above in isert_login_recv_done() has
been queued up in target-pending/for-next with Andrea's Tested-by and
your Reviewed-by:

https://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git/commit/?h=for-next=702c0f17403765cc5aa1c18f6ea6eb549c1bac9b

Please let me know if there are any other issues wrt the surgical fix.



Re: [kernel-hardening] Re: [PATCH v4 06/13] iscsi: ensure RNG is seeded before use

2017-06-25 Thread Nicholas A. Bellinger
Hi Stephan, Lee & Jason,

(Adding target-devel CC')

Apologies for coming late to the discussion.  Comments below.

On Sun, 2017-06-18 at 10:04 +0200, Stephan Müller wrote:
> Am Samstag, 17. Juni 2017, 05:45:57 CEST schrieb Lee Duncan:
> 
> Hi Lee,
> 
> > In your testing, how long might a process have to wait? Are we talking
> > seconds? Longer? What about timeouts?
> >
> 
> In current kernels (starting with 4.8) this timeout should clear within a few 
> seconds after boot.
> 
> In older kernels (pre 4.8), my KVM takes up to 90 seconds to reach that 
> seeding point. I have heard that on IBM System Z this trigger point requires 
> minutes to be reached.
> 

I share the same concern as Lee wrt to introducing latency into the
existing iscsi-target login sequence.

Namely in the use-cases where a single node is supporting ~1K unique
iscsi-target IQNs, and fail-over + re-balancing of IQNs where 100s of
login attempts are expected to occur in parallel.

If environments exist that require non trivial amounts of time for RNG
seeding to be ready for iscsi-target usage, then enforcing this
requirement at iscsi login time can open up problems, especially when
iscsi host environments may be sensitive to login timeouts, I/O
timeouts, et al.

That said, I'd prefer to simply wait for RNG to be seeded at modprobe
iscsi_target_mod time, instead of trying to enforce randomness during
login.

This way, those of use who have distributed storage platforms can know
to avoid putting a node into a state to accept iscsi-target IQN export
migration, before modprobe iscsi_target_mod has successfully loaded and
RNG seeding has been confirmed.

WDYT..?



Re: [kernel-hardening] Re: [PATCH v4 06/13] iscsi: ensure RNG is seeded before use

2017-06-25 Thread Nicholas A. Bellinger
Hi Stephan, Lee & Jason,

(Adding target-devel CC')

Apologies for coming late to the discussion.  Comments below.

On Sun, 2017-06-18 at 10:04 +0200, Stephan Müller wrote:
> Am Samstag, 17. Juni 2017, 05:45:57 CEST schrieb Lee Duncan:
> 
> Hi Lee,
> 
> > In your testing, how long might a process have to wait? Are we talking
> > seconds? Longer? What about timeouts?
> >
> 
> In current kernels (starting with 4.8) this timeout should clear within a few 
> seconds after boot.
> 
> In older kernels (pre 4.8), my KVM takes up to 90 seconds to reach that 
> seeding point. I have heard that on IBM System Z this trigger point requires 
> minutes to be reached.
> 

I share the same concern as Lee wrt to introducing latency into the
existing iscsi-target login sequence.

Namely in the use-cases where a single node is supporting ~1K unique
iscsi-target IQNs, and fail-over + re-balancing of IQNs where 100s of
login attempts are expected to occur in parallel.

If environments exist that require non trivial amounts of time for RNG
seeding to be ready for iscsi-target usage, then enforcing this
requirement at iscsi login time can open up problems, especially when
iscsi host environments may be sensitive to login timeouts, I/O
timeouts, et al.

That said, I'd prefer to simply wait for RNG to be seeded at modprobe
iscsi_target_mod time, instead of trying to enforce randomness during
login.

This way, those of use who have distributed storage platforms can know
to avoid putting a node into a state to accept iscsi-target IQN export
migration, before modprobe iscsi_target_mod has successfully loaded and
RNG seeding has been confirmed.

WDYT..?



Re: [PATCH] ib_isert: prevent NULL pointer dereference in isert_login_recv_done() (was: Re: NULL pointer dereference in isert_login_recv_done in 4.9.32)

2017-06-25 Thread Nicholas A. Bellinger
Hi Andrea & Robert,

(Adding HCH CC')

On Fri, 2017-06-23 at 00:37 +0200, Andrea Righi wrote:
> On Wed, Jun 21, 2017 at 10:33:45AM -0600, Robert LeBlanc wrote:
> > On Wed, Jun 21, 2017 at 9:17 AM, Robert LeBlanc  
> > wrote:
> > > On Tue, Jun 20, 2017 at 12:54 PM, Robert LeBlanc  
> > > wrote:
> > >> We have hit this four times today. Any ideas?
> > >>
> > >> [  169.382113] BUG: unable to handle kernel NULL pointer dereference at  
> > >>  (null)
> > >> [  169.382152] IP: [] isert_login_recv_done+0x28/0x170 
> > >> [ib_isert]
> 
> So, we spent more time to track down this bug.
> 
> It seems that at login time an error is happening, not sure exactly what
> kind of error, but isert_connect_error() is called and isert_conn->cm_id
> is set to NULL.
> 
> Later, isert_login_recv_done() is trying to access
> isert_conn->cm_id->device and we get the NULL pointer dereference.
> 
> Following there's the patch that we have applied to track down this
> problem.
> 
> And this is what we see in dmesg with this patch applied:
> 
>  [  658.633188] isert: isert_connect_error: conn 887f2209c000 error
>  [  658.633226] isert: isert_login_recv_done: login with broken rdma_cm_id
> 
> As we can see isert_connect_error() is called before isert_login_recv_done
> and at that point isert_conn->cm_id is NULL.
> 
> Obviously simply checking if the pointer is NULL, returning and ignoring
> the error in isert_login_recv_done() is not the best fix ever and I'm
> not sure if I'm breaking something else doing so (even if with this
> patch the kernel doesn't crash and I've not seen any problem so far).
> 
> Maybe a better way is to tear down the whole connection when this
> particular case is happening? Suggestions?
> 
> Thanks,
> -Andrea
> 
> ---
> ib_isert: prevent NULL pointer dereference in isert_login_recv_done()
> 
> During a login if an error is happening isert_connect_error() is called
> and isert_conn->cm_id is set to NULL.
> 
> Later, isert_login_recv_done() is executed, trying to access
> isert_conn->cm_id->device, causing the following BUG:
> 
>  [  169.382113] BUG: unable to handle kernel NULL pointer dereference at 
> (null)
>  [  169.382152] IP: [] isert_login_recv_done+0x28/0x170 
> [ib_isert]
> 
> Check if isert_con->cm_id is set to NULL in isert_login_recv_done() to
> avoid this problem.
> 
> Signed-off-by: Andrea Righi 
> Signed-off-by: Robert LeBlanc 
> ---
>  drivers/infiniband/ulp/isert/ib_isert.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
> b/drivers/infiniband/ulp/isert/ib_isert.c
> index fcbed35..a8c1143 100644
> --- a/drivers/infiniband/ulp/isert/ib_isert.c
> +++ b/drivers/infiniband/ulp/isert/ib_isert.c
> @@ -741,6 +741,7 @@ isert_connect_error(struct rdma_cm_id *cma_id)
>  {
>   struct isert_conn *isert_conn = cma_id->qp->qp_context;
>  
> + isert_warn("conn %p error\n", isert_conn);
>   list_del_init(_conn->node);
>   isert_conn->cm_id = NULL;
>   isert_put_conn(isert_conn);
> @@ -1452,7 +1453,13 @@ static void
>  isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
>  {
>   struct isert_conn *isert_conn = wc->qp->qp_context;
> - struct ib_device *ib_dev = isert_conn->cm_id->device;
> +struct ib_device *ib_dev;
> +
> + if (unlikely(isert_conn->cm_id == NULL)) {
> + isert_warn("login with broken rdma_cm_id");
> + return;
> + }
> + ib_dev = isert_conn->cm_id->device;
>  
>   if (unlikely(wc->status != IB_WC_SUCCESS)) {
>   isert_print_wc(wc, "login recv");

So I assume isert_cma_handler() -> isert_connect_error() getting called
to clear isert_conn->cm_id before connection established, and
subsequently isert_conn->login_req_buf->rx_cqe.done() ->
isert_login_recv_done() still getting invoked after connection failure
is new RDMA API behavior..

That said, following Sagi's original patch that added the clearing of
isert_conn->cm_id to isert_connect_error(), it probably makes sense to
use isert_conn->device->ib_device, and avoid dereferencing
isert_conn->cm_id before connection is established.

Here's a quick (untested) patch to do this for recv/send done callbacks,
and avoid using isert_conn->cm_id during isert_rdma_accept().

Sagi + Co, WDYT..?

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
b/drivers/infiniband/ulp/isert/ib_isert.c
index fcbed35..f7f97f3 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -52,7 +52,7 @@
 static int
 isert_login_post_recv(struct isert_conn *isert_conn);
 static int
-isert_rdma_accept(struct isert_conn *isert_conn);
+isert_rdma_accept(struct isert_conn *isert_conn, struct rdma_cm_id *cm_id);
 struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
 
 static void isert_release_work(struct work_struct *work);
@@ -543,7 +543,7 @@
if (ret)

Re: [PATCH] ib_isert: prevent NULL pointer dereference in isert_login_recv_done() (was: Re: NULL pointer dereference in isert_login_recv_done in 4.9.32)

2017-06-25 Thread Nicholas A. Bellinger
Hi Andrea & Robert,

(Adding HCH CC')

On Fri, 2017-06-23 at 00:37 +0200, Andrea Righi wrote:
> On Wed, Jun 21, 2017 at 10:33:45AM -0600, Robert LeBlanc wrote:
> > On Wed, Jun 21, 2017 at 9:17 AM, Robert LeBlanc  
> > wrote:
> > > On Tue, Jun 20, 2017 at 12:54 PM, Robert LeBlanc  
> > > wrote:
> > >> We have hit this four times today. Any ideas?
> > >>
> > >> [  169.382113] BUG: unable to handle kernel NULL pointer dereference at  
> > >>  (null)
> > >> [  169.382152] IP: [] isert_login_recv_done+0x28/0x170 
> > >> [ib_isert]
> 
> So, we spent more time to track down this bug.
> 
> It seems that at login time an error is happening, not sure exactly what
> kind of error, but isert_connect_error() is called and isert_conn->cm_id
> is set to NULL.
> 
> Later, isert_login_recv_done() is trying to access
> isert_conn->cm_id->device and we get the NULL pointer dereference.
> 
> Following there's the patch that we have applied to track down this
> problem.
> 
> And this is what we see in dmesg with this patch applied:
> 
>  [  658.633188] isert: isert_connect_error: conn 887f2209c000 error
>  [  658.633226] isert: isert_login_recv_done: login with broken rdma_cm_id
> 
> As we can see isert_connect_error() is called before isert_login_recv_done
> and at that point isert_conn->cm_id is NULL.
> 
> Obviously simply checking if the pointer is NULL, returning and ignoring
> the error in isert_login_recv_done() is not the best fix ever and I'm
> not sure if I'm breaking something else doing so (even if with this
> patch the kernel doesn't crash and I've not seen any problem so far).
> 
> Maybe a better way is to tear down the whole connection when this
> particular case is happening? Suggestions?
> 
> Thanks,
> -Andrea
> 
> ---
> ib_isert: prevent NULL pointer dereference in isert_login_recv_done()
> 
> During a login if an error is happening isert_connect_error() is called
> and isert_conn->cm_id is set to NULL.
> 
> Later, isert_login_recv_done() is executed, trying to access
> isert_conn->cm_id->device, causing the following BUG:
> 
>  [  169.382113] BUG: unable to handle kernel NULL pointer dereference at 
> (null)
>  [  169.382152] IP: [] isert_login_recv_done+0x28/0x170 
> [ib_isert]
> 
> Check if isert_con->cm_id is set to NULL in isert_login_recv_done() to
> avoid this problem.
> 
> Signed-off-by: Andrea Righi 
> Signed-off-by: Robert LeBlanc 
> ---
>  drivers/infiniband/ulp/isert/ib_isert.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
> b/drivers/infiniband/ulp/isert/ib_isert.c
> index fcbed35..a8c1143 100644
> --- a/drivers/infiniband/ulp/isert/ib_isert.c
> +++ b/drivers/infiniband/ulp/isert/ib_isert.c
> @@ -741,6 +741,7 @@ isert_connect_error(struct rdma_cm_id *cma_id)
>  {
>   struct isert_conn *isert_conn = cma_id->qp->qp_context;
>  
> + isert_warn("conn %p error\n", isert_conn);
>   list_del_init(_conn->node);
>   isert_conn->cm_id = NULL;
>   isert_put_conn(isert_conn);
> @@ -1452,7 +1453,13 @@ static void
>  isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
>  {
>   struct isert_conn *isert_conn = wc->qp->qp_context;
> - struct ib_device *ib_dev = isert_conn->cm_id->device;
> +struct ib_device *ib_dev;
> +
> + if (unlikely(isert_conn->cm_id == NULL)) {
> + isert_warn("login with broken rdma_cm_id");
> + return;
> + }
> + ib_dev = isert_conn->cm_id->device;
>  
>   if (unlikely(wc->status != IB_WC_SUCCESS)) {
>   isert_print_wc(wc, "login recv");

So I assume isert_cma_handler() -> isert_connect_error() getting called
to clear isert_conn->cm_id before connection established, and
subsequently isert_conn->login_req_buf->rx_cqe.done() ->
isert_login_recv_done() still getting invoked after connection failure
is new RDMA API behavior..

That said, following Sagi's original patch that added the clearing of
isert_conn->cm_id to isert_connect_error(), it probably makes sense to
use isert_conn->device->ib_device, and avoid dereferencing
isert_conn->cm_id before connection is established.

Here's a quick (untested) patch to do this for recv/send done callbacks,
and avoid using isert_conn->cm_id during isert_rdma_accept().

Sagi + Co, WDYT..?

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c 
b/drivers/infiniband/ulp/isert/ib_isert.c
index fcbed35..f7f97f3 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -52,7 +52,7 @@
 static int
 isert_login_post_recv(struct isert_conn *isert_conn);
 static int
-isert_rdma_accept(struct isert_conn *isert_conn);
+isert_rdma_accept(struct isert_conn *isert_conn, struct rdma_cm_id *cm_id);
 struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
 
 static void isert_release_work(struct work_struct *work);
@@ -543,7 +543,7 @@
if (ret)
goto out_conn_dev;
 
-   ret = isert_rdma_accept(isert_conn);
+   ret = 

Re: [PATCH][V2][target-devel-next] tcmu: make array tcmu_attrib_attrs static const

2017-06-25 Thread Nicholas A. Bellinger
On Tue, 2017-06-13 at 14:29 +0100, Colin King wrote:
> From: Colin Ian King 
> 
> The array tcmu_attrib_attrs does not need to be in global scope, so make
> it static.
> 
> Cleans up sparse warning:
> "symbol 'tcmu_attrib_attrs' was not declared. Should it be static?"
> 
> Signed-off-by: Colin Ian King 
> ---
>  drivers/target/target_core_user.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/target/target_core_user.c 
> b/drivers/target/target_core_user.c
> index afc1fd6bacaf..04fb3f720895 100644
> --- a/drivers/target/target_core_user.c
> +++ b/drivers/target/target_core_user.c
> @@ -1672,7 +1672,7 @@ static ssize_t tcmu_emulate_write_cache_store(struct 
> config_item *item,
>  }
>  CONFIGFS_ATTR(tcmu_, emulate_write_cache);
>  
> -struct configfs_attribute *tcmu_attrib_attrs[] = {
> +static struct configfs_attribute *tcmu_attrib_attrs[] = {
>   _attr_cmd_time_out,
>   _attr_dev_path,
>   _attr_dev_size,

Applied.

Thanks Colin.



Re: [PATCH][V2][target-devel-next] tcmu: make array tcmu_attrib_attrs static const

2017-06-25 Thread Nicholas A. Bellinger
On Tue, 2017-06-13 at 14:29 +0100, Colin King wrote:
> From: Colin Ian King 
> 
> The array tcmu_attrib_attrs does not need to be in global scope, so make
> it static.
> 
> Cleans up sparse warning:
> "symbol 'tcmu_attrib_attrs' was not declared. Should it be static?"
> 
> Signed-off-by: Colin Ian King 
> ---
>  drivers/target/target_core_user.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/target/target_core_user.c 
> b/drivers/target/target_core_user.c
> index afc1fd6bacaf..04fb3f720895 100644
> --- a/drivers/target/target_core_user.c
> +++ b/drivers/target/target_core_user.c
> @@ -1672,7 +1672,7 @@ static ssize_t tcmu_emulate_write_cache_store(struct 
> config_item *item,
>  }
>  CONFIGFS_ATTR(tcmu_, emulate_write_cache);
>  
> -struct configfs_attribute *tcmu_attrib_attrs[] = {
> +static struct configfs_attribute *tcmu_attrib_attrs[] = {
>   _attr_cmd_time_out,
>   _attr_dev_path,
>   _attr_dev_size,

Applied.

Thanks Colin.



[GIT PULL] target fixes for v4.12-rc7

2017-06-24 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending fixes for v4.12-rc7 that have been queued up
for the last 2 weeks.  Please go ahead and pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master

This includes:

- Fix a TMR related kref underflow detected by the recent refcount_t 
  conversion in upstream.
- Fix a iscsi-target corner case during explicit connection logout 
  timeout failure.
- Address last fallout in iscsi-target immediate data handling from
  v4.4 target-core now allowing control CDB payload underflow.

Thank you,

--nab

Nicholas Bellinger (3):
  target: Fix kref->refcount underflow in transport_cmd_finish_abort
  iscsi-target: Fix delayed logout processing greater than
SECONDS_FOR_LOGOUT_COMP
  iscsi-target: Reject immediate data underflow larger than SCSI
transfer length

 drivers/target/iscsi/iscsi_target.c| 22 --
 drivers/target/target_core_internal.h  |  2 +-
 drivers/target/target_core_tmr.c   | 16 
 drivers/target/target_core_transport.c |  9 ++---
 4 files changed, 35 insertions(+), 14 deletions(-)



[GIT PULL] target fixes for v4.12-rc7

2017-06-24 Thread Nicholas A. Bellinger
Hi Linus,

Here are the target-pending fixes for v4.12-rc7 that have been queued up
for the last 2 weeks.  Please go ahead and pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master

This includes:

- Fix a TMR related kref underflow detected by the recent refcount_t 
  conversion in upstream.
- Fix a iscsi-target corner case during explicit connection logout 
  timeout failure.
- Address last fallout in iscsi-target immediate data handling from
  v4.4 target-core now allowing control CDB payload underflow.

Thank you,

--nab

Nicholas Bellinger (3):
  target: Fix kref->refcount underflow in transport_cmd_finish_abort
  iscsi-target: Fix delayed logout processing greater than
SECONDS_FOR_LOGOUT_COMP
  iscsi-target: Reject immediate data underflow larger than SCSI
transfer length

 drivers/target/iscsi/iscsi_target.c| 22 --
 drivers/target/target_core_internal.h  |  2 +-
 drivers/target/target_core_tmr.c   | 16 
 drivers/target/target_core_transport.c |  9 ++---
 4 files changed, 35 insertions(+), 14 deletions(-)



Re: [PATCH] configfs: Fix race between create_link and configfs_rmdir

2017-06-09 Thread Nicholas A. Bellinger
On Thu, 2017-06-08 at 07:34 -0500, Bryant G. Ly wrote:
> > Thanks Nic,
> >
> > applied to the configfs-for-next tree.  I'm not entirely sure if we
> > should bother adding this to 4.12 or if it hits rarely enough?
> >
> It hits for us pretty often when we have a GPFS setup with 10 hosts and 1k+ 
> vms.
> 
> That is how we discovered the bug in the first place.
> 

Using a DATERA workload with 1K unique multi-tenant backend devices and
1K unique iscsi-target IQNs per node, I've never tripped across this
particular bug..

However, our userspace built atop rtslib is enforcing tenant shutdown of
individual rmdir(2) of /sys/kernel/config/target/$FABRIC/$WWN/$TPGT/,
before rmdir(2) of /sys/kernel/config/target/core/$HBA/$DEV/ occurs.

Based on Bryant's original backtrace with targetcli, it looks like the
Novalink user-space is not enforcing this requirement across user-space
processes doing fabric port symlink and backend device shutdown.

That said it probably doesn't need a special v4.12-rc PULL, but based on
Bryant's feedback it certainly does deserve a stable CC'.



Re: [PATCH] configfs: Fix race between create_link and configfs_rmdir

2017-06-09 Thread Nicholas A. Bellinger
On Thu, 2017-06-08 at 07:34 -0500, Bryant G. Ly wrote:
> > Thanks Nic,
> >
> > applied to the configfs-for-next tree.  I'm not entirely sure if we
> > should bother adding this to 4.12 or if it hits rarely enough?
> >
> It hits for us pretty often when we have a GPFS setup with 10 hosts and 1k+ 
> vms.
> 
> That is how we discovered the bug in the first place.
> 

Using a DATERA workload with 1K unique multi-tenant backend devices and
1K unique iscsi-target IQNs per node, I've never tripped across this
particular bug..

However, our userspace built atop rtslib is enforcing tenant shutdown of
individual rmdir(2) of /sys/kernel/config/target/$FABRIC/$WWN/$TPGT/,
before rmdir(2) of /sys/kernel/config/target/core/$HBA/$DEV/ occurs.

Based on Bryant's original backtrace with targetcli, it looks like the
Novalink user-space is not enforcing this requirement across user-space
processes doing fabric port symlink and backend device shutdown.

That said it probably doesn't need a special v4.12-rc PULL, but based on
Bryant's feedback it certainly does deserve a stable CC'.



Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-06-09 Thread Nicholas A. Bellinger
On Thu, 2017-06-08 at 15:37 +, Bart Van Assche wrote:
> On Thu, 2017-06-08 at 04:21 +0000, Nicholas A. Bellinger wrote:
> > +   /*
> > +* Check for underflow case where both EDTL and immediate data payload
> > +* exceeds what is presented by CDB's TRANSFER LENGTH, and what has
> > +* already been set in target_cmd_size_check() as se_cmd->data_length.
> > +*
> > +* For this special case, fail the command and dump the immediate data
> > +* payload.
> > +*/
> > +   if (cmd->first_burst_len > cmd->se_cmd.data_length) {
> > +   cmd->sense_reason = TCM_INVALID_CDB_FIELD;
> > +   goto after_immediate_data;
> > +   }
> 
> A quote from the iSCSI RFC (https://tools.ietf.org/html/rfc5048):
> 
>If SPDTL < EDTL for a task, iSCSI Underflow MUST be signaled in the
>SCSI Response PDU as specified in [RFC3720].  The Residual Count MUST
>be set to the numerical value of (EDTL - SPDTL).
> 
> Sorry but I don't think that sending TCM_INVALID_CDB_FIELD back to the
> initiator is compliant with the iSCSI RFC.

Alas, the nuance of what this patch actually does was missed when you
cut the context.

First, a bit of history.  LIO has rejected underflow for all WRITEs for
the first ~12.5 years of RFC-3720, and in the context of iscsi-target
mode there has never been a single host environment that ever once
cared.

Since Roland's patch to allow underflow for control CDBs in v4.3+ opened
this discussion for control CDBs with a WRITE payload in order to make
MSFT/FCP cert for PERSISTENT_RESERVE_OUT happy, the question has become
what control CDB WRITE underflow cases should we allow..?

The point with this patch is when a host is sending a underflow with a
iscsi immediate data payload that exceeds SCSI transfer length, it's a
bogus request with a garbage payload.  It's a garbage payload because
the SCSI CDB itself obviously doesn't want anything to do it.

I'm very dubious of any host environment who's trying to do this for any
CDB, and expects achieve expected results.

Of course, since v4.3+ normal overflow where SCSI transfer length
matches the iscsi immediate data payload just works with or without this
patch.

So to that extent, I'm going to push this patch as a defensive fix for
v4.3+, to let those imaginary iscsi host environments know they being
very, very naughty.

>  Please note that a fix that is
> compliant with the iSCSI RFC is present in the following patch series: [PATCH
> 00/33] SCSI target driver patches for kernel v4.13, 23 May 2017
> (https://www.spinics.net/lists/target-devel/msg15370.html).

So I might still consider this as a v4.13-rc item for control CDB
underflow, but no way as stable material.

Also, there is certainly no way I'm going to allow a patch to randomly
enable underflow/overflow for all WRITE non control CDBs tree-wide
across all fabric drivers, because 1) no host environments actually care
about this, and 2) it's still dangerous to do for all fabrics without
some serious auditing.



Re: [PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-06-09 Thread Nicholas A. Bellinger
On Thu, 2017-06-08 at 15:37 +, Bart Van Assche wrote:
> On Thu, 2017-06-08 at 04:21 +0000, Nicholas A. Bellinger wrote:
> > +   /*
> > +* Check for underflow case where both EDTL and immediate data payload
> > +* exceeds what is presented by CDB's TRANSFER LENGTH, and what has
> > +* already been set in target_cmd_size_check() as se_cmd->data_length.
> > +*
> > +* For this special case, fail the command and dump the immediate data
> > +* payload.
> > +*/
> > +   if (cmd->first_burst_len > cmd->se_cmd.data_length) {
> > +   cmd->sense_reason = TCM_INVALID_CDB_FIELD;
> > +   goto after_immediate_data;
> > +   }
> 
> A quote from the iSCSI RFC (https://tools.ietf.org/html/rfc5048):
> 
>If SPDTL < EDTL for a task, iSCSI Underflow MUST be signaled in the
>SCSI Response PDU as specified in [RFC3720].  The Residual Count MUST
>be set to the numerical value of (EDTL - SPDTL).
> 
> Sorry but I don't think that sending TCM_INVALID_CDB_FIELD back to the
> initiator is compliant with the iSCSI RFC.

Alas, the nuance of what this patch actually does was missed when you
cut the context.

First, a bit of history.  LIO has rejected underflow for all WRITEs for
the first ~12.5 years of RFC-3720, and in the context of iscsi-target
mode there has never been a single host environment that ever once
cared.

Since Roland's patch to allow underflow for control CDBs in v4.3+ opened
this discussion for control CDBs with a WRITE payload in order to make
MSFT/FCP cert for PERSISTENT_RESERVE_OUT happy, the question has become
what control CDB WRITE underflow cases should we allow..?

The point with this patch is when a host is sending a underflow with a
iscsi immediate data payload that exceeds SCSI transfer length, it's a
bogus request with a garbage payload.  It's a garbage payload because
the SCSI CDB itself obviously doesn't want anything to do it.

I'm very dubious of any host environment who's trying to do this for any
CDB, and expects achieve expected results.

Of course, since v4.3+ normal overflow where SCSI transfer length
matches the iscsi immediate data payload just works with or without this
patch.

So to that extent, I'm going to push this patch as a defensive fix for
v4.3+, to let those imaginary iscsi host environments know they being
very, very naughty.

>  Please note that a fix that is
> compliant with the iSCSI RFC is present in the following patch series: [PATCH
> 00/33] SCSI target driver patches for kernel v4.13, 23 May 2017
> (https://www.spinics.net/lists/target-devel/msg15370.html).

So I might still consider this as a v4.13-rc item for control CDB
underflow, but no way as stable material.

Also, there is certainly no way I'm going to allow a patch to randomly
enable underflow/overflow for all WRITE non control CDBs tree-wide
across all fabric drivers, because 1) no host environments actually care
about this, and 2) it's still dangerous to do for all fabrics without
some serious auditing.



Re: [PATCH 2/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK

2017-06-08 Thread Nicholas A. Bellinger
On Mon, 2017-06-05 at 15:57 +, Bart Van Assche wrote:
> On Sat, 2017-06-03 at 22:10 +0000, Nicholas A. Bellinger wrote:
> > +static bool target_lookup_lun_from_tag(struct se_session *se_sess, u64 tag,
> > +  u64 *unpacked_lun)
> > +{
> > +   struct se_cmd *se_cmd;
> > +   unsigned long flags;
> > +   bool ret = false;
> > +
> > +   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
> > +   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
> > +   if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
> > +   continue;
> > +
> > +   if (se_cmd->tag == tag) {
> > +   *unpacked_lun = se_cmd->orig_fe_lun;
> > +   ret = true;
> > +   break;
> > +   }
> > +   }
> > +   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
> > +
> > +   return ret;
> > +}
> > +
> >  /**
> >   * target_submit_tmr - lookup unpacked lun and submit uninitialized se_cmd
> >   * for TMR CDBs
> > @@ -1639,19 +1662,31 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct 
> > se_session *se_sess,
> > core_tmr_release_req(se_cmd->se_tmr_req);
> > return ret;
> > }
> > +   /*
> > +* If this is ABORT_TASK with no explicit fabric provided LUN,
> > +* go ahead and search active session tags for a match to figure
> > +* out unpacked_lun for the original se_cmd.
> > +*/
> > +   if (tm_type == TMR_ABORT_TASK && (flags & 
> > TARGET_SCF_LOOKUP_LUN_FROM_TAG)) {
> > +   if (!target_lookup_lun_from_tag(se_sess, tag, _lun))
> > +   goto failure;
> > +   }
> >  
> > ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun);
> > -   if (ret) {
> > -   /*
> > -* For callback during failure handling, push this work off
> > -* to process context with TMR_LUN_DOES_NOT_EXIST status.
> > -*/
> > -   INIT_WORK(_cmd->work, target_complete_tmr_failure);
> > -   schedule_work(_cmd->work);
> > -   return 0;
> > -   }
> > +   if (ret)
> > +   goto failure;
> > +
> > transport_generic_handle_tmr(se_cmd);
> > return 0;
> 
> Hello Nic,
> 
> So after LUN lookup has finished sess_cmd_lock lock is dropped, a context
> switch occurs due to the queue_work() call in transport_generic_handle_tmr()
> and next core_tmr_abort_task() reacquires that lock? Sorry but I'm afraid
> that if after that lock is dropped and before it is reacquired a command
> finishes and the initiator reuses the same tag for another command for the
> same LUN that this may result in the wrong command being aborted.

This is only getting a unpacked_lun to determine where the incoming
ABORT_TASK should perform a se_lun lookup and percpu ref upon.

The scenario you are talking about would require a tag be reused on the
same session for the same device between when the ABORT_TASK is
dispatched here, and actually processed.

Because qla2xxx doesn't reuse tags, it's not a problem since it's the
only consumer of TARGET_SCF_LOOKUP_LUN_FROM_TAG.

Since Himanshu and Quinn are OK it with, I'm OK with it.

If you have another driver that needs to use this logic where an
ABORT_TASK doesn't know the unpacked_lun to reference, and does reuse
tags then I'd consider a patch for that.



Re: [PATCH 2/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK

2017-06-08 Thread Nicholas A. Bellinger
On Mon, 2017-06-05 at 15:57 +, Bart Van Assche wrote:
> On Sat, 2017-06-03 at 22:10 +0000, Nicholas A. Bellinger wrote:
> > +static bool target_lookup_lun_from_tag(struct se_session *se_sess, u64 tag,
> > +  u64 *unpacked_lun)
> > +{
> > +   struct se_cmd *se_cmd;
> > +   unsigned long flags;
> > +   bool ret = false;
> > +
> > +   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
> > +   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
> > +   if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
> > +   continue;
> > +
> > +   if (se_cmd->tag == tag) {
> > +   *unpacked_lun = se_cmd->orig_fe_lun;
> > +   ret = true;
> > +   break;
> > +   }
> > +   }
> > +   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
> > +
> > +   return ret;
> > +}
> > +
> >  /**
> >   * target_submit_tmr - lookup unpacked lun and submit uninitialized se_cmd
> >   * for TMR CDBs
> > @@ -1639,19 +1662,31 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct 
> > se_session *se_sess,
> > core_tmr_release_req(se_cmd->se_tmr_req);
> > return ret;
> > }
> > +   /*
> > +* If this is ABORT_TASK with no explicit fabric provided LUN,
> > +* go ahead and search active session tags for a match to figure
> > +* out unpacked_lun for the original se_cmd.
> > +*/
> > +   if (tm_type == TMR_ABORT_TASK && (flags & 
> > TARGET_SCF_LOOKUP_LUN_FROM_TAG)) {
> > +   if (!target_lookup_lun_from_tag(se_sess, tag, _lun))
> > +   goto failure;
> > +   }
> >  
> > ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun);
> > -   if (ret) {
> > -   /*
> > -* For callback during failure handling, push this work off
> > -* to process context with TMR_LUN_DOES_NOT_EXIST status.
> > -*/
> > -   INIT_WORK(_cmd->work, target_complete_tmr_failure);
> > -   schedule_work(_cmd->work);
> > -   return 0;
> > -   }
> > +   if (ret)
> > +   goto failure;
> > +
> > transport_generic_handle_tmr(se_cmd);
> > return 0;
> 
> Hello Nic,
> 
> So after LUN lookup has finished sess_cmd_lock lock is dropped, a context
> switch occurs due to the queue_work() call in transport_generic_handle_tmr()
> and next core_tmr_abort_task() reacquires that lock? Sorry but I'm afraid
> that if after that lock is dropped and before it is reacquired a command
> finishes and the initiator reuses the same tag for another command for the
> same LUN that this may result in the wrong command being aborted.

This is only getting a unpacked_lun to determine where the incoming
ABORT_TASK should perform a se_lun lookup and percpu ref upon.

The scenario you are talking about would require a tag be reused on the
same session for the same device between when the ABORT_TASK is
dispatched here, and actually processed.

Because qla2xxx doesn't reuse tags, it's not a problem since it's the
only consumer of TARGET_SCF_LOOKUP_LUN_FROM_TAG.

Since Himanshu and Quinn are OK it with, I'm OK with it.

If you have another driver that needs to use this logic where an
ABORT_TASK doesn't know the unpacked_lun to reference, and does reuse
tags then I'd consider a patch for that.



Re: [PATCH 0/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support

2017-06-08 Thread Nicholas A. Bellinger
Hi Himanshu & Quinn,

On Wed, 2017-06-07 at 05:02 +, Madhani, Himanshu wrote:
> > On Jun 3, 2017, at 3:10 PM, Nicholas A. Bellinger <n...@linux-iscsi.org> 
> > wrote:
> > 
> > From: Nicholas Bellinger <n...@linux-iscsi.org>
> > 
> > Hi Himanshu + Quinn,
> > 
> > Here is a small series to introduce proper percpu se_lun->lun_ref
> > counting for TMR, and add common code in target_submit_tmr() to
> > do tag lookup for unpacked_lun in order to drop the original
> > driver specific lookup within __qlt_24xx_handle_abts().
> > 
> > It's rather straight-forward, so review and test as a v4.13 item.
> > 
> > Thanks!
> > 
> > Nicholas Bellinger (3):
> >  target: Add support for TMR percpu reference counting
> >  target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK
> >  qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG
> > 
> > drivers/scsi/qla2xxx/qla_target.c  | 39 ++-
> > drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 ++-
> > drivers/target/target_core_device.c| 14 ++---
> > drivers/target/target_core_transport.c | 56 
> > --
> > include/target/target_core_base.h  |  3 +-
> > 5 files changed, 71 insertions(+), 45 deletions(-)
> > 
> > -- 
> > 1.9.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe target-devel" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> Series looks good. 
> 
> Acked-by: Himanshu Madhani <himanshu.madh...@cavium.com>
> 

Thanks for the review! 



Re: [PATCH 0/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support

2017-06-08 Thread Nicholas A. Bellinger
Hi Himanshu & Quinn,

On Wed, 2017-06-07 at 05:02 +, Madhani, Himanshu wrote:
> > On Jun 3, 2017, at 3:10 PM, Nicholas A. Bellinger  
> > wrote:
> > 
> > From: Nicholas Bellinger 
> > 
> > Hi Himanshu + Quinn,
> > 
> > Here is a small series to introduce proper percpu se_lun->lun_ref
> > counting for TMR, and add common code in target_submit_tmr() to
> > do tag lookup for unpacked_lun in order to drop the original
> > driver specific lookup within __qlt_24xx_handle_abts().
> > 
> > It's rather straight-forward, so review and test as a v4.13 item.
> > 
> > Thanks!
> > 
> > Nicholas Bellinger (3):
> >  target: Add support for TMR percpu reference counting
> >  target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK
> >  qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG
> > 
> > drivers/scsi/qla2xxx/qla_target.c  | 39 ++-
> > drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 ++-
> > drivers/target/target_core_device.c| 14 ++---
> > drivers/target/target_core_transport.c | 56 
> > --
> > include/target/target_core_base.h  |  3 +-
> > 5 files changed, 71 insertions(+), 45 deletions(-)
> > 
> > -- 
> > 1.9.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe target-devel" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> Series looks good. 
> 
> Acked-by: Himanshu Madhani 
> 

Thanks for the review! 



Re: [PATCH] iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP

2017-06-08 Thread Nicholas A. Bellinger
Reviews pretty please..?

On Sat, 2017-06-03 at 21:32 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <n...@linux-iscsi.org>
> 
> This patch fixes a BUG() in iscsit_close_session() that could be
> triggered when iscsit_logout_post_handler() execution from within
> tx thread context was not run for more than SECONDS_FOR_LOGOUT_COMP
> (15 seconds), and the TCP connection didn't already close before
> then forcing tx thread context to automatically exit.
> 
> This would manifest itself during explicit logout as:
> 
> [33206.974254] 1 connection(s) still exist for iSCSI session to 
> iqn.1993-08.org.debian:01:3f5523242179
> [33206.980184] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
> 2100.772 msecs
> [33209.078643] [ cut here ]
> [33209.078646] kernel BUG at drivers/target/iscsi/iscsi_target.c:4346!
> 
> Normally when explicit logout attempt fails, the tx thread context
> exits and iscsit_close_connection() from rx thread context does the
> extra cleanup once it detects conn->conn_logout_remove has not been
> cleared by the logout type specific post handlers.
> 
> To address this special case, if the logout post handler in tx thread
> context detects conn->tx_thread_active has already been cleared, simply
> return and exit in order for existing iscsit_close_connection()
> logic from rx thread context do failed logout cleanup.
> 
> Reported-by: Bart Van Assche <bart.vanass...@sandisk.com>
> Cc: Mike Christie <mchri...@redhat.com>
> Cc: Hannes Reinecke <h...@suse.de>
> Cc: Sagi Grimberg <sa...@mellanox.com>
> Cc: sta...@vger.kernel.org # 3.14+
> Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
> ---
>  drivers/target/iscsi/iscsi_target.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target.c 
> b/drivers/target/iscsi/iscsi_target.c
> index 0d8f815..c025451 100644
> --- a/drivers/target/iscsi/iscsi_target.c
> +++ b/drivers/target/iscsi/iscsi_target.c
> @@ -4423,8 +4423,11 @@ static void iscsit_logout_post_handler_closesession(
>* always sleep waiting for RX/TX thread shutdown to complete
>* within iscsit_close_connection().
>*/
> - if (!conn->conn_transport->rdma_shutdown)
> + if (!conn->conn_transport->rdma_shutdown) {
>   sleep = cmpxchg(>tx_thread_active, true, false);
> + if (!sleep)
> + return;
> + }
>  
>   atomic_set(>conn_logout_remove, 0);
>   complete(>conn_logout_comp);
> @@ -4440,8 +4443,11 @@ static void iscsit_logout_post_handler_samecid(
>  {
>   int sleep = 1;
>  
> - if (!conn->conn_transport->rdma_shutdown)
> + if (!conn->conn_transport->rdma_shutdown) {
>   sleep = cmpxchg(>tx_thread_active, true, false);
> + if (!sleep)
> + return;
> + }
>  
>   atomic_set(>conn_logout_remove, 0);
>   complete(>conn_logout_comp);




Re: [PATCH] iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP

2017-06-08 Thread Nicholas A. Bellinger
Reviews pretty please..?

On Sat, 2017-06-03 at 21:32 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger 
> 
> This patch fixes a BUG() in iscsit_close_session() that could be
> triggered when iscsit_logout_post_handler() execution from within
> tx thread context was not run for more than SECONDS_FOR_LOGOUT_COMP
> (15 seconds), and the TCP connection didn't already close before
> then forcing tx thread context to automatically exit.
> 
> This would manifest itself during explicit logout as:
> 
> [33206.974254] 1 connection(s) still exist for iSCSI session to 
> iqn.1993-08.org.debian:01:3f5523242179
> [33206.980184] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
> 2100.772 msecs
> [33209.078643] [ cut here ]
> [33209.078646] kernel BUG at drivers/target/iscsi/iscsi_target.c:4346!
> 
> Normally when explicit logout attempt fails, the tx thread context
> exits and iscsit_close_connection() from rx thread context does the
> extra cleanup once it detects conn->conn_logout_remove has not been
> cleared by the logout type specific post handlers.
> 
> To address this special case, if the logout post handler in tx thread
> context detects conn->tx_thread_active has already been cleared, simply
> return and exit in order for existing iscsit_close_connection()
> logic from rx thread context do failed logout cleanup.
> 
> Reported-by: Bart Van Assche 
> Cc: Mike Christie 
> Cc: Hannes Reinecke 
> Cc: Sagi Grimberg 
> Cc: sta...@vger.kernel.org # 3.14+
> Signed-off-by: Nicholas Bellinger 
> ---
>  drivers/target/iscsi/iscsi_target.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target.c 
> b/drivers/target/iscsi/iscsi_target.c
> index 0d8f815..c025451 100644
> --- a/drivers/target/iscsi/iscsi_target.c
> +++ b/drivers/target/iscsi/iscsi_target.c
> @@ -4423,8 +4423,11 @@ static void iscsit_logout_post_handler_closesession(
>* always sleep waiting for RX/TX thread shutdown to complete
>* within iscsit_close_connection().
>*/
> - if (!conn->conn_transport->rdma_shutdown)
> + if (!conn->conn_transport->rdma_shutdown) {
>   sleep = cmpxchg(>tx_thread_active, true, false);
> + if (!sleep)
> + return;
> + }
>  
>   atomic_set(>conn_logout_remove, 0);
>   complete(>conn_logout_comp);
> @@ -4440,8 +4443,11 @@ static void iscsit_logout_post_handler_samecid(
>  {
>   int sleep = 1;
>  
> - if (!conn->conn_transport->rdma_shutdown)
> + if (!conn->conn_transport->rdma_shutdown) {
>   sleep = cmpxchg(>tx_thread_active, true, false);
> + if (!sleep)
> + return;
> + }
>  
>   atomic_set(>conn_logout_remove, 0);
>   complete(>conn_logout_comp);




Re: [PATCH] target: Fix kref->refcount underflow in transport_cmd_finish_abort

2017-06-08 Thread Nicholas A. Bellinger
(Adding Quinn CC')

Reviews please..?

On Sat, 2017-06-03 at 21:09 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <n...@linux-iscsi.org>
> 
> This patch fixes a se_cmd->cmd_kref underflow during CMD_T_ABORTED
> when a fabric driver drops it's second reference from below the
> target_core_tmr.c based callers of transport_cmd_finish_abort().
> 
> Recently with the conversion of kref to refcount_t, this bug was
> manifesting itself as:
> 
> [705519.601034] refcount_t: underflow; use-after-free.
> [705519.604034] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
> 20116.512 msecs
> [705539.719111] [ cut here ]
> [705539.719117] WARNING: CPU: 3 PID: 26510 at lib/refcount.c:184 
> refcount_sub_and_test+0x33/0x51
> 
> Since the original kref atomic_t based kref_put() didn't check for
> underflow and only invoked the final callback when zero was reached,
> this bug did not manifest in practice since all se_cmd memory is
> using preallocated tags.
> 
> To address this, go ahead and propigate the existing return from
> transport_put_cmd() up via transport_cmd_finish_abort(), and
> change transport_cmd_finish_abort() + core_tmr_handle_tas_abort()
> callers to only do their local target_put_sess_cmd() if necessary.
> 
> Reported-by: Bart Van Assche <bart.vanass...@sandisk.com>
> Cc: Mike Christie <mchri...@redhat.com>
> Cc: Hannes Reinecke <h...@suse.de>
> Cc: Christoph Hellwig <h...@lst.de>
> Cc: Himanshu Madhani <himanshu.madh...@qlogic.com>
> Cc: Sagi Grimberg <sa...@mellanox.com>
> Cc: sta...@vger.kernel.org # 3.14+
> Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
> ---
>  drivers/target/target_core_internal.h  |  2 +-
>  drivers/target/target_core_tmr.c   | 16 
>  drivers/target/target_core_transport.c |  9 ++---
>  3 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/target/target_core_internal.h 
> b/drivers/target/target_core_internal.h
> index 9ab7090..0912de7 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -136,7 +136,7 @@ struct se_node_acl 
> *core_tpg_add_initiator_node_acl(struct se_portal_group *tpg,
>  void release_se_kmem_caches(void);
>  u32  scsi_get_new_index(scsi_index_t);
>  void transport_subsystem_check_init(void);
> -void transport_cmd_finish_abort(struct se_cmd *, int);
> +int  transport_cmd_finish_abort(struct se_cmd *, int);
>  unsigned char *transport_dump_cmd_direction(struct se_cmd *);
>  void transport_dump_dev_state(struct se_device *, char *, int *);
>  void transport_dump_dev_info(struct se_device *, struct se_lun *,
> diff --git a/drivers/target/target_core_tmr.c 
> b/drivers/target/target_core_tmr.c
> index dce1e1b..13f47bf 100644
> --- a/drivers/target/target_core_tmr.c
> +++ b/drivers/target/target_core_tmr.c
> @@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
>   kfree(tmr);
>  }
>  
> -static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
> +static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
>  {
>   unsigned long flags;
>   bool remove = true, send_tas;
> @@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, 
> int tas)
>   transport_send_task_abort(cmd);
>   }
>  
> - transport_cmd_finish_abort(cmd, remove);
> + return transport_cmd_finish_abort(cmd, remove);
>  }
>  
>  static int target_check_cdb_and_preempt(struct list_head *list,
> @@ -184,8 +184,8 @@ void core_tmr_abort_task(
>   cancel_work_sync(_cmd->work);
>   transport_wait_for_tasks(se_cmd);
>  
> - transport_cmd_finish_abort(se_cmd, true);
> - target_put_sess_cmd(se_cmd);
> + if (!transport_cmd_finish_abort(se_cmd, true))
> + target_put_sess_cmd(se_cmd);
>  
>   printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
>   " ref_tag: %llu\n", ref_tag);
> @@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
>   cancel_work_sync(>work);
>   transport_wait_for_tasks(cmd);
>  
> - transport_cmd_finish_abort(cmd, 1);
> - target_put_sess_cmd(cmd);
> + if (!transport_cmd_finish_abort(cmd, 1))
> + target_put_sess_cmd(cmd);
>   }
>  }
>  
> @@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
>   cancel_work_sync(>work);
>   transport_wait_for_tasks(cmd);
>  
> - core_tmr_handle_tas_abort(cmd, tas);
> - targe

Re: [PATCH] target: Fix kref->refcount underflow in transport_cmd_finish_abort

2017-06-08 Thread Nicholas A. Bellinger
(Adding Quinn CC')

Reviews please..?

On Sat, 2017-06-03 at 21:09 +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger 
> 
> This patch fixes a se_cmd->cmd_kref underflow during CMD_T_ABORTED
> when a fabric driver drops it's second reference from below the
> target_core_tmr.c based callers of transport_cmd_finish_abort().
> 
> Recently with the conversion of kref to refcount_t, this bug was
> manifesting itself as:
> 
> [705519.601034] refcount_t: underflow; use-after-free.
> [705519.604034] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
> 20116.512 msecs
> [705539.719111] [ cut here ]
> [705539.719117] WARNING: CPU: 3 PID: 26510 at lib/refcount.c:184 
> refcount_sub_and_test+0x33/0x51
> 
> Since the original kref atomic_t based kref_put() didn't check for
> underflow and only invoked the final callback when zero was reached,
> this bug did not manifest in practice since all se_cmd memory is
> using preallocated tags.
> 
> To address this, go ahead and propigate the existing return from
> transport_put_cmd() up via transport_cmd_finish_abort(), and
> change transport_cmd_finish_abort() + core_tmr_handle_tas_abort()
> callers to only do their local target_put_sess_cmd() if necessary.
> 
> Reported-by: Bart Van Assche 
> Cc: Mike Christie 
> Cc: Hannes Reinecke 
> Cc: Christoph Hellwig 
> Cc: Himanshu Madhani 
> Cc: Sagi Grimberg 
> Cc: sta...@vger.kernel.org # 3.14+
> Signed-off-by: Nicholas Bellinger 
> ---
>  drivers/target/target_core_internal.h  |  2 +-
>  drivers/target/target_core_tmr.c   | 16 
>  drivers/target/target_core_transport.c |  9 ++---
>  3 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/target/target_core_internal.h 
> b/drivers/target/target_core_internal.h
> index 9ab7090..0912de7 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -136,7 +136,7 @@ struct se_node_acl 
> *core_tpg_add_initiator_node_acl(struct se_portal_group *tpg,
>  void release_se_kmem_caches(void);
>  u32  scsi_get_new_index(scsi_index_t);
>  void transport_subsystem_check_init(void);
> -void transport_cmd_finish_abort(struct se_cmd *, int);
> +int  transport_cmd_finish_abort(struct se_cmd *, int);
>  unsigned char *transport_dump_cmd_direction(struct se_cmd *);
>  void transport_dump_dev_state(struct se_device *, char *, int *);
>  void transport_dump_dev_info(struct se_device *, struct se_lun *,
> diff --git a/drivers/target/target_core_tmr.c 
> b/drivers/target/target_core_tmr.c
> index dce1e1b..13f47bf 100644
> --- a/drivers/target/target_core_tmr.c
> +++ b/drivers/target/target_core_tmr.c
> @@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
>   kfree(tmr);
>  }
>  
> -static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
> +static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
>  {
>   unsigned long flags;
>   bool remove = true, send_tas;
> @@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, 
> int tas)
>   transport_send_task_abort(cmd);
>   }
>  
> - transport_cmd_finish_abort(cmd, remove);
> + return transport_cmd_finish_abort(cmd, remove);
>  }
>  
>  static int target_check_cdb_and_preempt(struct list_head *list,
> @@ -184,8 +184,8 @@ void core_tmr_abort_task(
>   cancel_work_sync(_cmd->work);
>   transport_wait_for_tasks(se_cmd);
>  
> - transport_cmd_finish_abort(se_cmd, true);
> - target_put_sess_cmd(se_cmd);
> + if (!transport_cmd_finish_abort(se_cmd, true))
> + target_put_sess_cmd(se_cmd);
>  
>   printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
>   " ref_tag: %llu\n", ref_tag);
> @@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
>   cancel_work_sync(>work);
>   transport_wait_for_tasks(cmd);
>  
> - transport_cmd_finish_abort(cmd, 1);
> - target_put_sess_cmd(cmd);
> + if (!transport_cmd_finish_abort(cmd, 1))
> + target_put_sess_cmd(cmd);
>   }
>  }
>  
> @@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
>   cancel_work_sync(>work);
>   transport_wait_for_tasks(cmd);
>  
> - core_tmr_handle_tas_abort(cmd, tas);
> - target_put_sess_cmd(cmd);
> + if (!core_tmr_handle_tas_abort(cmd, tas))
> + target_put_sess_cmd(cmd);
>   }
>  }
>  
> diff --git a/drivers/target/target_core_transpo

[PATCH] configfs: Fix race between create_link and configfs_rmdir

2017-06-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch closes a long standing race in configfs between
the creation of a new symlink in create_link(), while the
symlink target's config_item is being concurrently removed
via configfs_rmdir().

This can happen because the symlink target's reference
is obtained by config_item_get() in create_link() before
the CONFIGFS_USET_DROPPING bit set by configfs_detach_prep()
during configfs_rmdir() shutdown is actually checked..

This originally manifested itself on ppc64 on v4.8.y under
heavy load using ibmvscsi target ports with Novalink API:

[ 7877.289863] rpadlpar_io: slot U8247.22L.212A91A-V1-C8 added
[ 7879.893760] [ cut here ]
[ 7879.893768] WARNING: CPU: 15 PID: 17585 at ./include/linux/kref.h:46 
config_item_get+0x7c/0x90 [configfs]
[ 7879.893811] CPU: 15 PID: 17585 Comm: targetcli Tainted: G   O 
4.8.17-customv2.22 #12
[ 7879.893812] task: c0018a0d3400 task.stack: c001f3b4
[ 7879.893813] NIP: d2c664ec LR: d2c60980 CTR: c0b70870
[ 7879.893814] REGS: c001f3b43810 TRAP: 0700   Tainted: G O 
(4.8.17-customv2.22)
[ 7879.893815] MSR: 80029033 <SF,EE,ME,IR,DR,RI,LE>  CR: 2842  XER: 

[ 7879.893820] CFAR: d2c664bc SOFTE: 1
GPR00: d2c60980 c001f3b43a90 d2c70908 
c000fbc06820
GPR04: c001ef1bd900 0004 0001 

GPR08:  0001 d2c69560 
d2c66d80
GPR12: c0b70870 ce798700 c001f3b43ca0 
c001d4949d40
GPR16: c0014637e1c0   
c000f2392940
GPR20: c001f3b43b98 0041 0060 

GPR24: f000  d2c60be0 
c001f1dac490
GPR28: 0004  c001ef1bd900 
c000f2392940
[ 7879.893839] NIP [d2c664ec] config_item_get+0x7c/0x90 [configfs]
[ 7879.893841] LR [d2c60980] check_perm+0x80/0x2e0 [configfs]
[ 7879.893842] Call Trace:
[ 7879.893844] [c001f3b43ac0] [d2c60980] check_perm+0x80/0x2e0 
[configfs]
[ 7879.893847] [c001f3b43b10] [c0329770] do_dentry_open+0x2c0/0x460
[ 7879.893849] [c001f3b43b70] [c0344480] path_openat+0x210/0x1490
[ 7879.893851] [c001f3b43c80] [c034708c] do_filp_open+0xfc/0x170
[ 7879.893853] [c001f3b43db0] [c032b5bc] do_sys_open+0x1cc/0x390
[ 7879.893856] [c001f3b43e30] [c0009584] system_call+0x38/0xec
[ 7879.893856] Instruction dump:
[ 7879.893858] 409d0014 38210030 e8010010 7c0803a6 4e800020 3d22 e94981e0 
892a
[ 7879.893861] 2f89 409effe0 3921 992a <0fe0> 4bd0 6000 
6000
[ 7879.893866] ---[ end trace 14078f0b3b5ad0aa ]---

To close this race, go ahead and obtain the symlink's target
config_item reference only after the existing CONFIGFS_USET_DROPPING
check succeeds.

This way, if configfs_rmdir() wins create_link() will return -ENONET,
and if create_link() wins configfs_rmdir() will return -EBUSY.

Reported-by: Bryant G. Ly <bryan...@linux.vnet.ibm.com>
Tested-by: Bryant G. Ly <bryan...@linux.vnet.ibm.com>
Cc: Bryant G. Ly <bryan...@linux.vnet.ibm.com>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Joel Becker <jl...@evilplan.org>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 fs/configfs/symlink.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index a6ab012..c8aabba 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
ret = -ENOMEM;
sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
if (sl) {
-   sl->sl_target = config_item_get(item);
spin_lock(_dirent_lock);
if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
spin_unlock(_dirent_lock);
-   config_item_put(item);
kfree(sl);
return -ENOENT;
}
+   sl->sl_target = config_item_get(item);
list_add(>sl_list, _sd->s_links);
spin_unlock(_dirent_lock);
ret = configfs_create_link(sl, parent_item->ci_dentry,
-- 
1.9.1



[PATCH] configfs: Fix race between create_link and configfs_rmdir

2017-06-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch closes a long standing race in configfs between
the creation of a new symlink in create_link(), while the
symlink target's config_item is being concurrently removed
via configfs_rmdir().

This can happen because the symlink target's reference
is obtained by config_item_get() in create_link() before
the CONFIGFS_USET_DROPPING bit set by configfs_detach_prep()
during configfs_rmdir() shutdown is actually checked..

This originally manifested itself on ppc64 on v4.8.y under
heavy load using ibmvscsi target ports with Novalink API:

[ 7877.289863] rpadlpar_io: slot U8247.22L.212A91A-V1-C8 added
[ 7879.893760] [ cut here ]
[ 7879.893768] WARNING: CPU: 15 PID: 17585 at ./include/linux/kref.h:46 
config_item_get+0x7c/0x90 [configfs]
[ 7879.893811] CPU: 15 PID: 17585 Comm: targetcli Tainted: G   O 
4.8.17-customv2.22 #12
[ 7879.893812] task: c0018a0d3400 task.stack: c001f3b4
[ 7879.893813] NIP: d2c664ec LR: d2c60980 CTR: c0b70870
[ 7879.893814] REGS: c001f3b43810 TRAP: 0700   Tainted: G O 
(4.8.17-customv2.22)
[ 7879.893815] MSR: 80029033   CR: 2842  XER: 

[ 7879.893820] CFAR: d2c664bc SOFTE: 1
GPR00: d2c60980 c001f3b43a90 d2c70908 
c000fbc06820
GPR04: c001ef1bd900 0004 0001 

GPR08:  0001 d2c69560 
d2c66d80
GPR12: c0b70870 ce798700 c001f3b43ca0 
c001d4949d40
GPR16: c0014637e1c0   
c000f2392940
GPR20: c001f3b43b98 0041 0060 

GPR24: f000  d2c60be0 
c001f1dac490
GPR28: 0004  c001ef1bd900 
c000f2392940
[ 7879.893839] NIP [d2c664ec] config_item_get+0x7c/0x90 [configfs]
[ 7879.893841] LR [d2c60980] check_perm+0x80/0x2e0 [configfs]
[ 7879.893842] Call Trace:
[ 7879.893844] [c001f3b43ac0] [d2c60980] check_perm+0x80/0x2e0 
[configfs]
[ 7879.893847] [c001f3b43b10] [c0329770] do_dentry_open+0x2c0/0x460
[ 7879.893849] [c001f3b43b70] [c0344480] path_openat+0x210/0x1490
[ 7879.893851] [c001f3b43c80] [c034708c] do_filp_open+0xfc/0x170
[ 7879.893853] [c001f3b43db0] [c032b5bc] do_sys_open+0x1cc/0x390
[ 7879.893856] [c001f3b43e30] [c0009584] system_call+0x38/0xec
[ 7879.893856] Instruction dump:
[ 7879.893858] 409d0014 38210030 e8010010 7c0803a6 4e800020 3d22 e94981e0 
892a
[ 7879.893861] 2f89 409effe0 3921 992a <0fe0> 4bd0 6000 
6000
[ 7879.893866] ---[ end trace 14078f0b3b5ad0aa ]---

To close this race, go ahead and obtain the symlink's target
config_item reference only after the existing CONFIGFS_USET_DROPPING
check succeeds.

This way, if configfs_rmdir() wins create_link() will return -ENONET,
and if create_link() wins configfs_rmdir() will return -EBUSY.

Reported-by: Bryant G. Ly 
Tested-by: Bryant G. Ly 
Cc: Bryant G. Ly 
Cc: Christoph Hellwig 
Cc: Joel Becker 
Signed-off-by: Nicholas Bellinger 
---
 fs/configfs/symlink.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index a6ab012..c8aabba 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
ret = -ENOMEM;
sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
if (sl) {
-   sl->sl_target = config_item_get(item);
spin_lock(_dirent_lock);
if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
spin_unlock(_dirent_lock);
-   config_item_put(item);
kfree(sl);
return -ENOENT;
}
+   sl->sl_target = config_item_get(item);
list_add(>sl_list, _sd->s_links);
spin_unlock(_dirent_lock);
ret = configfs_create_link(sl, parent_item->ci_dentry,
-- 
1.9.1



[PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-06-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

When iscsi WRITE underflow occurs there are two different scenarios
that can happen.

Normally in practice, when an EDTL vs. SCSI CDB TRANSFER LENGTH
underflow is detected, the iscsi immediate data payload is the
smaller SCSI CDB TRANSFER LENGTH.

That is, when a host fabric LLD is using a fixed size EDTL for
a specific control CDB, the SCSI CDB TRANSFER LENGTH and actual
SCSI payload ends up being smaller than EDTL.  In iscsi, this
means the received iscsi immediate data payload matches the
smaller SCSI CDB TRANSFER LENGTH, because there is no more
SCSI payload to accept beyond SCSI CDB TRANSFER LENGTH.

However, it's possible for a malicous host to send a WRITE
underflow where EDTL is larger than SCSI CDB TRANSFER LENGTH,
but incoming iscsi immediate data actually matches EDTL.

In the wild, we've never had a iscsi host environment actually
try to do this.

For this special case, it's wrong to truncate part of the
control CDB payload and continue to process the command during
underflow when immediate data payload received was larger than
SCSI CDB TRANSFER LENGTH, so go ahead and reject and drop the
bogus payload as a defensive action.

Note this potential bug was originally relaxed by the following
for allowing WRITE underflow in MSFT FCP host environments:

   commit c72c5250224d475614a00c1d7e54a67f77cd3410
   Author: Roland Dreier <rol...@purestorage.com>
   Date:   Wed Jul 22 15:08:18 2015 -0700

  target: allow underflow/overflow for PR OUT etc. commands

Cc: Roland Dreier <rol...@purestorage.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.de>
Cc: Martin K. Petersen <martin.peter...@oracle.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index c025451..3fdca2c 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1279,6 +1279,18 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, 
struct iscsi_cmd *cmd,
 */
if (dump_payload)
goto after_immediate_data;
+   /*
+* Check for underflow case where both EDTL and immediate data payload
+* exceeds what is presented by CDB's TRANSFER LENGTH, and what has
+* already been set in target_cmd_size_check() as se_cmd->data_length.
+*
+* For this special case, fail the command and dump the immediate data
+* payload.
+*/
+   if (cmd->first_burst_len > cmd->se_cmd.data_length) {
+   cmd->sense_reason = TCM_INVALID_CDB_FIELD;
+   goto after_immediate_data;
+   }
 
immed_ret = iscsit_handle_immediate_data(cmd, hdr,
cmd->first_burst_len);
-- 
1.9.1



[PATCH] iscsi-target: Reject immediate data underflow larger than SCSI transfer length

2017-06-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

When iscsi WRITE underflow occurs there are two different scenarios
that can happen.

Normally in practice, when an EDTL vs. SCSI CDB TRANSFER LENGTH
underflow is detected, the iscsi immediate data payload is the
smaller SCSI CDB TRANSFER LENGTH.

That is, when a host fabric LLD is using a fixed size EDTL for
a specific control CDB, the SCSI CDB TRANSFER LENGTH and actual
SCSI payload ends up being smaller than EDTL.  In iscsi, this
means the received iscsi immediate data payload matches the
smaller SCSI CDB TRANSFER LENGTH, because there is no more
SCSI payload to accept beyond SCSI CDB TRANSFER LENGTH.

However, it's possible for a malicous host to send a WRITE
underflow where EDTL is larger than SCSI CDB TRANSFER LENGTH,
but incoming iscsi immediate data actually matches EDTL.

In the wild, we've never had a iscsi host environment actually
try to do this.

For this special case, it's wrong to truncate part of the
control CDB payload and continue to process the command during
underflow when immediate data payload received was larger than
SCSI CDB TRANSFER LENGTH, so go ahead and reject and drop the
bogus payload as a defensive action.

Note this potential bug was originally relaxed by the following
for allowing WRITE underflow in MSFT FCP host environments:

   commit c72c5250224d475614a00c1d7e54a67f77cd3410
   Author: Roland Dreier 
   Date:   Wed Jul 22 15:08:18 2015 -0700

  target: allow underflow/overflow for PR OUT etc. commands

Cc: Roland Dreier 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Martin K. Petersen 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index c025451..3fdca2c 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1279,6 +1279,18 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, 
struct iscsi_cmd *cmd,
 */
if (dump_payload)
goto after_immediate_data;
+   /*
+* Check for underflow case where both EDTL and immediate data payload
+* exceeds what is presented by CDB's TRANSFER LENGTH, and what has
+* already been set in target_cmd_size_check() as se_cmd->data_length.
+*
+* For this special case, fail the command and dump the immediate data
+* payload.
+*/
+   if (cmd->first_burst_len > cmd->se_cmd.data_length) {
+   cmd->sense_reason = TCM_INVALID_CDB_FIELD;
+   goto after_immediate_data;
+   }
 
immed_ret = iscsit_handle_immediate_data(cmd, hdr,
cmd->first_burst_len);
-- 
1.9.1



[PATCH 0/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Hi Himanshu + Quinn,

Here is a small series to introduce proper percpu se_lun->lun_ref
counting for TMR, and add common code in target_submit_tmr() to
do tag lookup for unpacked_lun in order to drop the original
driver specific lookup within __qlt_24xx_handle_abts().

It's rather straight-forward, so review and test as a v4.13 item.

Thanks!

Nicholas Bellinger (3):
  target: Add support for TMR percpu reference counting
  target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK
  qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG

 drivers/scsi/qla2xxx/qla_target.c  | 39 ++-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 ++-
 drivers/target/target_core_device.c| 14 ++---
 drivers/target/target_core_transport.c | 56 --
 include/target/target_core_base.h  |  3 +-
 5 files changed, 71 insertions(+), 45 deletions(-)

-- 
1.9.1



[PATCH 1/3] target: Add support for TMR percpu reference counting

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch introduces TMR percpu reference counting using
se_lun->lun_ref in transport_lookup_tmr_lun(), following
how existing non TMR per se_lun reference counting works
within transport_lookup_cmd_lun().

It also adds explicit transport_lun_remove_cmd() calls to
drop the reference in the three tmr related locations that
invoke transport_cmd_check_stop_to_fabric();

   - target_tmr_work() during normal ->queue_tm_rsp()
   - target_complete_tmr_failure() during error ->queue_tm_rsp()
   - transport_generic_handle_tmr() during early failure

Also, note the exception paths in transport_generic_free_cmd()
and transport_cmd_finish_abort() already check SCF_SE_LUN_CMD,
and will invoke transport_lun_remove_cmd() when necessary.

Cc: Himanshu Madhani <himanshu.madh...@cavium.com>
Cc: Quinn Tran <quinn.t...@cavium.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Christoph Hellwig <h...@lst.de>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_device.c| 14 ++
 drivers/target/target_core_transport.c |  3 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index 8f0e0e3..11c80c4 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -168,11 +168,20 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 
unpacked_lun)
rcu_read_lock();
deve = target_nacl_find_deve(nacl, unpacked_lun);
if (deve) {
-   se_cmd->se_lun = rcu_dereference(deve->se_lun);
se_lun = rcu_dereference(deve->se_lun);
+
+   if (!percpu_ref_tryget_live(_lun->lun_ref)) {
+   se_lun = NULL;
+   goto out_unlock;
+   }
+
+   se_cmd->se_lun = rcu_dereference(deve->se_lun);
se_cmd->pr_res_key = deve->pr_res_key;
se_cmd->orig_fe_lun = unpacked_lun;
+   se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
+   se_cmd->lun_ref_active = true;
}
+out_unlock:
rcu_read_unlock();
 
if (!se_lun) {
@@ -182,9 +191,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 
unpacked_lun)
unpacked_lun);
return -ENODEV;
}
-   /*
-* XXX: Add percpu se_lun->lun_ref reference count for TMR
-*/
se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev);
se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev);
 
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index f16a789..83bfc97 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1588,6 +1588,7 @@ static void target_complete_tmr_failure(struct 
work_struct *work)
se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
se_cmd->se_tfo->queue_tm_rsp(se_cmd);
 
+   transport_lun_remove_cmd(se_cmd);
transport_cmd_check_stop_to_fabric(se_cmd);
 }
 
@@ -3199,6 +3200,7 @@ static void target_tmr_work(struct work_struct *work)
cmd->se_tfo->queue_tm_rsp(cmd);
 
 check_stop:
+   transport_lun_remove_cmd(cmd);
transport_cmd_check_stop_to_fabric(cmd);
 }
 
@@ -3221,6 +3223,7 @@ int transport_generic_handle_tmr(
pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d"
"ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function,
cmd->se_tmr_req->ref_task_tag, cmd->tag);
+   transport_lun_remove_cmd(cmd);
transport_cmd_check_stop_to_fabric(cmd);
return 0;
}
-- 
1.9.1



[PATCH 0/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Hi Himanshu + Quinn,

Here is a small series to introduce proper percpu se_lun->lun_ref
counting for TMR, and add common code in target_submit_tmr() to
do tag lookup for unpacked_lun in order to drop the original
driver specific lookup within __qlt_24xx_handle_abts().

It's rather straight-forward, so review and test as a v4.13 item.

Thanks!

Nicholas Bellinger (3):
  target: Add support for TMR percpu reference counting
  target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK
  qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG

 drivers/scsi/qla2xxx/qla_target.c  | 39 ++-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 ++-
 drivers/target/target_core_device.c| 14 ++---
 drivers/target/target_core_transport.c | 56 --
 include/target/target_core_base.h  |  3 +-
 5 files changed, 71 insertions(+), 45 deletions(-)

-- 
1.9.1



[PATCH 1/3] target: Add support for TMR percpu reference counting

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch introduces TMR percpu reference counting using
se_lun->lun_ref in transport_lookup_tmr_lun(), following
how existing non TMR per se_lun reference counting works
within transport_lookup_cmd_lun().

It also adds explicit transport_lun_remove_cmd() calls to
drop the reference in the three tmr related locations that
invoke transport_cmd_check_stop_to_fabric();

   - target_tmr_work() during normal ->queue_tm_rsp()
   - target_complete_tmr_failure() during error ->queue_tm_rsp()
   - transport_generic_handle_tmr() during early failure

Also, note the exception paths in transport_generic_free_cmd()
and transport_cmd_finish_abort() already check SCF_SE_LUN_CMD,
and will invoke transport_lun_remove_cmd() when necessary.

Cc: Himanshu Madhani 
Cc: Quinn Tran 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_device.c| 14 ++
 drivers/target/target_core_transport.c |  3 +++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index 8f0e0e3..11c80c4 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -168,11 +168,20 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 
unpacked_lun)
rcu_read_lock();
deve = target_nacl_find_deve(nacl, unpacked_lun);
if (deve) {
-   se_cmd->se_lun = rcu_dereference(deve->se_lun);
se_lun = rcu_dereference(deve->se_lun);
+
+   if (!percpu_ref_tryget_live(_lun->lun_ref)) {
+   se_lun = NULL;
+   goto out_unlock;
+   }
+
+   se_cmd->se_lun = rcu_dereference(deve->se_lun);
se_cmd->pr_res_key = deve->pr_res_key;
se_cmd->orig_fe_lun = unpacked_lun;
+   se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
+   se_cmd->lun_ref_active = true;
}
+out_unlock:
rcu_read_unlock();
 
if (!se_lun) {
@@ -182,9 +191,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 
unpacked_lun)
unpacked_lun);
return -ENODEV;
}
-   /*
-* XXX: Add percpu se_lun->lun_ref reference count for TMR
-*/
se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev);
se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev);
 
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index f16a789..83bfc97 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1588,6 +1588,7 @@ static void target_complete_tmr_failure(struct 
work_struct *work)
se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
se_cmd->se_tfo->queue_tm_rsp(se_cmd);
 
+   transport_lun_remove_cmd(se_cmd);
transport_cmd_check_stop_to_fabric(se_cmd);
 }
 
@@ -3199,6 +3200,7 @@ static void target_tmr_work(struct work_struct *work)
cmd->se_tfo->queue_tm_rsp(cmd);
 
 check_stop:
+   transport_lun_remove_cmd(cmd);
transport_cmd_check_stop_to_fabric(cmd);
 }
 
@@ -3221,6 +3223,7 @@ int transport_generic_handle_tmr(
pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d"
"ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function,
cmd->se_tmr_req->ref_task_tag, cmd->tag);
+   transport_lun_remove_cmd(cmd);
transport_cmd_check_stop_to_fabric(cmd);
return 0;
}
-- 
1.9.1



[PATCH 3/3] qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Following Himanshu's earlier patch to drop the redundant tag
lookup within __qlt_24xx_handle_abts(), go ahead and drop this
now QLA_TGT_ABTS can use TARGET_SCF_LOOKUP_LUN_FROM_TAG and
have target_submit_tmr() do this from common code.

Cc: Himanshu Madhani <himanshu.madh...@cavium.com>
Cc: Quinn Tran <quinn.t...@cavium.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Christoph Hellwig <h...@lst.de>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/scsi/qla2xxx/qla_target.c  | 39 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 +++-
 2 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 0e03ca2..401e245 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1847,38 +1847,13 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
struct abts_recv_from_24xx *abts, struct fc_port *sess)
 {
struct qla_hw_data *ha = vha->hw;
-   struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
-   struct se_cmd *se_cmd;
-   u32 lun = 0;
int rc;
-   bool found_lun = false;
-   unsigned long flags;
-
-   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
-   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   struct qla_tgt_cmd *cmd =
-   container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
-   if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   lun = cmd->unpacked_lun;
-   found_lun = true;
-   break;
-   }
-   }
-   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
 
-   /* cmd not in LIO lists, look in qla list */
-   if (!found_lun) {
-   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
-   /* send TASK_ABORT response immediately */
-   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
-   return 0;
-   } else {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
-   "unable to find cmd in driver or LIO for tag 
0x%x\n",
-   abts->exchange_addr_to_abort);
-   return -ENOENT;
-   }
+   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
+   /* send TASK_ABORT response immediately */
+   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
+   return 0;
}
 
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
@@ -1899,7 +1874,11 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+   /*
+* LUN is looked up by target-core internally based on the passed
+* abts->exchange_addr_to_abort tag.
+*/
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 7443e4e..75aeb9f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -601,11 +601,13 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd 
*mcmd, uint32_t lun,
struct fc_port *sess = mcmd->sess;
struct se_cmd *se_cmd = >se_cmd;
int transl_tmr_func = 0;
+   int flags = TARGET_SCF_ACK_KREF;
 
switch (tmr_func) {
case QLA_TGT_ABTS:
pr_debug("%ld: ABTS received\n", sess->vha->host_no);
transl_tmr_func = TMR_ABORT_TASK;
+   flags |= TARGET_SCF_LOOKUP_LUN_FROM_TAG;
break;
case QLA_TGT_2G_ABORT_TASK:
pr_debug("%ld: 2G Abort Task received\n", sess->vha->host_no);
@@ -638,7 +640,7 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd 
*mcmd, uint32_t lun,
}
 
return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd,
-   transl_tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF);
+   transl_tmr_func, GFP_ATOMIC, tag, flags);
 }
 
 static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
-- 
1.9.1



[PATCH 2/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch introduces support in target_submit_tmr() for locating a
unpacked_lun from an existing se_cmd->tag during ABORT_TASK.

When TARGET_SCF_LOOKUP_LUN_FROM_TAG is set, target_submit_tmr()
will do the extra lookup via target_lookup_lun_from_tag() and
subsequently invoke transport_lookup_tmr_lun() so a proper
percpu se_lun->lun_ref is taken before workqueue dispatch into
se_device->tmr_wq happens.

Aside from the extra target_lookup_lun_from_tag(), the existing
code-path remains unchanged.

Cc: Himanshu Madhani <himanshu.madh...@cavium.com>
Cc: Quinn Tran <quinn.t...@cavium.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Christoph Hellwig <h...@lst.de>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_transport.c | 53 --
 include/target/target_core_base.h  |  3 +-
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 83bfc97..dbb8101 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1592,6 +1592,29 @@ static void target_complete_tmr_failure(struct 
work_struct *work)
transport_cmd_check_stop_to_fabric(se_cmd);
 }
 
+static bool target_lookup_lun_from_tag(struct se_session *se_sess, u64 tag,
+  u64 *unpacked_lun)
+{
+   struct se_cmd *se_cmd;
+   unsigned long flags;
+   bool ret = false;
+
+   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
+   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
+   if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+   continue;
+
+   if (se_cmd->tag == tag) {
+   *unpacked_lun = se_cmd->orig_fe_lun;
+   ret = true;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
+
+   return ret;
+}
+
 /**
  * target_submit_tmr - lookup unpacked lun and submit uninitialized se_cmd
  * for TMR CDBs
@@ -1639,19 +1662,31 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct 
se_session *se_sess,
core_tmr_release_req(se_cmd->se_tmr_req);
return ret;
}
+   /*
+* If this is ABORT_TASK with no explicit fabric provided LUN,
+* go ahead and search active session tags for a match to figure
+* out unpacked_lun for the original se_cmd.
+*/
+   if (tm_type == TMR_ABORT_TASK && (flags & 
TARGET_SCF_LOOKUP_LUN_FROM_TAG)) {
+   if (!target_lookup_lun_from_tag(se_sess, tag, _lun))
+   goto failure;
+   }
 
ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun);
-   if (ret) {
-   /*
-* For callback during failure handling, push this work off
-* to process context with TMR_LUN_DOES_NOT_EXIST status.
-*/
-   INIT_WORK(_cmd->work, target_complete_tmr_failure);
-   schedule_work(_cmd->work);
-   return 0;
-   }
+   if (ret)
+   goto failure;
+
transport_generic_handle_tmr(se_cmd);
return 0;
+
+   /*
+* For callback during failure handling, push this work off
+* to process context with TMR_LUN_DOES_NOT_EXIST status.
+*/
+failure:
+   INIT_WORK(_cmd->work, target_complete_tmr_failure);
+   schedule_work(_cmd->work);
+   return 0;
 }
 EXPORT_SYMBOL(target_submit_tmr);
 
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index db2c7b3..a3af69f 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -188,7 +188,8 @@ enum target_sc_flags_table {
TARGET_SCF_BIDI_OP  = 0x01,
TARGET_SCF_ACK_KREF = 0x02,
TARGET_SCF_UNKNOWN_SIZE = 0x04,
-   TARGET_SCF_USE_CPUID= 0x08,
+   TARGET_SCF_USE_CPUID= 0x08,
+   TARGET_SCF_LOOKUP_LUN_FROM_TAG  = 0x10,
 };
 
 /* fabric independent task management function values */
-- 
1.9.1



[PATCH 3/3] qla2xxx: Convert QLA_TGT_ABTS to TARGET_SCF_LOOKUP_LUN_FROM_TAG

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Following Himanshu's earlier patch to drop the redundant tag
lookup within __qlt_24xx_handle_abts(), go ahead and drop this
now QLA_TGT_ABTS can use TARGET_SCF_LOOKUP_LUN_FROM_TAG and
have target_submit_tmr() do this from common code.

Cc: Himanshu Madhani 
Cc: Quinn Tran 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Signed-off-by: Nicholas Bellinger 
---
 drivers/scsi/qla2xxx/qla_target.c  | 39 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  4 +++-
 2 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 0e03ca2..401e245 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1847,38 +1847,13 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
struct abts_recv_from_24xx *abts, struct fc_port *sess)
 {
struct qla_hw_data *ha = vha->hw;
-   struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
-   struct se_cmd *se_cmd;
-   u32 lun = 0;
int rc;
-   bool found_lun = false;
-   unsigned long flags;
-
-   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
-   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
-   struct qla_tgt_cmd *cmd =
-   container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
-   if (se_cmd->tag == abts->exchange_addr_to_abort) {
-   lun = cmd->unpacked_lun;
-   found_lun = true;
-   break;
-   }
-   }
-   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
 
-   /* cmd not in LIO lists, look in qla list */
-   if (!found_lun) {
-   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
-   /* send TASK_ABORT response immediately */
-   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
-   return 0;
-   } else {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
-   "unable to find cmd in driver or LIO for tag 
0x%x\n",
-   abts->exchange_addr_to_abort);
-   return -ENOENT;
-   }
+   if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
+   /* send TASK_ABORT response immediately */
+   qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
+   return 0;
}
 
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
@@ -1899,7 +1874,11 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
mcmd->reset_count = vha->hw->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
 
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, mcmd->tmr_func,
+   /*
+* LUN is looked up by target-core internally based on the passed
+* abts->exchange_addr_to_abort tag.
+*/
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, mcmd->tmr_func,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c 
b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 7443e4e..75aeb9f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -601,11 +601,13 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd 
*mcmd, uint32_t lun,
struct fc_port *sess = mcmd->sess;
struct se_cmd *se_cmd = >se_cmd;
int transl_tmr_func = 0;
+   int flags = TARGET_SCF_ACK_KREF;
 
switch (tmr_func) {
case QLA_TGT_ABTS:
pr_debug("%ld: ABTS received\n", sess->vha->host_no);
transl_tmr_func = TMR_ABORT_TASK;
+   flags |= TARGET_SCF_LOOKUP_LUN_FROM_TAG;
break;
case QLA_TGT_2G_ABORT_TASK:
pr_debug("%ld: 2G Abort Task received\n", sess->vha->host_no);
@@ -638,7 +640,7 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd 
*mcmd, uint32_t lun,
}
 
return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd,
-   transl_tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF);
+   transl_tmr_func, GFP_ATOMIC, tag, flags);
 }
 
 static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
-- 
1.9.1



[PATCH 2/3] target: Add TARGET_SCF_LOOKUP_LUN_FROM_TAG support for ABORT_TASK

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch introduces support in target_submit_tmr() for locating a
unpacked_lun from an existing se_cmd->tag during ABORT_TASK.

When TARGET_SCF_LOOKUP_LUN_FROM_TAG is set, target_submit_tmr()
will do the extra lookup via target_lookup_lun_from_tag() and
subsequently invoke transport_lookup_tmr_lun() so a proper
percpu se_lun->lun_ref is taken before workqueue dispatch into
se_device->tmr_wq happens.

Aside from the extra target_lookup_lun_from_tag(), the existing
code-path remains unchanged.

Cc: Himanshu Madhani 
Cc: Quinn Tran 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_transport.c | 53 --
 include/target/target_core_base.h  |  3 +-
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 83bfc97..dbb8101 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1592,6 +1592,29 @@ static void target_complete_tmr_failure(struct 
work_struct *work)
transport_cmd_check_stop_to_fabric(se_cmd);
 }
 
+static bool target_lookup_lun_from_tag(struct se_session *se_sess, u64 tag,
+  u64 *unpacked_lun)
+{
+   struct se_cmd *se_cmd;
+   unsigned long flags;
+   bool ret = false;
+
+   spin_lock_irqsave(_sess->sess_cmd_lock, flags);
+   list_for_each_entry(se_cmd, _sess->sess_cmd_list, se_cmd_list) {
+   if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+   continue;
+
+   if (se_cmd->tag == tag) {
+   *unpacked_lun = se_cmd->orig_fe_lun;
+   ret = true;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(_sess->sess_cmd_lock, flags);
+
+   return ret;
+}
+
 /**
  * target_submit_tmr - lookup unpacked lun and submit uninitialized se_cmd
  * for TMR CDBs
@@ -1639,19 +1662,31 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct 
se_session *se_sess,
core_tmr_release_req(se_cmd->se_tmr_req);
return ret;
}
+   /*
+* If this is ABORT_TASK with no explicit fabric provided LUN,
+* go ahead and search active session tags for a match to figure
+* out unpacked_lun for the original se_cmd.
+*/
+   if (tm_type == TMR_ABORT_TASK && (flags & 
TARGET_SCF_LOOKUP_LUN_FROM_TAG)) {
+   if (!target_lookup_lun_from_tag(se_sess, tag, _lun))
+   goto failure;
+   }
 
ret = transport_lookup_tmr_lun(se_cmd, unpacked_lun);
-   if (ret) {
-   /*
-* For callback during failure handling, push this work off
-* to process context with TMR_LUN_DOES_NOT_EXIST status.
-*/
-   INIT_WORK(_cmd->work, target_complete_tmr_failure);
-   schedule_work(_cmd->work);
-   return 0;
-   }
+   if (ret)
+   goto failure;
+
transport_generic_handle_tmr(se_cmd);
return 0;
+
+   /*
+* For callback during failure handling, push this work off
+* to process context with TMR_LUN_DOES_NOT_EXIST status.
+*/
+failure:
+   INIT_WORK(_cmd->work, target_complete_tmr_failure);
+   schedule_work(_cmd->work);
+   return 0;
 }
 EXPORT_SYMBOL(target_submit_tmr);
 
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index db2c7b3..a3af69f 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -188,7 +188,8 @@ enum target_sc_flags_table {
TARGET_SCF_BIDI_OP  = 0x01,
TARGET_SCF_ACK_KREF = 0x02,
TARGET_SCF_UNKNOWN_SIZE = 0x04,
-   TARGET_SCF_USE_CPUID= 0x08,
+   TARGET_SCF_USE_CPUID= 0x08,
+   TARGET_SCF_LOOKUP_LUN_FROM_TAG  = 0x10,
 };
 
 /* fabric independent task management function values */
-- 
1.9.1



[PATCH] iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a BUG() in iscsit_close_session() that could be
triggered when iscsit_logout_post_handler() execution from within
tx thread context was not run for more than SECONDS_FOR_LOGOUT_COMP
(15 seconds), and the TCP connection didn't already close before
then forcing tx thread context to automatically exit.

This would manifest itself during explicit logout as:

[33206.974254] 1 connection(s) still exist for iSCSI session to 
iqn.1993-08.org.debian:01:3f5523242179
[33206.980184] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
2100.772 msecs
[33209.078643] [ cut here ]
[33209.078646] kernel BUG at drivers/target/iscsi/iscsi_target.c:4346!

Normally when explicit logout attempt fails, the tx thread context
exits and iscsit_close_connection() from rx thread context does the
extra cleanup once it detects conn->conn_logout_remove has not been
cleared by the logout type specific post handlers.

To address this special case, if the logout post handler in tx thread
context detects conn->tx_thread_active has already been cleared, simply
return and exit in order for existing iscsit_close_connection()
logic from rx thread context do failed logout cleanup.

Reported-by: Bart Van Assche <bart.vanass...@sandisk.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.de>
Cc: Sagi Grimberg <sa...@mellanox.com>
Cc: sta...@vger.kernel.org # 3.14+
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/iscsi/iscsi_target.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 0d8f815..c025451 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -4423,8 +4423,11 @@ static void iscsit_logout_post_handler_closesession(
 * always sleep waiting for RX/TX thread shutdown to complete
 * within iscsit_close_connection().
 */
-   if (!conn->conn_transport->rdma_shutdown)
+   if (!conn->conn_transport->rdma_shutdown) {
sleep = cmpxchg(>tx_thread_active, true, false);
+   if (!sleep)
+   return;
+   }
 
atomic_set(>conn_logout_remove, 0);
complete(>conn_logout_comp);
@@ -4440,8 +4443,11 @@ static void iscsit_logout_post_handler_samecid(
 {
int sleep = 1;
 
-   if (!conn->conn_transport->rdma_shutdown)
+   if (!conn->conn_transport->rdma_shutdown) {
sleep = cmpxchg(>tx_thread_active, true, false);
+   if (!sleep)
+   return;
+   }
 
atomic_set(>conn_logout_remove, 0);
complete(>conn_logout_comp);
-- 
1.9.1



[PATCH] iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a BUG() in iscsit_close_session() that could be
triggered when iscsit_logout_post_handler() execution from within
tx thread context was not run for more than SECONDS_FOR_LOGOUT_COMP
(15 seconds), and the TCP connection didn't already close before
then forcing tx thread context to automatically exit.

This would manifest itself during explicit logout as:

[33206.974254] 1 connection(s) still exist for iSCSI session to 
iqn.1993-08.org.debian:01:3f5523242179
[33206.980184] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
2100.772 msecs
[33209.078643] [ cut here ]
[33209.078646] kernel BUG at drivers/target/iscsi/iscsi_target.c:4346!

Normally when explicit logout attempt fails, the tx thread context
exits and iscsit_close_connection() from rx thread context does the
extra cleanup once it detects conn->conn_logout_remove has not been
cleared by the logout type specific post handlers.

To address this special case, if the logout post handler in tx thread
context detects conn->tx_thread_active has already been cleared, simply
return and exit in order for existing iscsit_close_connection()
logic from rx thread context do failed logout cleanup.

Reported-by: Bart Van Assche 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Sagi Grimberg 
Cc: sta...@vger.kernel.org # 3.14+
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/iscsi/iscsi_target.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 0d8f815..c025451 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -4423,8 +4423,11 @@ static void iscsit_logout_post_handler_closesession(
 * always sleep waiting for RX/TX thread shutdown to complete
 * within iscsit_close_connection().
 */
-   if (!conn->conn_transport->rdma_shutdown)
+   if (!conn->conn_transport->rdma_shutdown) {
sleep = cmpxchg(>tx_thread_active, true, false);
+   if (!sleep)
+   return;
+   }
 
atomic_set(>conn_logout_remove, 0);
complete(>conn_logout_comp);
@@ -4440,8 +4443,11 @@ static void iscsit_logout_post_handler_samecid(
 {
int sleep = 1;
 
-   if (!conn->conn_transport->rdma_shutdown)
+   if (!conn->conn_transport->rdma_shutdown) {
sleep = cmpxchg(>tx_thread_active, true, false);
+   if (!sleep)
+   return;
+   }
 
atomic_set(>conn_logout_remove, 0);
complete(>conn_logout_comp);
-- 
1.9.1



[PATCH] target: Fix kref->refcount underflow in transport_cmd_finish_abort

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

This patch fixes a se_cmd->cmd_kref underflow during CMD_T_ABORTED
when a fabric driver drops it's second reference from below the
target_core_tmr.c based callers of transport_cmd_finish_abort().

Recently with the conversion of kref to refcount_t, this bug was
manifesting itself as:

[705519.601034] refcount_t: underflow; use-after-free.
[705519.604034] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
20116.512 msecs
[705539.719111] [ cut here ]
[705539.719117] WARNING: CPU: 3 PID: 26510 at lib/refcount.c:184 
refcount_sub_and_test+0x33/0x51

Since the original kref atomic_t based kref_put() didn't check for
underflow and only invoked the final callback when zero was reached,
this bug did not manifest in practice since all se_cmd memory is
using preallocated tags.

To address this, go ahead and propigate the existing return from
transport_put_cmd() up via transport_cmd_finish_abort(), and
change transport_cmd_finish_abort() + core_tmr_handle_tas_abort()
callers to only do their local target_put_sess_cmd() if necessary.

Reported-by: Bart Van Assche <bart.vanass...@sandisk.com>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.de>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Himanshu Madhani <himanshu.madh...@qlogic.com>
Cc: Sagi Grimberg <sa...@mellanox.com>
Cc: sta...@vger.kernel.org # 3.14+
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_internal.h  |  2 +-
 drivers/target/target_core_tmr.c   | 16 
 drivers/target/target_core_transport.c |  9 ++---
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/target/target_core_internal.h 
b/drivers/target/target_core_internal.h
index 9ab7090..0912de7 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -136,7 +136,7 @@ struct se_node_acl *core_tpg_add_initiator_node_acl(struct 
se_portal_group *tpg,
 void   release_se_kmem_caches(void);
 u32scsi_get_new_index(scsi_index_t);
 void   transport_subsystem_check_init(void);
-void   transport_cmd_finish_abort(struct se_cmd *, int);
+inttransport_cmd_finish_abort(struct se_cmd *, int);
 unsigned char *transport_dump_cmd_direction(struct se_cmd *);
 void   transport_dump_dev_state(struct se_device *, char *, int *);
 void   transport_dump_dev_info(struct se_device *, struct se_lun *,
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index dce1e1b..13f47bf 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
kfree(tmr);
 }
 
-static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
+static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
 {
unsigned long flags;
bool remove = true, send_tas;
@@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int 
tas)
transport_send_task_abort(cmd);
}
 
-   transport_cmd_finish_abort(cmd, remove);
+   return transport_cmd_finish_abort(cmd, remove);
 }
 
 static int target_check_cdb_and_preempt(struct list_head *list,
@@ -184,8 +184,8 @@ void core_tmr_abort_task(
cancel_work_sync(_cmd->work);
transport_wait_for_tasks(se_cmd);
 
-   transport_cmd_finish_abort(se_cmd, true);
-   target_put_sess_cmd(se_cmd);
+   if (!transport_cmd_finish_abort(se_cmd, true))
+   target_put_sess_cmd(se_cmd);
 
printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
" ref_tag: %llu\n", ref_tag);
@@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
cancel_work_sync(>work);
transport_wait_for_tasks(cmd);
 
-   transport_cmd_finish_abort(cmd, 1);
-   target_put_sess_cmd(cmd);
+   if (!transport_cmd_finish_abort(cmd, 1))
+   target_put_sess_cmd(cmd);
}
 }
 
@@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
cancel_work_sync(>work);
transport_wait_for_tasks(cmd);
 
-   core_tmr_handle_tas_abort(cmd, tas);
-   target_put_sess_cmd(cmd);
+   if (!core_tmr_handle_tas_abort(cmd, tas))
+   target_put_sess_cmd(cmd);
}
 }
 
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 6025935..f1b3a46 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -651,9 +651,10 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
percpu_ref_put(>lun_ref);
 }
 
-void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
+int transport_cmd_finish_

[PATCH] target: Fix kref->refcount underflow in transport_cmd_finish_abort

2017-06-03 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes a se_cmd->cmd_kref underflow during CMD_T_ABORTED
when a fabric driver drops it's second reference from below the
target_core_tmr.c based callers of transport_cmd_finish_abort().

Recently with the conversion of kref to refcount_t, this bug was
manifesting itself as:

[705519.601034] refcount_t: underflow; use-after-free.
[705519.604034] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 
20116.512 msecs
[705539.719111] [ cut here ]
[705539.719117] WARNING: CPU: 3 PID: 26510 at lib/refcount.c:184 
refcount_sub_and_test+0x33/0x51

Since the original kref atomic_t based kref_put() didn't check for
underflow and only invoked the final callback when zero was reached,
this bug did not manifest in practice since all se_cmd memory is
using preallocated tags.

To address this, go ahead and propigate the existing return from
transport_put_cmd() up via transport_cmd_finish_abort(), and
change transport_cmd_finish_abort() + core_tmr_handle_tas_abort()
callers to only do their local target_put_sess_cmd() if necessary.

Reported-by: Bart Van Assche 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Cc: Christoph Hellwig 
Cc: Himanshu Madhani 
Cc: Sagi Grimberg 
Cc: sta...@vger.kernel.org # 3.14+
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_internal.h  |  2 +-
 drivers/target/target_core_tmr.c   | 16 
 drivers/target/target_core_transport.c |  9 ++---
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/target/target_core_internal.h 
b/drivers/target/target_core_internal.h
index 9ab7090..0912de7 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -136,7 +136,7 @@ struct se_node_acl *core_tpg_add_initiator_node_acl(struct 
se_portal_group *tpg,
 void   release_se_kmem_caches(void);
 u32scsi_get_new_index(scsi_index_t);
 void   transport_subsystem_check_init(void);
-void   transport_cmd_finish_abort(struct se_cmd *, int);
+inttransport_cmd_finish_abort(struct se_cmd *, int);
 unsigned char *transport_dump_cmd_direction(struct se_cmd *);
 void   transport_dump_dev_state(struct se_device *, char *, int *);
 void   transport_dump_dev_info(struct se_device *, struct se_lun *,
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index dce1e1b..13f47bf 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
kfree(tmr);
 }
 
-static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
+static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
 {
unsigned long flags;
bool remove = true, send_tas;
@@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int 
tas)
transport_send_task_abort(cmd);
}
 
-   transport_cmd_finish_abort(cmd, remove);
+   return transport_cmd_finish_abort(cmd, remove);
 }
 
 static int target_check_cdb_and_preempt(struct list_head *list,
@@ -184,8 +184,8 @@ void core_tmr_abort_task(
cancel_work_sync(_cmd->work);
transport_wait_for_tasks(se_cmd);
 
-   transport_cmd_finish_abort(se_cmd, true);
-   target_put_sess_cmd(se_cmd);
+   if (!transport_cmd_finish_abort(se_cmd, true))
+   target_put_sess_cmd(se_cmd);
 
printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
" ref_tag: %llu\n", ref_tag);
@@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
cancel_work_sync(>work);
transport_wait_for_tasks(cmd);
 
-   transport_cmd_finish_abort(cmd, 1);
-   target_put_sess_cmd(cmd);
+   if (!transport_cmd_finish_abort(cmd, 1))
+   target_put_sess_cmd(cmd);
}
 }
 
@@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
cancel_work_sync(>work);
transport_wait_for_tasks(cmd);
 
-   core_tmr_handle_tas_abort(cmd, tas);
-   target_put_sess_cmd(cmd);
+   if (!core_tmr_handle_tas_abort(cmd, tas))
+   target_put_sess_cmd(cmd);
}
 }
 
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 6025935..f1b3a46 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -651,9 +651,10 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
percpu_ref_put(>lun_ref);
 }
 
-void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
+int transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 {
bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF);
+   int ret = 0;
 
if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
transpo

Re: linux-next: upcoming conflict between the target-updates and target-bva trees

2017-06-01 Thread Nicholas A. Bellinger
On Fri, 2017-06-02 at 13:39 +1000, Stephen Rothwell wrote:
> Hi all,
> 
> Last night the tagret-bva tree was rebased on top of the target-updates
> tree.  Just now, part of the target-updates tree has been rewritten.
> So now I expect to get conflict(s) when I merge these trees since the
> commits in the target-updates tree are no longer the same as those that
> the target-bva tree was rebased on top of.
> 
> Please take a little time to sort out your development process.
> 

Unfortunately, this is going to continue to be a problem once these
patches are list reviewed, and included in target-updates.

Bart, can you please drop the patches until they are list reviewed so
there isn't a constant stream of merge conflicts in linux-next for your
un-reviewed code..?






Re: linux-next: upcoming conflict between the target-updates and target-bva trees

2017-06-01 Thread Nicholas A. Bellinger
On Fri, 2017-06-02 at 13:39 +1000, Stephen Rothwell wrote:
> Hi all,
> 
> Last night the tagret-bva tree was rebased on top of the target-updates
> tree.  Just now, part of the target-updates tree has been rewritten.
> So now I expect to get conflict(s) when I merge these trees since the
> commits in the target-updates tree are no longer the same as those that
> the target-bva tree was rebased on top of.
> 
> Please take a little time to sort out your development process.
> 

Unfortunately, this is going to continue to be a problem once these
patches are list reviewed, and included in target-updates.

Bart, can you please drop the patches until they are list reviewed so
there isn't a constant stream of merge conflicts in linux-next for your
un-reviewed code..?






Re: linux-next: manual merge of the target-bva tree with the target-updates tree

2017-06-01 Thread Nicholas A. Bellinger
On Thu, 2017-06-01 at 14:14 -0700, Bart Van Assche wrote:
> On 05/31/17 22:04, Nicholas A. Bellinger wrote:
> > Go ahead and get list review on drivers/target/ changes before pushing
> > them into linux-next, please.
> > 
> > Btw, I don't care if you queue up one's that do have at least two
> > Reviewed-bys into your tree, but everything that doesn't have
> > Reviewed-bys or Acked-by should not be going into linux-next.
> 
> It is not your job to rewrite the rules for linux-next. I'm following
> the guidelines I received from Stephen in December 2016. You were copied
> on the e-mail with guidelines Stephen sent to me. See also
> https://www.spinics.net/lists/linux-next/msg38488.html.
> 
> Stephen, if anything would have changed in the meantime that I'm not
> aware of please let me know.
> 

The point is you're not sending PULL requests.

But like I said earlier, I really don't care if you put patches that
have been reviewed into your tree for linux-next before I get a chance
to review and pick them up for target-pending.

However, you putting random un-reviewed changes is where I have to draw
the line, especially considering what happened earlier in year where
what you had in linux-next close to the merge window was completely and
utterly broken.

Would you put un-reviewed block and scsi changes into linux-next..?

What would those subsystem maintainers say about that..?

Why is drivers/target any different..?



Re: linux-next: manual merge of the target-bva tree with the target-updates tree

2017-06-01 Thread Nicholas A. Bellinger
On Thu, 2017-06-01 at 14:14 -0700, Bart Van Assche wrote:
> On 05/31/17 22:04, Nicholas A. Bellinger wrote:
> > Go ahead and get list review on drivers/target/ changes before pushing
> > them into linux-next, please.
> > 
> > Btw, I don't care if you queue up one's that do have at least two
> > Reviewed-bys into your tree, but everything that doesn't have
> > Reviewed-bys or Acked-by should not be going into linux-next.
> 
> It is not your job to rewrite the rules for linux-next. I'm following
> the guidelines I received from Stephen in December 2016. You were copied
> on the e-mail with guidelines Stephen sent to me. See also
> https://www.spinics.net/lists/linux-next/msg38488.html.
> 
> Stephen, if anything would have changed in the meantime that I'm not
> aware of please let me know.
> 

The point is you're not sending PULL requests.

But like I said earlier, I really don't care if you put patches that
have been reviewed into your tree for linux-next before I get a chance
to review and pick them up for target-pending.

However, you putting random un-reviewed changes is where I have to draw
the line, especially considering what happened earlier in year where
what you had in linux-next close to the merge window was completely and
utterly broken.

Would you put un-reviewed block and scsi changes into linux-next..?

What would those subsystem maintainers say about that..?

Why is drivers/target any different..?



Re: [PATCH] iscsi: Fix a sleep-in-atomic bug

2017-06-01 Thread Nicholas A. Bellinger
On Fri, 2017-06-02 at 09:13 +0800, Jia-Ju Bai wrote:
> On 06/01/2017 02:21 PM, Nicholas A. Bellinger wrote:
> > Hi Jia-Ju,
> >
> > On Wed, 2017-05-31 at 11:26 +0800, Jia-Ju Bai wrote:
> >> The driver may sleep under a spin lock, and the function call path is:
> >> iscsit_tpg_enable_portal_group (acquire the lock by spin_lock)
> >>iscsi_update_param_value
> >>  kstrdup(GFP_KERNEL) -->  may sleep
> >>
> >> To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC".
> >>
> >> Signed-off-by: Jia-Ju Bai<baijiaju1...@163.com>
> >> ---
> >>   drivers/target/iscsi/iscsi_target_parameters.c |2 +-
> >>   1 file changed, 1 insertion(+), 1 deletion(-)
> > Btw, the use of tpg->tpg_state_lock in iscsit_tpg_enable_portal_group()
> > while checking existing state and calling iscsi_update_param_value() is
> > not necessary, since lio_target_tpg_enable_store() is already holding
> > iscsit_get_tpg() ->  tpg->tpg_access_lock.
> >
> > How about the following instead to only take tpg->tpg_state_lock when
> > updating tpg->tpg_state instead..?
> >
> > diff --git a/drivers/target/iscsi/iscsi_target_tpg.c 
> > b/drivers/target/iscsi/iscsi_target_tpg.c
> > index 2e7e08d..abaabba 100644
> > --- a/drivers/target/iscsi/iscsi_target_tpg.c
> > +++ b/drivers/target/iscsi/iscsi_target_tpg.c
> > @@ -311,11 +311,9 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
> >  int ret;
> >
> > -   spin_lock(>tpg_state_lock);
> >  if (tpg->tpg_state == TPG_STATE_ACTIVE) {
> >  pr_err("iSCSI target portal group: %hu is already"
> >  " active, ignoring request.\n", tpg->tpgt);
> > -   spin_unlock(>tpg_state_lock);
> >  return -EINVAL;
> >  }
> >  /*
> > @@ -324,10 +322,8 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >   * is enforced (as per default), and remove the NONE option.
> >   */
> >  param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
> > -   if (!param) {
> > -   spin_unlock(>tpg_state_lock);
> > +   if (!param)
> >  return -EINVAL;
> > -   }
> >
> >  if (tpg->tpg_attrib.authentication) {
> >  if (!strcmp(param->value, NONE)) {
> > @@ -341,6 +337,7 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  goto err;
> >  }
> >
> > +   spin_lock(>tpg_state_lock);
> >  tpg->tpg_state = TPG_STATE_ACTIVE;
> >  spin_unlock(>tpg_state_lock);
> >
> > @@ -353,7 +350,6 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  return 0;
> >
> >   err:
> > -   spin_unlock(>tpg_state_lock);
> >  return ret;
> >   }
> >
> I think it is fine to me.
> 
> Thanks,
> Jia-Ju Bai

Applied with your Reported-by and Reviewed-by.

Thanks!



Re: [PATCH] iscsi: Fix a sleep-in-atomic bug

2017-06-01 Thread Nicholas A. Bellinger
On Fri, 2017-06-02 at 09:13 +0800, Jia-Ju Bai wrote:
> On 06/01/2017 02:21 PM, Nicholas A. Bellinger wrote:
> > Hi Jia-Ju,
> >
> > On Wed, 2017-05-31 at 11:26 +0800, Jia-Ju Bai wrote:
> >> The driver may sleep under a spin lock, and the function call path is:
> >> iscsit_tpg_enable_portal_group (acquire the lock by spin_lock)
> >>iscsi_update_param_value
> >>  kstrdup(GFP_KERNEL) -->  may sleep
> >>
> >> To fix it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC".
> >>
> >> Signed-off-by: Jia-Ju Bai
> >> ---
> >>   drivers/target/iscsi/iscsi_target_parameters.c |2 +-
> >>   1 file changed, 1 insertion(+), 1 deletion(-)
> > Btw, the use of tpg->tpg_state_lock in iscsit_tpg_enable_portal_group()
> > while checking existing state and calling iscsi_update_param_value() is
> > not necessary, since lio_target_tpg_enable_store() is already holding
> > iscsit_get_tpg() ->  tpg->tpg_access_lock.
> >
> > How about the following instead to only take tpg->tpg_state_lock when
> > updating tpg->tpg_state instead..?
> >
> > diff --git a/drivers/target/iscsi/iscsi_target_tpg.c 
> > b/drivers/target/iscsi/iscsi_target_tpg.c
> > index 2e7e08d..abaabba 100644
> > --- a/drivers/target/iscsi/iscsi_target_tpg.c
> > +++ b/drivers/target/iscsi/iscsi_target_tpg.c
> > @@ -311,11 +311,9 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
> >  int ret;
> >
> > -   spin_lock(>tpg_state_lock);
> >  if (tpg->tpg_state == TPG_STATE_ACTIVE) {
> >  pr_err("iSCSI target portal group: %hu is already"
> >  " active, ignoring request.\n", tpg->tpgt);
> > -   spin_unlock(>tpg_state_lock);
> >  return -EINVAL;
> >  }
> >  /*
> > @@ -324,10 +322,8 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >   * is enforced (as per default), and remove the NONE option.
> >   */
> >  param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
> > -   if (!param) {
> > -   spin_unlock(>tpg_state_lock);
> > +   if (!param)
> >  return -EINVAL;
> > -   }
> >
> >  if (tpg->tpg_attrib.authentication) {
> >  if (!strcmp(param->value, NONE)) {
> > @@ -341,6 +337,7 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  goto err;
> >  }
> >
> > +   spin_lock(>tpg_state_lock);
> >  tpg->tpg_state = TPG_STATE_ACTIVE;
> >  spin_unlock(>tpg_state_lock);
> >
> > @@ -353,7 +350,6 @@ int iscsit_tpg_enable_portal_group(struct 
> > iscsi_portal_group *tpg)
> >  return 0;
> >
> >   err:
> > -   spin_unlock(>tpg_state_lock);
> >  return ret;
> >   }
> >
> I think it is fine to me.
> 
> Thanks,
> Jia-Ju Bai

Applied with your Reported-by and Reviewed-by.

Thanks!



[PATCH-v2] target: Avoid target_shutdown_sessions loop during queue_depth change

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

When target_shutdown_sessions() is invoked to shutdown all active
sessions associated with a se_node_acl when se_node_acl->queue_depth
is changed via core_tpg_set_initiator_node_queue_depth(), it's
possible that new connections reconnect immediately after explicit
shutdown occurs via target_shutdown_sessions().

Which means it's possible for the newly reconnected session with
the proper queue_depth can be shutdown multiple times when
target_shutdown_sessions() loops to drain all active sessions
for all cases.

This was regression was introduced by:

  commit bc6e6bb470eda42f44bcac96c261cff1216577b3
  Author: Christoph Hellwig <h...@lst.de>
  Date:   Mon May 2 15:45:19 2016 +0200

  target: consolidate and fix session shutdown

To avoid this case, instead change target_shutdown_sessions() to
pass 'do_restart' and avoid the looping drain of sessions when
invoked via core_tpg_set_initiator_node_queue_depth(), but still
loop during normal se_node_acl delete until all associated
sessions have been shutdown.

(v2 - go back to the original version instead of a local list,
 in order to protect list_del_init(>sess_acl_list) from
 transport_deregister_session_configfs.
 Also use safe list walking in target_shutdown_sessions - nab)

Cc: Christoph Hellwig <h...@lst.de>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_tpg.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 3691373..1b2b60e 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -336,14 +336,14 @@ struct se_node_acl *core_tpg_add_initiator_node_acl(
return acl;
 }
 
-static void target_shutdown_sessions(struct se_node_acl *acl)
+static void target_shutdown_sessions(struct se_node_acl *acl, bool do_restart)
 {
-   struct se_session *sess;
+   struct se_session *sess, *sess_tmp;
unsigned long flags;
 
 restart:
spin_lock_irqsave(>nacl_sess_lock, flags);
-   list_for_each_entry(sess, >acl_sess_list, sess_acl_list) {
+   list_for_each_entry_safe(sess, sess_tmp, >acl_sess_list, 
sess_acl_list) {
if (sess->sess_tearing_down)
continue;
 
@@ -352,7 +352,11 @@ static void target_shutdown_sessions(struct se_node_acl 
*acl)
 
if (acl->se_tpg->se_tpg_tfo->close_session)
acl->se_tpg->se_tpg_tfo->close_session(sess);
-   goto restart;
+
+   if (do_restart)
+   goto restart;
+
+   spin_lock_irqsave(>nacl_sess_lock, flags);
}
spin_unlock_irqrestore(>nacl_sess_lock, flags);
 }
@@ -367,7 +371,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl 
*acl)
list_del(>acl_list);
mutex_unlock(>acl_node_mutex);
 
-   target_shutdown_sessions(acl);
+   target_shutdown_sessions(acl, true);
 
target_put_nacl(acl);
/*
@@ -414,7 +418,7 @@ int core_tpg_set_initiator_node_queue_depth(
/*
 * Shutdown all pending sessions to force session reinstatement.
 */
-   target_shutdown_sessions(acl);
+   target_shutdown_sessions(acl, false);
 
pr_debug("Successfully changed queue depth to: %d for Initiator"
" Node: %s on %s Target Portal Group: %u\n", acl->queue_depth,
-- 
1.9.1



[PATCH-v2] target: Avoid target_shutdown_sessions loop during queue_depth change

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

When target_shutdown_sessions() is invoked to shutdown all active
sessions associated with a se_node_acl when se_node_acl->queue_depth
is changed via core_tpg_set_initiator_node_queue_depth(), it's
possible that new connections reconnect immediately after explicit
shutdown occurs via target_shutdown_sessions().

Which means it's possible for the newly reconnected session with
the proper queue_depth can be shutdown multiple times when
target_shutdown_sessions() loops to drain all active sessions
for all cases.

This was regression was introduced by:

  commit bc6e6bb470eda42f44bcac96c261cff1216577b3
  Author: Christoph Hellwig 
  Date:   Mon May 2 15:45:19 2016 +0200

  target: consolidate and fix session shutdown

To avoid this case, instead change target_shutdown_sessions() to
pass 'do_restart' and avoid the looping drain of sessions when
invoked via core_tpg_set_initiator_node_queue_depth(), but still
loop during normal se_node_acl delete until all associated
sessions have been shutdown.

(v2 - go back to the original version instead of a local list,
 in order to protect list_del_init(>sess_acl_list) from
 transport_deregister_session_configfs.
 Also use safe list walking in target_shutdown_sessions - nab)

Cc: Christoph Hellwig 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_tpg.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 3691373..1b2b60e 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -336,14 +336,14 @@ struct se_node_acl *core_tpg_add_initiator_node_acl(
return acl;
 }
 
-static void target_shutdown_sessions(struct se_node_acl *acl)
+static void target_shutdown_sessions(struct se_node_acl *acl, bool do_restart)
 {
-   struct se_session *sess;
+   struct se_session *sess, *sess_tmp;
unsigned long flags;
 
 restart:
spin_lock_irqsave(>nacl_sess_lock, flags);
-   list_for_each_entry(sess, >acl_sess_list, sess_acl_list) {
+   list_for_each_entry_safe(sess, sess_tmp, >acl_sess_list, 
sess_acl_list) {
if (sess->sess_tearing_down)
continue;
 
@@ -352,7 +352,11 @@ static void target_shutdown_sessions(struct se_node_acl 
*acl)
 
if (acl->se_tpg->se_tpg_tfo->close_session)
acl->se_tpg->se_tpg_tfo->close_session(sess);
-   goto restart;
+
+   if (do_restart)
+   goto restart;
+
+   spin_lock_irqsave(>nacl_sess_lock, flags);
}
spin_unlock_irqrestore(>nacl_sess_lock, flags);
 }
@@ -367,7 +371,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl 
*acl)
list_del(>acl_list);
mutex_unlock(>acl_node_mutex);
 
-   target_shutdown_sessions(acl);
+   target_shutdown_sessions(acl, true);
 
target_put_nacl(acl);
/*
@@ -414,7 +418,7 @@ int core_tpg_set_initiator_node_queue_depth(
/*
 * Shutdown all pending sessions to force session reinstatement.
 */
-   target_shutdown_sessions(acl);
+   target_shutdown_sessions(acl, false);
 
pr_debug("Successfully changed queue depth to: %d for Initiator"
" Node: %s on %s Target Portal Group: %u\n", acl->queue_depth,
-- 
1.9.1



[PATCH 2/2] target/configfs: Kill se_lun->lun_link_magic

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Instead of using a hardcoded magic value in se_lun when verifying
a target config_item symlink source during target_fabric_mappedlun_link(),
go ahead and use target_fabric_port_item_ops directly instead.

Cc: Christoph Hellwig <h...@lst.de>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_fabric_configfs.c | 13 -
 drivers/target/target_core_tpg.c |  1 -
 include/target/target_core_base.h|  2 --
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index 2cbaecd..e9e917c 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -65,6 +65,8 @@
pr_debug("Setup generic %s\n", __stringify(_name)); \
 }
 
+static struct configfs_item_operations target_fabric_port_item_ops;
+
 /* Start of tfc_tpg_mappedlun_cit */
 
 static int target_fabric_mappedlun_link(
@@ -72,19 +74,20 @@ static int target_fabric_mappedlun_link(
struct config_item *lun_ci)
 {
struct se_dev_entry *deve;
-   struct se_lun *lun = container_of(to_config_group(lun_ci),
-   struct se_lun, lun_group);
+   struct se_lun *lun;
struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
struct se_lun_acl, se_lun_group);
struct se_portal_group *se_tpg;
struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
bool lun_access_ro;
 
-   if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) {
-   pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:"
-   " %p to struct lun: %p\n", lun_ci, lun);
+   if (!lun_ci->ci_type ||
+   lun_ci->ci_type->ct_item_ops != _fabric_port_item_ops) {
+   pr_err("Bad lun_ci, not a valid lun_ci pointer: %p\n", lun_ci);
return -EFAULT;
}
+   lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
+
/*
 * Ensure that the source port exists
 */
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 74893ac..6b20b9f 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -584,7 +584,6 @@ struct se_lun *core_tpg_alloc_lun(
return ERR_PTR(-ENOMEM);
}
lun->unpacked_lun = unpacked_lun;
-   lun->lun_link_magic = SE_LUN_LINK_MAGIC;
atomic_set(>lun_acl_count, 0);
init_completion(>lun_ref_comp);
init_completion(>lun_shutdown_comp);
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index c3c14d0..47d9f38 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -701,8 +701,6 @@ struct scsi_port_stats {
 
 struct se_lun {
u64 unpacked_lun;
-#define SE_LUN_LINK_MAGIC  0x7771
-   u32 lun_link_magic;
boollun_shutdown;
boollun_access_ro;
u32 lun_index;
-- 
1.9.1



[PATCH 1/2] target/configfs: Kill se_device->dev_link_magic

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger <n...@linux-iscsi.org>

Instead of using a hardcoded magic value in se_device when verifying
a target config_item symlink source during target_fabric_port_link(),
go ahead and use target_core_dev_item_ops directly instead.

Cc: Christoph Hellwig <h...@lst.de>
Cc: Mike Christie <mchri...@redhat.com>
Cc: Hannes Reinecke <h...@suse.com>
Signed-off-by: Nicholas Bellinger <n...@linux-iscsi.org>
---
 drivers/target/target_core_configfs.c|  6 +-
 drivers/target/target_core_device.c  |  1 -
 drivers/target/target_core_fabric_configfs.c | 12 +++-
 include/target/target_core_base.h|  2 --
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
index 0326607..9b8abd5 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2236,7 +2236,11 @@ static void target_core_dev_release(struct config_item 
*item)
target_free_device(dev);
 }
 
-static struct configfs_item_operations target_core_dev_item_ops = {
+/*
+ * Used in target_core_fabric_configfs.c to verify valid se_device symlink
+ * within target_fabric_port_link()
+ */
+struct configfs_item_operations target_core_dev_item_ops = {
.release= target_core_dev_release,
 };
 
diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index a5762e6..e4771ce 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -756,7 +756,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, 
const char *name)
if (!dev)
return NULL;
 
-   dev->dev_link_magic = SE_DEV_LINK_MAGIC;
dev->se_hba = hba;
dev->transport = hba->backend->ops;
dev->prot_length = sizeof(struct t10_pi_tuple);
diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index d1e6cab..2cbaecd 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -620,6 +620,8 @@ static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
NULL,
 };
 
+extern struct configfs_item_operations target_core_dev_item_ops;
+
 static int target_fabric_port_link(
struct config_item *lun_ci,
struct config_item *se_dev_ci)
@@ -628,16 +630,16 @@ static int target_fabric_port_link(
struct se_lun *lun = container_of(to_config_group(lun_ci),
struct se_lun, lun_group);
struct se_portal_group *se_tpg;
-   struct se_device *dev =
-   container_of(to_config_group(se_dev_ci), struct se_device, 
dev_group);
+   struct se_device *dev;
struct target_fabric_configfs *tf;
int ret;
 
-   if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) {
-   pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:"
-   " %p to struct se_device: %p\n", se_dev_ci, dev);
+   if (!se_dev_ci->ci_type ||
+   se_dev_ci->ci_type->ct_item_ops != _core_dev_item_ops) {
+   pr_err("Bad se_dev_ci, not a valid se_dev_ci pointer: %p\n", 
se_dev_ci);
return -EFAULT;
}
+   dev = container_of(to_config_group(se_dev_ci), struct se_device, 
dev_group);
 
if (!(dev->dev_flags & DF_CONFIGURED)) {
pr_err("se_device not configured yet, cannot port link\n");
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 0c1dce2..c3c14d0 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -746,8 +746,6 @@ struct se_dev_stat_grps {
 };
 
 struct se_device {
-#define SE_DEV_LINK_MAGIC  0xfeeddeef
-   u32 dev_link_magic;
/* RELATIVE TARGET PORT IDENTIFER Counter */
u16 dev_rpti_counter;
/* Used for SAM Task Attribute ordering */
-- 
1.9.1



[PATCH 2/2] target/configfs: Kill se_lun->lun_link_magic

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Instead of using a hardcoded magic value in se_lun when verifying
a target config_item symlink source during target_fabric_mappedlun_link(),
go ahead and use target_fabric_port_item_ops directly instead.

Cc: Christoph Hellwig 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_fabric_configfs.c | 13 -
 drivers/target/target_core_tpg.c |  1 -
 include/target/target_core_base.h|  2 --
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index 2cbaecd..e9e917c 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -65,6 +65,8 @@
pr_debug("Setup generic %s\n", __stringify(_name)); \
 }
 
+static struct configfs_item_operations target_fabric_port_item_ops;
+
 /* Start of tfc_tpg_mappedlun_cit */
 
 static int target_fabric_mappedlun_link(
@@ -72,19 +74,20 @@ static int target_fabric_mappedlun_link(
struct config_item *lun_ci)
 {
struct se_dev_entry *deve;
-   struct se_lun *lun = container_of(to_config_group(lun_ci),
-   struct se_lun, lun_group);
+   struct se_lun *lun;
struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
struct se_lun_acl, se_lun_group);
struct se_portal_group *se_tpg;
struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
bool lun_access_ro;
 
-   if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) {
-   pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:"
-   " %p to struct lun: %p\n", lun_ci, lun);
+   if (!lun_ci->ci_type ||
+   lun_ci->ci_type->ct_item_ops != _fabric_port_item_ops) {
+   pr_err("Bad lun_ci, not a valid lun_ci pointer: %p\n", lun_ci);
return -EFAULT;
}
+   lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
+
/*
 * Ensure that the source port exists
 */
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 74893ac..6b20b9f 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -584,7 +584,6 @@ struct se_lun *core_tpg_alloc_lun(
return ERR_PTR(-ENOMEM);
}
lun->unpacked_lun = unpacked_lun;
-   lun->lun_link_magic = SE_LUN_LINK_MAGIC;
atomic_set(>lun_acl_count, 0);
init_completion(>lun_ref_comp);
init_completion(>lun_shutdown_comp);
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index c3c14d0..47d9f38 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -701,8 +701,6 @@ struct scsi_port_stats {
 
 struct se_lun {
u64 unpacked_lun;
-#define SE_LUN_LINK_MAGIC  0x7771
-   u32 lun_link_magic;
boollun_shutdown;
boollun_access_ro;
u32 lun_index;
-- 
1.9.1



[PATCH 1/2] target/configfs: Kill se_device->dev_link_magic

2017-06-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Instead of using a hardcoded magic value in se_device when verifying
a target config_item symlink source during target_fabric_port_link(),
go ahead and use target_core_dev_item_ops directly instead.

Cc: Christoph Hellwig 
Cc: Mike Christie 
Cc: Hannes Reinecke 
Signed-off-by: Nicholas Bellinger 
---
 drivers/target/target_core_configfs.c|  6 +-
 drivers/target/target_core_device.c  |  1 -
 drivers/target/target_core_fabric_configfs.c | 12 +++-
 include/target/target_core_base.h|  2 --
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
index 0326607..9b8abd5 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2236,7 +2236,11 @@ static void target_core_dev_release(struct config_item 
*item)
target_free_device(dev);
 }
 
-static struct configfs_item_operations target_core_dev_item_ops = {
+/*
+ * Used in target_core_fabric_configfs.c to verify valid se_device symlink
+ * within target_fabric_port_link()
+ */
+struct configfs_item_operations target_core_dev_item_ops = {
.release= target_core_dev_release,
 };
 
diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index a5762e6..e4771ce 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -756,7 +756,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, 
const char *name)
if (!dev)
return NULL;
 
-   dev->dev_link_magic = SE_DEV_LINK_MAGIC;
dev->se_hba = hba;
dev->transport = hba->backend->ops;
dev->prot_length = sizeof(struct t10_pi_tuple);
diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index d1e6cab..2cbaecd 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -620,6 +620,8 @@ static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
NULL,
 };
 
+extern struct configfs_item_operations target_core_dev_item_ops;
+
 static int target_fabric_port_link(
struct config_item *lun_ci,
struct config_item *se_dev_ci)
@@ -628,16 +630,16 @@ static int target_fabric_port_link(
struct se_lun *lun = container_of(to_config_group(lun_ci),
struct se_lun, lun_group);
struct se_portal_group *se_tpg;
-   struct se_device *dev =
-   container_of(to_config_group(se_dev_ci), struct se_device, 
dev_group);
+   struct se_device *dev;
struct target_fabric_configfs *tf;
int ret;
 
-   if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) {
-   pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:"
-   " %p to struct se_device: %p\n", se_dev_ci, dev);
+   if (!se_dev_ci->ci_type ||
+   se_dev_ci->ci_type->ct_item_ops != _core_dev_item_ops) {
+   pr_err("Bad se_dev_ci, not a valid se_dev_ci pointer: %p\n", 
se_dev_ci);
return -EFAULT;
}
+   dev = container_of(to_config_group(se_dev_ci), struct se_device, 
dev_group);
 
if (!(dev->dev_flags & DF_CONFIGURED)) {
pr_err("se_device not configured yet, cannot port link\n");
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 0c1dce2..c3c14d0 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -746,8 +746,6 @@ struct se_dev_stat_grps {
 };
 
 struct se_device {
-#define SE_DEV_LINK_MAGIC  0xfeeddeef
-   u32 dev_link_magic;
/* RELATIVE TARGET PORT IDENTIFER Counter */
u16 dev_rpti_counter;
/* Used for SAM Task Attribute ordering */
-- 
1.9.1



  1   2   3   4   5   6   7   8   9   10   >