scsi_transport_iscsi.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  1. /*
  2. * iSCSI transport class definitions
  3. *
  4. * Copyright (C) IBM Corporation, 2004
  5. * Copyright (C) Mike Christie, 2004 - 2005
  6. * Copyright (C) Dmitry Yusupov, 2004 - 2005
  7. * Copyright (C) Alex Aizman, 2004 - 2005
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. */
  23. #include <linux/module.h>
  24. #include <linux/mempool.h>
  25. #include <linux/mutex.h>
  26. #include <net/tcp.h>
  27. #include <scsi/scsi.h>
  28. #include <scsi/scsi_host.h>
  29. #include <scsi/scsi_device.h>
  30. #include <scsi/scsi_transport.h>
  31. #include <scsi/scsi_transport_iscsi.h>
  32. #include <scsi/iscsi_if.h>
  33. #define ISCSI_SESSION_ATTRS 11
  34. #define ISCSI_CONN_ATTRS 11
  35. #define ISCSI_HOST_ATTRS 0
  36. struct iscsi_internal {
  37. int daemon_pid;
  38. struct scsi_transport_template t;
  39. struct iscsi_transport *iscsi_transport;
  40. struct list_head list;
  41. struct class_device cdev;
  42. struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
  43. struct transport_container conn_cont;
  44. struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
  45. struct transport_container session_cont;
  46. struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
  47. };
  48. static int iscsi_session_nr; /* sysfs session id for next new session */
  49. /*
  50. * list of registered transports and lock that must
  51. * be held while accessing list. The iscsi_transport_lock must
  52. * be acquired after the rx_queue_mutex.
  53. */
  54. static LIST_HEAD(iscsi_transports);
  55. static DEFINE_SPINLOCK(iscsi_transport_lock);
  56. #define to_iscsi_internal(tmpl) \
  57. container_of(tmpl, struct iscsi_internal, t)
  58. #define cdev_to_iscsi_internal(_cdev) \
  59. container_of(_cdev, struct iscsi_internal, cdev)
  60. static void iscsi_transport_release(struct class_device *cdev)
  61. {
  62. struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
  63. kfree(priv);
  64. }
  65. /*
  66. * iscsi_transport_class represents the iscsi_transports that are
  67. * registered.
  68. */
  69. static struct class iscsi_transport_class = {
  70. .name = "iscsi_transport",
  71. .release = iscsi_transport_release,
  72. };
  73. static ssize_t
  74. show_transport_handle(struct class_device *cdev, char *buf)
  75. {
  76. struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
  77. return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
  78. }
  79. static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
  80. #define show_transport_attr(name, format) \
  81. static ssize_t \
  82. show_transport_##name(struct class_device *cdev, char *buf) \
  83. { \
  84. struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \
  85. return sprintf(buf, format"\n", priv->iscsi_transport->name); \
  86. } \
  87. static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
  88. show_transport_attr(caps, "0x%x");
  89. show_transport_attr(max_lun, "%d");
  90. show_transport_attr(max_conn, "%d");
  91. show_transport_attr(max_cmd_len, "%d");
  92. static struct attribute *iscsi_transport_attrs[] = {
  93. &class_device_attr_handle.attr,
  94. &class_device_attr_caps.attr,
  95. &class_device_attr_max_lun.attr,
  96. &class_device_attr_max_conn.attr,
  97. &class_device_attr_max_cmd_len.attr,
  98. NULL,
  99. };
  100. static struct attribute_group iscsi_transport_group = {
  101. .attrs = iscsi_transport_attrs,
  102. };
  103. static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
  104. struct class_device *cdev)
  105. {
  106. struct Scsi_Host *shost = dev_to_shost(dev);
  107. struct iscsi_host *ihost = shost->shost_data;
  108. memset(ihost, 0, sizeof(*ihost));
  109. INIT_LIST_HEAD(&ihost->sessions);
  110. mutex_init(&ihost->mutex);
  111. return 0;
  112. }
  113. static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
  114. "iscsi_host",
  115. iscsi_setup_host,
  116. NULL,
  117. NULL);
  118. static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
  119. "iscsi_session",
  120. NULL,
  121. NULL,
  122. NULL);
  123. static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
  124. "iscsi_connection",
  125. NULL,
  126. NULL,
  127. NULL);
  128. static struct sock *nls;
  129. static DEFINE_MUTEX(rx_queue_mutex);
  130. struct mempool_zone {
  131. mempool_t *pool;
  132. atomic_t allocated;
  133. int size;
  134. int hiwat;
  135. struct list_head freequeue;
  136. spinlock_t freelock;
  137. };
  138. static struct mempool_zone *z_reply;
  139. /*
  140. * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
  141. * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
  142. * so daemon will notice OOM on NETLINK tranposrt level and will
  143. * be able to predict or change operational behavior
  144. */
  145. #define Z_MAX_REPLY 8
  146. #define Z_HIWAT_REPLY 6
  147. #define Z_MAX_PDU 8
  148. #define Z_HIWAT_PDU 6
  149. #define Z_MAX_ERROR 16
  150. #define Z_HIWAT_ERROR 12
  151. static LIST_HEAD(sesslist);
  152. static DEFINE_SPINLOCK(sesslock);
  153. static LIST_HEAD(connlist);
  154. static DEFINE_SPINLOCK(connlock);
  155. static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
  156. {
  157. struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
  158. return sess->sid;
  159. }
  160. /*
  161. * Returns the matching session to a given sid
  162. */
  163. static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
  164. {
  165. unsigned long flags;
  166. struct iscsi_cls_session *sess;
  167. spin_lock_irqsave(&sesslock, flags);
  168. list_for_each_entry(sess, &sesslist, sess_list) {
  169. if (sess->sid == sid) {
  170. spin_unlock_irqrestore(&sesslock, flags);
  171. return sess;
  172. }
  173. }
  174. spin_unlock_irqrestore(&sesslock, flags);
  175. return NULL;
  176. }
  177. /*
  178. * Returns the matching connection to a given sid / cid tuple
  179. */
  180. static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
  181. {
  182. unsigned long flags;
  183. struct iscsi_cls_conn *conn;
  184. spin_lock_irqsave(&connlock, flags);
  185. list_for_each_entry(conn, &connlist, conn_list) {
  186. if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
  187. spin_unlock_irqrestore(&connlock, flags);
  188. return conn;
  189. }
  190. }
  191. spin_unlock_irqrestore(&connlock, flags);
  192. return NULL;
  193. }
  194. /*
  195. * The following functions can be used by LLDs that allocate
  196. * their own scsi_hosts or by software iscsi LLDs
  197. */
  198. static void iscsi_session_release(struct device *dev)
  199. {
  200. struct iscsi_cls_session *session = iscsi_dev_to_session(dev);
  201. struct Scsi_Host *shost;
  202. shost = iscsi_session_to_shost(session);
  203. scsi_host_put(shost);
  204. kfree(session);
  205. }
  206. static int iscsi_is_session_dev(const struct device *dev)
  207. {
  208. return dev->release == iscsi_session_release;
  209. }
  210. static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
  211. uint id, uint lun)
  212. {
  213. struct iscsi_host *ihost = shost->shost_data;
  214. struct iscsi_cls_session *session;
  215. mutex_lock(&ihost->mutex);
  216. list_for_each_entry(session, &ihost->sessions, host_list) {
  217. if ((channel == SCAN_WILD_CARD || channel == 0) &&
  218. (id == SCAN_WILD_CARD || id == session->target_id))
  219. scsi_scan_target(&session->dev, 0,
  220. session->target_id, lun, 1);
  221. }
  222. mutex_unlock(&ihost->mutex);
  223. return 0;
  224. }
  225. static void session_recovery_timedout(void *data)
  226. {
  227. struct iscsi_cls_session *session = data;
  228. dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
  229. "out after %d secs\n", session->recovery_tmo);
  230. if (session->transport->session_recovery_timedout)
  231. session->transport->session_recovery_timedout(session);
  232. scsi_target_unblock(&session->dev);
  233. }
  234. void iscsi_unblock_session(struct iscsi_cls_session *session)
  235. {
  236. if (!cancel_delayed_work(&session->recovery_work))
  237. flush_scheduled_work();
  238. scsi_target_unblock(&session->dev);
  239. }
  240. EXPORT_SYMBOL_GPL(iscsi_unblock_session);
  241. void iscsi_block_session(struct iscsi_cls_session *session)
  242. {
  243. scsi_target_block(&session->dev);
  244. schedule_delayed_work(&session->recovery_work,
  245. session->recovery_tmo * HZ);
  246. }
  247. EXPORT_SYMBOL_GPL(iscsi_block_session);
  248. struct iscsi_cls_session *
  249. iscsi_alloc_session(struct Scsi_Host *shost,
  250. struct iscsi_transport *transport)
  251. {
  252. struct iscsi_cls_session *session;
  253. session = kzalloc(sizeof(*session) + transport->sessiondata_size,
  254. GFP_KERNEL);
  255. if (!session)
  256. return NULL;
  257. session->transport = transport;
  258. session->recovery_tmo = 120;
  259. INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
  260. INIT_LIST_HEAD(&session->host_list);
  261. INIT_LIST_HEAD(&session->sess_list);
  262. /* this is released in the dev's release function */
  263. scsi_host_get(shost);
  264. session->dev.parent = &shost->shost_gendev;
  265. session->dev.release = iscsi_session_release;
  266. device_initialize(&session->dev);
  267. if (transport->sessiondata_size)
  268. session->dd_data = &session[1];
  269. return session;
  270. }
  271. EXPORT_SYMBOL_GPL(iscsi_alloc_session);
  272. int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
  273. {
  274. struct Scsi_Host *shost = iscsi_session_to_shost(session);
  275. struct iscsi_host *ihost;
  276. int err;
  277. ihost = shost->shost_data;
  278. session->sid = iscsi_session_nr++;
  279. session->target_id = target_id;
  280. snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
  281. session->sid);
  282. err = device_add(&session->dev);
  283. if (err) {
  284. dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
  285. "register session's dev\n");
  286. goto release_host;
  287. }
  288. transport_register_device(&session->dev);
  289. mutex_lock(&ihost->mutex);
  290. list_add(&session->host_list, &ihost->sessions);
  291. mutex_unlock(&ihost->mutex);
  292. return 0;
  293. release_host:
  294. scsi_host_put(shost);
  295. return err;
  296. }
  297. EXPORT_SYMBOL_GPL(iscsi_add_session);
  298. /**
  299. * iscsi_create_session - create iscsi class session
  300. * @shost: scsi host
  301. * @transport: iscsi transport
  302. *
  303. * This can be called from a LLD or iscsi_transport.
  304. **/
  305. struct iscsi_cls_session *
  306. iscsi_create_session(struct Scsi_Host *shost,
  307. struct iscsi_transport *transport,
  308. unsigned int target_id)
  309. {
  310. struct iscsi_cls_session *session;
  311. session = iscsi_alloc_session(shost, transport);
  312. if (!session)
  313. return NULL;
  314. if (iscsi_add_session(session, target_id)) {
  315. iscsi_free_session(session);
  316. return NULL;
  317. }
  318. return session;
  319. }
  320. EXPORT_SYMBOL_GPL(iscsi_create_session);
  321. void iscsi_remove_session(struct iscsi_cls_session *session)
  322. {
  323. struct Scsi_Host *shost = iscsi_session_to_shost(session);
  324. struct iscsi_host *ihost = shost->shost_data;
  325. if (!cancel_delayed_work(&session->recovery_work))
  326. flush_scheduled_work();
  327. mutex_lock(&ihost->mutex);
  328. list_del(&session->host_list);
  329. mutex_unlock(&ihost->mutex);
  330. scsi_remove_target(&session->dev);
  331. transport_unregister_device(&session->dev);
  332. device_del(&session->dev);
  333. }
  334. EXPORT_SYMBOL_GPL(iscsi_remove_session);
  335. void iscsi_free_session(struct iscsi_cls_session *session)
  336. {
  337. put_device(&session->dev);
  338. }
  339. EXPORT_SYMBOL_GPL(iscsi_free_session);
  340. /**
  341. * iscsi_destroy_session - destroy iscsi session
  342. * @session: iscsi_session
  343. *
  344. * Can be called by a LLD or iscsi_transport. There must not be
  345. * any running connections.
  346. **/
  347. int iscsi_destroy_session(struct iscsi_cls_session *session)
  348. {
  349. iscsi_remove_session(session);
  350. iscsi_free_session(session);
  351. return 0;
  352. }
  353. EXPORT_SYMBOL_GPL(iscsi_destroy_session);
  354. static void mempool_zone_destroy(struct mempool_zone *zp)
  355. {
  356. mempool_destroy(zp->pool);
  357. kfree(zp);
  358. }
  359. static void*
  360. mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
  361. {
  362. struct mempool_zone *zone = pool_data;
  363. return alloc_skb(zone->size, gfp_mask);
  364. }
  365. static void
  366. mempool_zone_free_skb(void *element, void *pool_data)
  367. {
  368. kfree_skb(element);
  369. }
  370. static struct mempool_zone *
  371. mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
  372. {
  373. struct mempool_zone *zp;
  374. zp = kzalloc(sizeof(*zp), GFP_KERNEL);
  375. if (!zp)
  376. return NULL;
  377. zp->size = size;
  378. zp->hiwat = hiwat;
  379. INIT_LIST_HEAD(&zp->freequeue);
  380. spin_lock_init(&zp->freelock);
  381. atomic_set(&zp->allocated, 0);
  382. zp->pool = mempool_create(max, mempool_zone_alloc_skb,
  383. mempool_zone_free_skb, zp);
  384. if (!zp->pool) {
  385. kfree(zp);
  386. return NULL;
  387. }
  388. return zp;
  389. }
  390. static void iscsi_conn_release(struct device *dev)
  391. {
  392. struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
  393. struct device *parent = conn->dev.parent;
  394. mempool_zone_destroy(conn->z_pdu);
  395. mempool_zone_destroy(conn->z_error);
  396. kfree(conn);
  397. put_device(parent);
  398. }
  399. static int iscsi_is_conn_dev(const struct device *dev)
  400. {
  401. return dev->release == iscsi_conn_release;
  402. }
  403. static int iscsi_create_event_pools(struct iscsi_cls_conn *conn)
  404. {
  405. conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
  406. NLMSG_SPACE(sizeof(struct iscsi_uevent) +
  407. sizeof(struct iscsi_hdr) +
  408. DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
  409. Z_HIWAT_PDU);
  410. if (!conn->z_pdu) {
  411. dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
  412. "pdu zone for new conn\n");
  413. return -ENOMEM;
  414. }
  415. conn->z_error = mempool_zone_init(Z_MAX_ERROR,
  416. NLMSG_SPACE(sizeof(struct iscsi_uevent)),
  417. Z_HIWAT_ERROR);
  418. if (!conn->z_error) {
  419. dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
  420. "error zone for new conn\n");
  421. mempool_zone_destroy(conn->z_pdu);
  422. return -ENOMEM;
  423. }
  424. return 0;
  425. }
  426. /**
  427. * iscsi_create_conn - create iscsi class connection
  428. * @session: iscsi cls session
  429. * @cid: connection id
  430. *
  431. * This can be called from a LLD or iscsi_transport. The connection
  432. * is child of the session so cid must be unique for all connections
  433. * on the session.
  434. *
  435. * Since we do not support MCS, cid will normally be zero. In some cases
  436. * for software iscsi we could be trying to preallocate a connection struct
  437. * in which case there could be two connection structs and cid would be
  438. * non-zero.
  439. **/
  440. struct iscsi_cls_conn *
  441. iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
  442. {
  443. struct iscsi_transport *transport = session->transport;
  444. struct iscsi_cls_conn *conn;
  445. int err;
  446. conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL);
  447. if (!conn)
  448. return NULL;
  449. if (transport->conndata_size)
  450. conn->dd_data = &conn[1];
  451. INIT_LIST_HEAD(&conn->conn_list);
  452. conn->transport = transport;
  453. conn->cid = cid;
  454. if (iscsi_create_event_pools(conn))
  455. goto free_conn;
  456. /* this is released in the dev's release function */
  457. if (!get_device(&session->dev))
  458. goto free_conn_pools;
  459. snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
  460. session->sid, cid);
  461. conn->dev.parent = &session->dev;
  462. conn->dev.release = iscsi_conn_release;
  463. err = device_register(&conn->dev);
  464. if (err) {
  465. dev_printk(KERN_ERR, &conn->dev, "iscsi: could not register "
  466. "connection's dev\n");
  467. goto release_parent_ref;
  468. }
  469. transport_register_device(&conn->dev);
  470. return conn;
  471. release_parent_ref:
  472. put_device(&session->dev);
  473. free_conn_pools:
  474. free_conn:
  475. kfree(conn);
  476. return NULL;
  477. }
  478. EXPORT_SYMBOL_GPL(iscsi_create_conn);
  479. /**
  480. * iscsi_destroy_conn - destroy iscsi class connection
  481. * @session: iscsi cls session
  482. *
  483. * This can be called from a LLD or iscsi_transport.
  484. **/
  485. int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
  486. {
  487. transport_unregister_device(&conn->dev);
  488. device_unregister(&conn->dev);
  489. return 0;
  490. }
  491. EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
  492. /*
  493. * iscsi interface functions
  494. */
  495. static struct iscsi_internal *
  496. iscsi_if_transport_lookup(struct iscsi_transport *tt)
  497. {
  498. struct iscsi_internal *priv;
  499. unsigned long flags;
  500. spin_lock_irqsave(&iscsi_transport_lock, flags);
  501. list_for_each_entry(priv, &iscsi_transports, list) {
  502. if (tt == priv->iscsi_transport) {
  503. spin_unlock_irqrestore(&iscsi_transport_lock, flags);
  504. return priv;
  505. }
  506. }
  507. spin_unlock_irqrestore(&iscsi_transport_lock, flags);
  508. return NULL;
  509. }
  510. static inline struct list_head *skb_to_lh(struct sk_buff *skb)
  511. {
  512. return (struct list_head *)&skb->cb;
  513. }
  514. static void
  515. mempool_zone_complete(struct mempool_zone *zone)
  516. {
  517. unsigned long flags;
  518. struct list_head *lh, *n;
  519. spin_lock_irqsave(&zone->freelock, flags);
  520. list_for_each_safe(lh, n, &zone->freequeue) {
  521. struct sk_buff *skb = (struct sk_buff *)((char *)lh -
  522. offsetof(struct sk_buff, cb));
  523. if (!skb_shared(skb)) {
  524. list_del(skb_to_lh(skb));
  525. mempool_free(skb, zone->pool);
  526. atomic_dec(&zone->allocated);
  527. }
  528. }
  529. spin_unlock_irqrestore(&zone->freelock, flags);
  530. }
  531. static struct sk_buff*
  532. mempool_zone_get_skb(struct mempool_zone *zone)
  533. {
  534. struct sk_buff *skb;
  535. skb = mempool_alloc(zone->pool, GFP_ATOMIC);
  536. if (skb)
  537. atomic_inc(&zone->allocated);
  538. return skb;
  539. }
  540. static int
  541. iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb)
  542. {
  543. unsigned long flags;
  544. int rc;
  545. skb_get(skb);
  546. rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL);
  547. if (rc < 0) {
  548. mempool_free(skb, zone->pool);
  549. printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
  550. return rc;
  551. }
  552. spin_lock_irqsave(&zone->freelock, flags);
  553. INIT_LIST_HEAD(skb_to_lh(skb));
  554. list_add(skb_to_lh(skb), &zone->freequeue);
  555. spin_unlock_irqrestore(&zone->freelock, flags);
  556. return 0;
  557. }
  558. static int
  559. iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
  560. {
  561. unsigned long flags;
  562. int rc;
  563. skb_get(skb);
  564. rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
  565. if (rc < 0) {
  566. mempool_free(skb, zone->pool);
  567. printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
  568. return rc;
  569. }
  570. spin_lock_irqsave(&zone->freelock, flags);
  571. INIT_LIST_HEAD(skb_to_lh(skb));
  572. list_add(skb_to_lh(skb), &zone->freequeue);
  573. spin_unlock_irqrestore(&zone->freelock, flags);
  574. return 0;
  575. }
  576. int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
  577. char *data, uint32_t data_size)
  578. {
  579. struct nlmsghdr *nlh;
  580. struct sk_buff *skb;
  581. struct iscsi_uevent *ev;
  582. char *pdu;
  583. struct iscsi_internal *priv;
  584. int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
  585. data_size);
  586. priv = iscsi_if_transport_lookup(conn->transport);
  587. if (!priv)
  588. return -EINVAL;
  589. mempool_zone_complete(conn->z_pdu);
  590. skb = mempool_zone_get_skb(conn->z_pdu);
  591. if (!skb) {
  592. iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
  593. dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "
  594. "control PDU: OOM\n");
  595. return -ENOMEM;
  596. }
  597. nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
  598. ev = NLMSG_DATA(nlh);
  599. memset(ev, 0, sizeof(*ev));
  600. ev->transport_handle = iscsi_handle(conn->transport);
  601. ev->type = ISCSI_KEVENT_RECV_PDU;
  602. if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
  603. ev->iferror = -ENOMEM;
  604. ev->r.recv_req.cid = conn->cid;
  605. ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
  606. pdu = (char*)ev + sizeof(*ev);
  607. memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
  608. memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
  609. return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
  610. }
  611. EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
  612. void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
  613. {
  614. struct nlmsghdr *nlh;
  615. struct sk_buff *skb;
  616. struct iscsi_uevent *ev;
  617. struct iscsi_internal *priv;
  618. int len = NLMSG_SPACE(sizeof(*ev));
  619. priv = iscsi_if_transport_lookup(conn->transport);
  620. if (!priv)
  621. return;
  622. mempool_zone_complete(conn->z_error);
  623. skb = mempool_zone_get_skb(conn->z_error);
  624. if (!skb) {
  625. dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "
  626. "conn error (%d)\n", error);
  627. return;
  628. }
  629. nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
  630. ev = NLMSG_DATA(nlh);
  631. ev->transport_handle = iscsi_handle(conn->transport);
  632. ev->type = ISCSI_KEVENT_CONN_ERROR;
  633. if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
  634. ev->iferror = -ENOMEM;
  635. ev->r.connerror.error = error;
  636. ev->r.connerror.cid = conn->cid;
  637. ev->r.connerror.sid = iscsi_conn_get_sid(conn);
  638. iscsi_broadcast_skb(conn->z_error, skb);
  639. dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
  640. error);
  641. }
  642. EXPORT_SYMBOL_GPL(iscsi_conn_error);
  643. static int
  644. iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
  645. void *payload, int size)
  646. {
  647. struct sk_buff *skb;
  648. struct nlmsghdr *nlh;
  649. int len = NLMSG_SPACE(size);
  650. int flags = multi ? NLM_F_MULTI : 0;
  651. int t = done ? NLMSG_DONE : type;
  652. mempool_zone_complete(z_reply);
  653. skb = mempool_zone_get_skb(z_reply);
  654. /*
  655. * FIXME:
  656. * user is supposed to react on iferror == -ENOMEM;
  657. * see iscsi_if_rx().
  658. */
  659. BUG_ON(!skb);
  660. nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
  661. nlh->nlmsg_flags = flags;
  662. memcpy(NLMSG_DATA(nlh), payload, size);
  663. return iscsi_unicast_skb(z_reply, skb, pid);
  664. }
  665. static int
  666. iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
  667. {
  668. struct iscsi_uevent *ev = NLMSG_DATA(nlh);
  669. struct iscsi_stats *stats;
  670. struct sk_buff *skbstat;
  671. struct iscsi_cls_conn *conn;
  672. struct nlmsghdr *nlhstat;
  673. struct iscsi_uevent *evstat;
  674. struct iscsi_internal *priv;
  675. int len = NLMSG_SPACE(sizeof(*ev) +
  676. sizeof(struct iscsi_stats) +
  677. sizeof(struct iscsi_stats_custom) *
  678. ISCSI_STATS_CUSTOM_MAX);
  679. int err = 0;
  680. priv = iscsi_if_transport_lookup(transport);
  681. if (!priv)
  682. return -EINVAL;
  683. conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
  684. if (!conn)
  685. return -EEXIST;
  686. do {
  687. int actual_size;
  688. mempool_zone_complete(conn->z_pdu);
  689. skbstat = mempool_zone_get_skb(conn->z_pdu);
  690. if (!skbstat) {
  691. dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "
  692. "deliver stats: OOM\n");
  693. return -ENOMEM;
  694. }
  695. nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0,
  696. (len - sizeof(*nlhstat)), 0);
  697. evstat = NLMSG_DATA(nlhstat);
  698. memset(evstat, 0, sizeof(*evstat));
  699. evstat->transport_handle = iscsi_handle(conn->transport);
  700. evstat->type = nlh->nlmsg_type;
  701. if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
  702. evstat->iferror = -ENOMEM;
  703. evstat->u.get_stats.cid =
  704. ev->u.get_stats.cid;
  705. evstat->u.get_stats.sid =
  706. ev->u.get_stats.sid;
  707. stats = (struct iscsi_stats *)
  708. ((char*)evstat + sizeof(*evstat));
  709. memset(stats, 0, sizeof(*stats));
  710. transport->get_stats(conn, stats);
  711. actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) +
  712. sizeof(struct iscsi_stats) +
  713. sizeof(struct iscsi_stats_custom) *
  714. stats->custom_length);
  715. actual_size -= sizeof(*nlhstat);
  716. actual_size = NLMSG_LENGTH(actual_size);
  717. skb_trim(skbstat, NLMSG_ALIGN(actual_size));
  718. nlhstat->nlmsg_len = actual_size;
  719. err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
  720. } while (err < 0 && err != -ECONNREFUSED);
  721. return err;
  722. }
  723. /**
  724. * iscsi_if_destroy_session_done - send session destr. completion event
  725. * @conn: last connection for session
  726. *
  727. * This is called by HW iscsi LLDs to notify userpsace that its HW has
  728. * removed a session.
  729. **/
  730. int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn)
  731. {
  732. struct iscsi_internal *priv;
  733. struct iscsi_cls_session *session;
  734. struct Scsi_Host *shost;
  735. struct iscsi_uevent *ev;
  736. struct sk_buff *skb;
  737. struct nlmsghdr *nlh;
  738. unsigned long flags;
  739. int rc, len = NLMSG_SPACE(sizeof(*ev));
  740. priv = iscsi_if_transport_lookup(conn->transport);
  741. if (!priv)
  742. return -EINVAL;
  743. session = iscsi_dev_to_session(conn->dev.parent);
  744. shost = iscsi_session_to_shost(session);
  745. mempool_zone_complete(conn->z_pdu);
  746. skb = mempool_zone_get_skb(conn->z_pdu);
  747. if (!skb) {
  748. dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
  749. "session creation event\n");
  750. return -ENOMEM;
  751. }
  752. nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
  753. ev = NLMSG_DATA(nlh);
  754. ev->transport_handle = iscsi_handle(conn->transport);
  755. ev->type = ISCSI_KEVENT_DESTROY_SESSION;
  756. ev->r.d_session.host_no = shost->host_no;
  757. ev->r.d_session.sid = session->sid;
  758. /*
  759. * this will occur if the daemon is not up, so we just warn
  760. * the user and when the daemon is restarted it will handle it
  761. */
  762. rc = iscsi_broadcast_skb(conn->z_pdu, skb);
  763. if (rc < 0)
  764. dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
  765. "session destruction event. Check iscsi daemon\n");
  766. spin_lock_irqsave(&sesslock, flags);
  767. list_del(&session->sess_list);
  768. spin_unlock_irqrestore(&sesslock, flags);
  769. spin_lock_irqsave(&connlock, flags);
  770. conn->active = 0;
  771. list_del(&conn->conn_list);
  772. spin_unlock_irqrestore(&connlock, flags);
  773. return rc;
  774. }
  775. EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done);
  776. /**
  777. * iscsi_if_create_session_done - send session creation completion event
  778. * @conn: leading connection for session
  779. *
  780. * This is called by HW iscsi LLDs to notify userpsace that its HW has
  781. * created a session or a existing session is back in the logged in state.
  782. **/
  783. int iscsi_if_create_session_done(struct iscsi_cls_conn *conn)
  784. {
  785. struct iscsi_internal *priv;
  786. struct iscsi_cls_session *session;
  787. struct Scsi_Host *shost;
  788. struct iscsi_uevent *ev;
  789. struct sk_buff *skb;
  790. struct nlmsghdr *nlh;
  791. unsigned long flags;
  792. int rc, len = NLMSG_SPACE(sizeof(*ev));
  793. priv = iscsi_if_transport_lookup(conn->transport);
  794. if (!priv)
  795. return -EINVAL;
  796. session = iscsi_dev_to_session(conn->dev.parent);
  797. shost = iscsi_session_to_shost(session);
  798. mempool_zone_complete(conn->z_pdu);
  799. skb = mempool_zone_get_skb(conn->z_pdu);
  800. if (!skb) {
  801. dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
  802. "session creation event\n");
  803. return -ENOMEM;
  804. }
  805. nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
  806. ev = NLMSG_DATA(nlh);
  807. ev->transport_handle = iscsi_handle(conn->transport);
  808. ev->type = ISCSI_UEVENT_CREATE_SESSION;
  809. ev->r.c_session_ret.host_no = shost->host_no;
  810. ev->r.c_session_ret.sid = session->sid;
  811. /*
  812. * this will occur if the daemon is not up, so we just warn
  813. * the user and when the daemon is restarted it will handle it
  814. */
  815. rc = iscsi_broadcast_skb(conn->z_pdu, skb);
  816. if (rc < 0)
  817. dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
  818. "session creation event. Check iscsi daemon\n");
  819. spin_lock_irqsave(&sesslock, flags);
  820. list_add(&session->sess_list, &sesslist);
  821. spin_unlock_irqrestore(&sesslock, flags);
  822. spin_lock_irqsave(&connlock, flags);
  823. list_add(&conn->conn_list, &connlist);
  824. conn->active = 1;
  825. spin_unlock_irqrestore(&connlock, flags);
  826. return rc;
  827. }
  828. EXPORT_SYMBOL_GPL(iscsi_if_create_session_done);
  829. static int
  830. iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
  831. {
  832. struct iscsi_transport *transport = priv->iscsi_transport;
  833. struct iscsi_cls_session *session;
  834. unsigned long flags;
  835. uint32_t hostno;
  836. session = transport->create_session(transport, &priv->t,
  837. ev->u.c_session.initial_cmdsn,
  838. &hostno);
  839. if (!session)
  840. return -ENOMEM;
  841. spin_lock_irqsave(&sesslock, flags);
  842. list_add(&session->sess_list, &sesslist);
  843. spin_unlock_irqrestore(&sesslock, flags);
  844. ev->r.c_session_ret.host_no = hostno;
  845. ev->r.c_session_ret.sid = session->sid;
  846. return 0;
  847. }
  848. static int
  849. iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
  850. {
  851. struct iscsi_cls_conn *conn;
  852. struct iscsi_cls_session *session;
  853. unsigned long flags;
  854. session = iscsi_session_lookup(ev->u.c_conn.sid);
  855. if (!session) {
  856. printk(KERN_ERR "iscsi: invalid session %d\n",
  857. ev->u.c_conn.sid);
  858. return -EINVAL;
  859. }
  860. conn = transport->create_conn(session, ev->u.c_conn.cid);
  861. if (!conn) {
  862. printk(KERN_ERR "iscsi: couldn't create a new "
  863. "connection for session %d\n",
  864. session->sid);
  865. return -ENOMEM;
  866. }
  867. ev->r.c_conn_ret.sid = session->sid;
  868. ev->r.c_conn_ret.cid = conn->cid;
  869. spin_lock_irqsave(&connlock, flags);
  870. list_add(&conn->conn_list, &connlist);
  871. conn->active = 1;
  872. spin_unlock_irqrestore(&connlock, flags);
  873. return 0;
  874. }
  875. static int
  876. iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
  877. {
  878. unsigned long flags;
  879. struct iscsi_cls_conn *conn;
  880. conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
  881. if (!conn)
  882. return -EINVAL;
  883. spin_lock_irqsave(&connlock, flags);
  884. conn->active = 0;
  885. list_del(&conn->conn_list);
  886. spin_unlock_irqrestore(&connlock, flags);
  887. if (transport->destroy_conn)
  888. transport->destroy_conn(conn);
  889. return 0;
  890. }
  891. static int
  892. iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
  893. {
  894. char *data = (char*)ev + sizeof(*ev);
  895. struct iscsi_cls_conn *conn;
  896. struct iscsi_cls_session *session;
  897. int err = 0, value = 0;
  898. session = iscsi_session_lookup(ev->u.set_param.sid);
  899. conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
  900. if (!conn || !session)
  901. return -EINVAL;
  902. switch (ev->u.set_param.param) {
  903. case ISCSI_PARAM_SESS_RECOVERY_TMO:
  904. sscanf(data, "%d", &value);
  905. if (value != 0)
  906. session->recovery_tmo = value;
  907. break;
  908. default:
  909. err = transport->set_param(conn, ev->u.set_param.param,
  910. data, ev->u.set_param.len);
  911. }
  912. return err;
  913. }
  914. static int
  915. iscsi_if_transport_ep(struct iscsi_transport *transport,
  916. struct iscsi_uevent *ev, int msg_type)
  917. {
  918. struct sockaddr *dst_addr;
  919. int rc = 0;
  920. switch (msg_type) {
  921. case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
  922. if (!transport->ep_connect)
  923. return -EINVAL;
  924. dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
  925. rc = transport->ep_connect(dst_addr,
  926. ev->u.ep_connect.non_blocking,
  927. &ev->r.ep_connect_ret.handle);
  928. break;
  929. case ISCSI_UEVENT_TRANSPORT_EP_POLL:
  930. if (!transport->ep_poll)
  931. return -EINVAL;
  932. ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle,
  933. ev->u.ep_poll.timeout_ms);
  934. break;
  935. case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
  936. if (!transport->ep_disconnect)
  937. return -EINVAL;
  938. transport->ep_disconnect(ev->u.ep_disconnect.ep_handle);
  939. break;
  940. }
  941. return rc;
  942. }
  943. static int
  944. iscsi_tgt_dscvr(struct iscsi_transport *transport,
  945. struct iscsi_uevent *ev)
  946. {
  947. struct sockaddr *dst_addr;
  948. if (!transport->tgt_dscvr)
  949. return -EINVAL;
  950. dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
  951. return transport->tgt_dscvr(ev->u.tgt_dscvr.type,
  952. ev->u.tgt_dscvr.host_no,
  953. ev->u.tgt_dscvr.enable, dst_addr);
  954. }
  955. static int
  956. iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  957. {
  958. int err = 0;
  959. struct iscsi_uevent *ev = NLMSG_DATA(nlh);
  960. struct iscsi_transport *transport = NULL;
  961. struct iscsi_internal *priv;
  962. struct iscsi_cls_session *session;
  963. struct iscsi_cls_conn *conn;
  964. unsigned long flags;
  965. priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
  966. if (!priv)
  967. return -EINVAL;
  968. transport = priv->iscsi_transport;
  969. if (!try_module_get(transport->owner))
  970. return -EINVAL;
  971. priv->daemon_pid = NETLINK_CREDS(skb)->pid;
  972. switch (nlh->nlmsg_type) {
  973. case ISCSI_UEVENT_CREATE_SESSION:
  974. err = iscsi_if_create_session(priv, ev);
  975. break;
  976. case ISCSI_UEVENT_DESTROY_SESSION:
  977. session = iscsi_session_lookup(ev->u.d_session.sid);
  978. if (session) {
  979. spin_lock_irqsave(&sesslock, flags);
  980. list_del(&session->sess_list);
  981. spin_unlock_irqrestore(&sesslock, flags);
  982. transport->destroy_session(session);
  983. } else
  984. err = -EINVAL;
  985. break;
  986. case ISCSI_UEVENT_CREATE_CONN:
  987. err = iscsi_if_create_conn(transport, ev);
  988. break;
  989. case ISCSI_UEVENT_DESTROY_CONN:
  990. err = iscsi_if_destroy_conn(transport, ev);
  991. break;
  992. case ISCSI_UEVENT_BIND_CONN:
  993. session = iscsi_session_lookup(ev->u.b_conn.sid);
  994. conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
  995. if (session && conn)
  996. ev->r.retcode = transport->bind_conn(session, conn,
  997. ev->u.b_conn.transport_eph,
  998. ev->u.b_conn.is_leading);
  999. else
  1000. err = -EINVAL;
  1001. break;
  1002. case ISCSI_UEVENT_SET_PARAM:
  1003. err = iscsi_set_param(transport, ev);
  1004. break;
  1005. case ISCSI_UEVENT_START_CONN:
  1006. conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
  1007. if (conn)
  1008. ev->r.retcode = transport->start_conn(conn);
  1009. else
  1010. err = -EINVAL;
  1011. break;
  1012. case ISCSI_UEVENT_STOP_CONN:
  1013. conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
  1014. if (conn)
  1015. transport->stop_conn(conn, ev->u.stop_conn.flag);
  1016. else
  1017. err = -EINVAL;
  1018. break;
  1019. case ISCSI_UEVENT_SEND_PDU:
  1020. conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
  1021. if (conn)
  1022. ev->r.retcode = transport->send_pdu(conn,
  1023. (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
  1024. (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
  1025. ev->u.send_pdu.data_size);
  1026. else
  1027. err = -EINVAL;
  1028. break;
  1029. case ISCSI_UEVENT_GET_STATS:
  1030. err = iscsi_if_get_stats(transport, nlh);
  1031. break;
  1032. case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
  1033. case ISCSI_UEVENT_TRANSPORT_EP_POLL:
  1034. case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
  1035. err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
  1036. break;
  1037. case ISCSI_UEVENT_TGT_DSCVR:
  1038. err = iscsi_tgt_dscvr(transport, ev);
  1039. break;
  1040. default:
  1041. err = -EINVAL;
  1042. break;
  1043. }
  1044. module_put(transport->owner);
  1045. return err;
  1046. }
  1047. /*
  1048. * Get message from skb (based on rtnetlink_rcv_skb). Each message is
  1049. * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or
  1050. * invalid creds are discarded silently.
  1051. */
  1052. static void
  1053. iscsi_if_rx(struct sock *sk, int len)
  1054. {
  1055. struct sk_buff *skb;
  1056. mutex_lock(&rx_queue_mutex);
  1057. while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
  1058. if (NETLINK_CREDS(skb)->uid) {
  1059. skb_pull(skb, skb->len);
  1060. goto free_skb;
  1061. }
  1062. while (skb->len >= NLMSG_SPACE(0)) {
  1063. int err;
  1064. uint32_t rlen;
  1065. struct nlmsghdr *nlh;
  1066. struct iscsi_uevent *ev;
  1067. nlh = (struct nlmsghdr *)skb->data;
  1068. if (nlh->nlmsg_len < sizeof(*nlh) ||
  1069. skb->len < nlh->nlmsg_len) {
  1070. break;
  1071. }
  1072. ev = NLMSG_DATA(nlh);
  1073. rlen = NLMSG_ALIGN(nlh->nlmsg_len);
  1074. if (rlen > skb->len)
  1075. rlen = skb->len;
  1076. err = iscsi_if_recv_msg(skb, nlh);
  1077. if (err) {
  1078. ev->type = ISCSI_KEVENT_IF_ERROR;
  1079. ev->iferror = err;
  1080. }
  1081. do {
  1082. /*
  1083. * special case for GET_STATS:
  1084. * on success - sending reply and stats from
  1085. * inside of if_recv_msg(),
  1086. * on error - fall through.
  1087. */
  1088. if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
  1089. break;
  1090. err = iscsi_if_send_reply(
  1091. NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
  1092. nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
  1093. if (atomic_read(&z_reply->allocated) >=
  1094. z_reply->hiwat)
  1095. ev->iferror = -ENOMEM;
  1096. } while (err < 0 && err != -ECONNREFUSED);
  1097. skb_pull(skb, rlen);
  1098. }
  1099. free_skb:
  1100. kfree_skb(skb);
  1101. }
  1102. mutex_unlock(&rx_queue_mutex);
  1103. }
  1104. #define iscsi_cdev_to_conn(_cdev) \
  1105. iscsi_dev_to_conn(_cdev->dev)
  1106. #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \
  1107. struct class_device_attribute class_device_attr_##_prefix##_##_name = \
  1108. __ATTR(_name,_mode,_show,_store)
  1109. /*
  1110. * iSCSI connection attrs
  1111. */
  1112. #define iscsi_conn_attr_show(param) \
  1113. static ssize_t \
  1114. show_conn_param_##param(struct class_device *cdev, char *buf) \
  1115. { \
  1116. struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
  1117. struct iscsi_transport *t = conn->transport; \
  1118. return t->get_conn_param(conn, param, buf); \
  1119. }
  1120. #define iscsi_conn_attr(field, param) \
  1121. iscsi_conn_attr_show(param) \
  1122. static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \
  1123. NULL);
  1124. iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
  1125. iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
  1126. iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN);
  1127. iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN);
  1128. iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN);
  1129. iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN);
  1130. iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT);
  1131. iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT);
  1132. iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
  1133. iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
  1134. iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
  1135. #define iscsi_cdev_to_session(_cdev) \
  1136. iscsi_dev_to_session(_cdev->dev)
  1137. /*
  1138. * iSCSI session attrs
  1139. */
  1140. #define iscsi_session_attr_show(param) \
  1141. static ssize_t \
  1142. show_session_param_##param(struct class_device *cdev, char *buf) \
  1143. { \
  1144. struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
  1145. struct iscsi_transport *t = session->transport; \
  1146. return t->get_session_param(session, param, buf); \
  1147. }
  1148. #define iscsi_session_attr(field, param) \
  1149. iscsi_session_attr_show(param) \
  1150. static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \
  1151. NULL);
  1152. iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME);
  1153. iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
  1154. iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
  1155. iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
  1156. iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST);
  1157. iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST);
  1158. iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
  1159. iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN);
  1160. iscsi_session_attr(erl, ISCSI_PARAM_ERL);
  1161. iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT);
  1162. #define iscsi_priv_session_attr_show(field, format) \
  1163. static ssize_t \
  1164. show_priv_session_##field(struct class_device *cdev, char *buf) \
  1165. { \
  1166. struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
  1167. return sprintf(buf, format"\n", session->field); \
  1168. }
  1169. #define iscsi_priv_session_attr(field, format) \
  1170. iscsi_priv_session_attr_show(field, format) \
  1171. static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
  1172. NULL)
  1173. iscsi_priv_session_attr(recovery_tmo, "%d");
  1174. #define SETUP_PRIV_SESSION_RD_ATTR(field) \
  1175. do { \
  1176. priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
  1177. count++; \
  1178. } while (0)
  1179. #define SETUP_SESSION_RD_ATTR(field, param_flag) \
  1180. do { \
  1181. if (tt->param_mask & param_flag) { \
  1182. priv->session_attrs[count] = &class_device_attr_sess_##field; \
  1183. count++; \
  1184. } \
  1185. } while (0)
  1186. #define SETUP_CONN_RD_ATTR(field, param_flag) \
  1187. do { \
  1188. if (tt->param_mask & param_flag) { \
  1189. priv->conn_attrs[count] = &class_device_attr_conn_##field; \
  1190. count++; \
  1191. } \
  1192. } while (0)
  1193. static int iscsi_session_match(struct attribute_container *cont,
  1194. struct device *dev)
  1195. {
  1196. struct iscsi_cls_session *session;
  1197. struct Scsi_Host *shost;
  1198. struct iscsi_internal *priv;
  1199. if (!iscsi_is_session_dev(dev))
  1200. return 0;
  1201. session = iscsi_dev_to_session(dev);
  1202. shost = iscsi_session_to_shost(session);
  1203. if (!shost->transportt)
  1204. return 0;
  1205. priv = to_iscsi_internal(shost->transportt);
  1206. if (priv->session_cont.ac.class != &iscsi_session_class.class)
  1207. return 0;
  1208. return &priv->session_cont.ac == cont;
  1209. }
  1210. static int iscsi_conn_match(struct attribute_container *cont,
  1211. struct device *dev)
  1212. {
  1213. struct iscsi_cls_session *session;
  1214. struct iscsi_cls_conn *conn;
  1215. struct Scsi_Host *shost;
  1216. struct iscsi_internal *priv;
  1217. if (!iscsi_is_conn_dev(dev))
  1218. return 0;
  1219. conn = iscsi_dev_to_conn(dev);
  1220. session = iscsi_dev_to_session(conn->dev.parent);
  1221. shost = iscsi_session_to_shost(session);
  1222. if (!shost->transportt)
  1223. return 0;
  1224. priv = to_iscsi_internal(shost->transportt);
  1225. if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
  1226. return 0;
  1227. return &priv->conn_cont.ac == cont;
  1228. }
  1229. static int iscsi_host_match(struct attribute_container *cont,
  1230. struct device *dev)
  1231. {
  1232. struct Scsi_Host *shost;
  1233. struct iscsi_internal *priv;
  1234. if (!scsi_is_host_device(dev))
  1235. return 0;
  1236. shost = dev_to_shost(dev);
  1237. if (!shost->transportt ||
  1238. shost->transportt->host_attrs.ac.class != &iscsi_host_class.class)
  1239. return 0;
  1240. priv = to_iscsi_internal(shost->transportt);
  1241. return &priv->t.host_attrs.ac == cont;
  1242. }
  1243. struct scsi_transport_template *
  1244. iscsi_register_transport(struct iscsi_transport *tt)
  1245. {
  1246. struct iscsi_internal *priv;
  1247. unsigned long flags;
  1248. int count = 0, err;
  1249. BUG_ON(!tt);
  1250. priv = iscsi_if_transport_lookup(tt);
  1251. if (priv)
  1252. return NULL;
  1253. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  1254. if (!priv)
  1255. return NULL;
  1256. INIT_LIST_HEAD(&priv->list);
  1257. priv->daemon_pid = -1;
  1258. priv->iscsi_transport = tt;
  1259. priv->t.user_scan = iscsi_user_scan;
  1260. priv->cdev.class = &iscsi_transport_class;
  1261. snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
  1262. err = class_device_register(&priv->cdev);
  1263. if (err)
  1264. goto free_priv;
  1265. err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
  1266. if (err)
  1267. goto unregister_cdev;
  1268. /* host parameters */
  1269. priv->t.host_attrs.ac.attrs = &priv->host_attrs[0];
  1270. priv->t.host_attrs.ac.class = &iscsi_host_class.class;
  1271. priv->t.host_attrs.ac.match = iscsi_host_match;
  1272. priv->t.host_size = sizeof(struct iscsi_host);
  1273. priv->host_attrs[0] = NULL;
  1274. transport_container_register(&priv->t.host_attrs);
  1275. /* connection parameters */
  1276. priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
  1277. priv->conn_cont.ac.class = &iscsi_connection_class.class;
  1278. priv->conn_cont.ac.match = iscsi_conn_match;
  1279. transport_container_register(&priv->conn_cont);
  1280. SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH);
  1281. SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH);
  1282. SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN);
  1283. SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN);
  1284. SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN);
  1285. SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
  1286. SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
  1287. SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
  1288. SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
  1289. SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
  1290. SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
  1291. BUG_ON(count > ISCSI_CONN_ATTRS);
  1292. priv->conn_attrs[count] = NULL;
  1293. count = 0;
  1294. /* session parameters */
  1295. priv->session_cont.ac.attrs = &priv->session_attrs[0];
  1296. priv->session_cont.ac.class = &iscsi_session_class.class;
  1297. priv->session_cont.ac.match = iscsi_session_match;
  1298. transport_container_register(&priv->session_cont);
  1299. SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN);
  1300. SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T);
  1301. SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN);
  1302. SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST);
  1303. SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST);
  1304. SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN);
  1305. SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN);
  1306. SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL);
  1307. SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
  1308. SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
  1309. SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
  1310. BUG_ON(count > ISCSI_SESSION_ATTRS);
  1311. priv->session_attrs[count] = NULL;
  1312. spin_lock_irqsave(&iscsi_transport_lock, flags);
  1313. list_add(&priv->list, &iscsi_transports);
  1314. spin_unlock_irqrestore(&iscsi_transport_lock, flags);
  1315. printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
  1316. return &priv->t;
  1317. unregister_cdev:
  1318. class_device_unregister(&priv->cdev);
  1319. free_priv:
  1320. kfree(priv);
  1321. return NULL;
  1322. }
  1323. EXPORT_SYMBOL_GPL(iscsi_register_transport);
  1324. int iscsi_unregister_transport(struct iscsi_transport *tt)
  1325. {
  1326. struct iscsi_internal *priv;
  1327. unsigned long flags;
  1328. BUG_ON(!tt);
  1329. mutex_lock(&rx_queue_mutex);
  1330. priv = iscsi_if_transport_lookup(tt);
  1331. BUG_ON (!priv);
  1332. spin_lock_irqsave(&iscsi_transport_lock, flags);
  1333. list_del(&priv->list);
  1334. spin_unlock_irqrestore(&iscsi_transport_lock, flags);
  1335. transport_container_unregister(&priv->conn_cont);
  1336. transport_container_unregister(&priv->session_cont);
  1337. transport_container_unregister(&priv->t.host_attrs);
  1338. sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
  1339. class_device_unregister(&priv->cdev);
  1340. mutex_unlock(&rx_queue_mutex);
  1341. return 0;
  1342. }
  1343. EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
  1344. static int
  1345. iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
  1346. {
  1347. struct netlink_notify *n = ptr;
  1348. if (event == NETLINK_URELEASE &&
  1349. n->protocol == NETLINK_ISCSI && n->pid) {
  1350. struct iscsi_cls_conn *conn;
  1351. unsigned long flags;
  1352. mempool_zone_complete(z_reply);
  1353. spin_lock_irqsave(&connlock, flags);
  1354. list_for_each_entry(conn, &connlist, conn_list) {
  1355. mempool_zone_complete(conn->z_error);
  1356. mempool_zone_complete(conn->z_pdu);
  1357. }
  1358. spin_unlock_irqrestore(&connlock, flags);
  1359. }
  1360. return NOTIFY_DONE;
  1361. }
  1362. static struct notifier_block iscsi_nl_notifier = {
  1363. .notifier_call = iscsi_rcv_nl_event,
  1364. };
  1365. static __init int iscsi_transport_init(void)
  1366. {
  1367. int err;
  1368. err = class_register(&iscsi_transport_class);
  1369. if (err)
  1370. return err;
  1371. err = transport_class_register(&iscsi_host_class);
  1372. if (err)
  1373. goto unregister_transport_class;
  1374. err = transport_class_register(&iscsi_connection_class);
  1375. if (err)
  1376. goto unregister_host_class;
  1377. err = transport_class_register(&iscsi_session_class);
  1378. if (err)
  1379. goto unregister_conn_class;
  1380. err = netlink_register_notifier(&iscsi_nl_notifier);
  1381. if (err)
  1382. goto unregister_session_class;
  1383. nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
  1384. THIS_MODULE);
  1385. if (!nls) {
  1386. err = -ENOBUFS;
  1387. goto unregister_notifier;
  1388. }
  1389. z_reply = mempool_zone_init(Z_MAX_REPLY,
  1390. NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
  1391. if (z_reply)
  1392. return 0;
  1393. sock_release(nls->sk_socket);
  1394. unregister_notifier:
  1395. netlink_unregister_notifier(&iscsi_nl_notifier);
  1396. unregister_session_class:
  1397. transport_class_unregister(&iscsi_session_class);
  1398. unregister_conn_class:
  1399. transport_class_unregister(&iscsi_connection_class);
  1400. unregister_host_class:
  1401. transport_class_unregister(&iscsi_host_class);
  1402. unregister_transport_class:
  1403. class_unregister(&iscsi_transport_class);
  1404. return err;
  1405. }
  1406. static void __exit iscsi_transport_exit(void)
  1407. {
  1408. mempool_zone_destroy(z_reply);
  1409. sock_release(nls->sk_socket);
  1410. netlink_unregister_notifier(&iscsi_nl_notifier);
  1411. transport_class_unregister(&iscsi_connection_class);
  1412. transport_class_unregister(&iscsi_session_class);
  1413. transport_class_unregister(&iscsi_host_class);
  1414. class_unregister(&iscsi_transport_class);
  1415. }
  1416. module_init(iscsi_transport_init);
  1417. module_exit(iscsi_transport_exit);
  1418. MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
  1419. "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
  1420. "Alex Aizman <itn780@yahoo.com>");
  1421. MODULE_DESCRIPTION("iSCSI Transport Interface");
  1422. MODULE_LICENSE("GPL");