greybus: operation: fix connection tear down

Fix connection tear down, which was done in an unsafe way that could
result in use-after-free as the per-connection list of operations was
iterated without any locking or refcounting.

Specifically, the operations list was iterated without holding any locks or
operation refcounts even though operations were being both removed from
the list and deallocated during per-operation cancellation. Any
operation completing during tear down could also cause corruption.

Change the per-connection operation list to only contain active
operations and use the recently introduced active counter to maintain
the list.

Add new helper that is called on connection tear down to cancel all
outstanding operations in a safe way by using proper locks and making
sure to hold a reference to any operation being cancelled.

Note that by verifying the connection state before incrementing the
active count we can make sure that all active operations have been
cancelled and that no new ones have been started when the helper
returns.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h
index c2b71fe..fb7a1fb 100644
--- a/drivers/staging/greybus/connection.h
+++ b/drivers/staging/greybus/connection.h
@@ -37,9 +37,9 @@
 
 	spinlock_t			lock;
 	enum gb_connection_state	state;
+	struct list_head		operations;
 
 	atomic_t			op_cycle;
-	struct list_head		operations;
 
 	void				*private;
 };