net.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. /*
  2. * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <linux/fsnotify.h>
  16. #include <linux/jhash.h>
  17. #include <linux/in.h>
  18. #include <linux/in6.h>
  19. #include <linux/kthread.h>
  20. #include <linux/pagemap.h>
  21. #include <linux/poll.h>
  22. #include <linux/slab.h>
  23. #include <linux/swap.h>
  24. #include <linux/syscalls.h>
  25. #include <linux/vmalloc.h>
  26. #include "netfs.h"
  27. /*
  28. * Async machinery lives here.
  29. * All commands being sent to server do _not_ require sync reply,
  30. * instead, if it is really needed, like readdir or readpage, caller
  31. * sleeps waiting for data, which will be placed into provided buffer
  32. * and caller will be awakened.
  33. *
  34. * Every command response can come without some listener. For example
  35. * readdir response will add new objects into cache without appropriate
  36. * request from userspace. This is used in cache coherency.
  37. *
  38. * If object is not found for given data, it is discarded.
  39. *
  40. * All requests are received by dedicated kernel thread.
  41. */
  42. /*
  43. * Basic network sending/receiving functions.
  44. * Blocked mode is used.
  45. */
  46. static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
  47. {
  48. struct msghdr msg;
  49. struct kvec iov;
  50. int err;
  51. BUG_ON(!size);
  52. iov.iov_base = buf;
  53. iov.iov_len = size;
  54. msg.msg_iov = (struct iovec *)&iov;
  55. msg.msg_iovlen = 1;
  56. msg.msg_name = NULL;
  57. msg.msg_namelen = 0;
  58. msg.msg_control = NULL;
  59. msg.msg_controllen = 0;
  60. msg.msg_flags = MSG_DONTWAIT;
  61. err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
  62. msg.msg_flags);
  63. if (err <= 0) {
  64. printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
  65. if (err == 0)
  66. err = -ECONNRESET;
  67. }
  68. return err;
  69. }
  70. static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
  71. {
  72. unsigned int revents = 0;
  73. unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
  74. unsigned int mask = err_mask | POLLIN;
  75. int err = 0;
  76. while (size && !err) {
  77. revents = netfs_state_poll(st);
  78. if (!(revents & mask)) {
  79. DEFINE_WAIT(wait);
  80. for (;;) {
  81. prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
  82. if (kthread_should_stop())
  83. break;
  84. revents = netfs_state_poll(st);
  85. if (revents & mask)
  86. break;
  87. if (signal_pending(current))
  88. break;
  89. schedule();
  90. continue;
  91. }
  92. finish_wait(&st->thread_wait, &wait);
  93. }
  94. err = 0;
  95. netfs_state_lock(st);
  96. if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
  97. err = netfs_data_recv(st, data, size);
  98. if (err > 0) {
  99. data += err;
  100. size -= err;
  101. err = 0;
  102. } else if (err == 0)
  103. err = -ECONNRESET;
  104. }
  105. if (revents & err_mask) {
  106. printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
  107. __func__, revents, st->socket, size, err);
  108. err = -ECONNRESET;
  109. }
  110. netfs_state_unlock(st);
  111. if (err < 0) {
  112. if (netfs_state_trylock_send(st)) {
  113. netfs_state_exit(st);
  114. err = netfs_state_init(st);
  115. if (!err)
  116. err = -EAGAIN;
  117. netfs_state_unlock_send(st);
  118. } else {
  119. st->need_reset = 1;
  120. }
  121. }
  122. if (kthread_should_stop())
  123. err = -ENODEV;
  124. if (err)
  125. printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
  126. "should_stop: %d, size: %u, err: %d.\n",
  127. __func__, st->socket, st->read_socket,
  128. revents, revents & err_mask, kthread_should_stop(), size, err);
  129. }
  130. return err;
  131. }
  132. int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
  133. {
  134. struct netfs_cmd *cmd = &st->cmd;
  135. int err;
  136. err = pohmelfs_data_recv(st, data, size);
  137. if (err)
  138. return err;
  139. return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
  140. }
  141. /*
  142. * Polling machinery.
  143. */
  144. struct netfs_poll_helper {
  145. poll_table pt;
  146. struct netfs_state *st;
  147. };
  148. static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
  149. {
  150. struct netfs_state *st = container_of(wait, struct netfs_state, wait);
  151. wake_up(&st->thread_wait);
  152. return 1;
  153. }
  154. static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
  155. poll_table *pt)
  156. {
  157. struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
  158. st->whead = whead;
  159. init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
  160. add_wait_queue(whead, &st->wait);
  161. }
  162. static void netfs_poll_exit(struct netfs_state *st)
  163. {
  164. if (st->whead) {
  165. remove_wait_queue(st->whead, &st->wait);
  166. st->whead = NULL;
  167. }
  168. }
  169. static int netfs_poll_init(struct netfs_state *st)
  170. {
  171. struct netfs_poll_helper ph;
  172. ph.st = st;
  173. init_poll_funcptr(&ph.pt, &netfs_queue_func);
  174. st->socket->ops->poll(NULL, st->socket, &ph.pt);
  175. return 0;
  176. }
  177. /*
  178. * Get response for readpage command. We search inode and page in its mapping
  179. * and copy data into. If it was async request, then we queue page into shared
  180. * data and wakeup listener, who will copy it to userspace.
  181. *
  182. * There is a work in progress of allowing to call copy_to_user() directly from
  183. * async receiving kernel thread.
  184. */
  185. static int pohmelfs_read_page_response(struct netfs_state *st)
  186. {
  187. struct pohmelfs_sb *psb = st->psb;
  188. struct netfs_cmd *cmd = &st->cmd;
  189. struct inode *inode;
  190. struct page *page;
  191. int err = 0;
  192. if (cmd->size > PAGE_CACHE_SIZE) {
  193. err = -EINVAL;
  194. goto err_out_exit;
  195. }
  196. inode = ilookup(st->psb->sb, cmd->id);
  197. if (!inode) {
  198. printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
  199. err = -ENOENT;
  200. goto err_out_exit;
  201. }
  202. page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
  203. if (!page || !PageLocked(page)) {
  204. printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
  205. __func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
  206. while (cmd->size) {
  207. unsigned int sz = min(cmd->size, st->size);
  208. err = pohmelfs_data_recv(st, st->data, sz);
  209. if (err)
  210. break;
  211. cmd->size -= sz;
  212. }
  213. err = -ENODEV;
  214. if (page)
  215. goto err_out_page_put;
  216. goto err_out_put;
  217. }
  218. if (cmd->size) {
  219. void *addr;
  220. addr = kmap(page);
  221. err = pohmelfs_data_recv(st, addr, cmd->size);
  222. kunmap(page);
  223. if (err)
  224. goto err_out_page_unlock;
  225. }
  226. dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
  227. __func__, page, cmd->start, cmd->size, PageLocked(page));
  228. SetPageChecked(page);
  229. if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
  230. err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
  231. if (err < 0)
  232. goto err_out_page_unlock;
  233. } else {
  234. SetPageUptodate(page);
  235. unlock_page(page);
  236. page_cache_release(page);
  237. }
  238. pohmelfs_put_inode(POHMELFS_I(inode));
  239. wake_up(&st->psb->wait);
  240. return 0;
  241. err_out_page_unlock:
  242. SetPageError(page);
  243. unlock_page(page);
  244. err_out_page_put:
  245. page_cache_release(page);
  246. err_out_put:
  247. pohmelfs_put_inode(POHMELFS_I(inode));
  248. err_out_exit:
  249. wake_up(&st->psb->wait);
  250. return err;
  251. }
  252. static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
  253. struct netfs_inode_info *info)
  254. {
  255. struct inode *inode;
  256. struct pohmelfs_name *n;
  257. int err = 0;
  258. u64 ino = 0;
  259. mutex_lock(&parent->offset_lock);
  260. n = pohmelfs_search_hash(parent, str->hash);
  261. if (n)
  262. ino = n->ino;
  263. mutex_unlock(&parent->offset_lock);
  264. if (!ino)
  265. goto out;
  266. inode = ilookup(parent->vfs_inode.i_sb, ino);
  267. if (!inode)
  268. goto out;
  269. dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
  270. pohmelfs_fill_inode(inode, info);
  271. pohmelfs_put_inode(POHMELFS_I(inode));
  272. err = -EEXIST;
  273. out:
  274. return err;
  275. }
  276. /*
  277. * Readdir response from server. If special field is set, we wakeup
  278. * listener (readdir() call), which will copy data to userspace.
  279. */
  280. static int pohmelfs_readdir_response(struct netfs_state *st)
  281. {
  282. struct inode *inode;
  283. struct netfs_cmd *cmd = &st->cmd;
  284. struct netfs_inode_info *info;
  285. struct pohmelfs_inode *parent = NULL, *npi;
  286. int err = 0, last = cmd->ext;
  287. struct qstr str;
  288. if (cmd->size > st->size)
  289. return -EINVAL;
  290. inode = ilookup(st->psb->sb, cmd->id);
  291. if (!inode) {
  292. printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
  293. return -ENOENT;
  294. }
  295. parent = POHMELFS_I(inode);
  296. if (!cmd->size && cmd->start) {
  297. err = -cmd->start;
  298. goto out;
  299. }
  300. if (cmd->size) {
  301. char *name;
  302. err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
  303. if (err)
  304. goto err_out_put;
  305. info = (struct netfs_inode_info *)(st->data);
  306. name = (char *)(info + 1);
  307. str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
  308. name[str.len] = 0;
  309. str.name = name;
  310. str.hash = jhash(str.name, str.len, 0);
  311. netfs_convert_inode_info(info);
  312. if (parent) {
  313. err = pohmelfs_check_name(parent, &str, info);
  314. if (err) {
  315. if (err == -EEXIST)
  316. err = 0;
  317. goto out;
  318. }
  319. }
  320. info->ino = cmd->start;
  321. if (!info->ino)
  322. info->ino = pohmelfs_new_ino(st->psb);
  323. dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
  324. __func__, parent->ino, info->ino, str.name, str.hash, str.len,
  325. info->mode);
  326. npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
  327. if (IS_ERR(npi)) {
  328. err = PTR_ERR(npi);
  329. if (err != -EEXIST)
  330. goto err_out_put;
  331. } else {
  332. struct dentry *dentry, *alias, *pd;
  333. set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
  334. clear_bit(NETFS_INODE_OWNED, &npi->state);
  335. pd = d_find_alias(&parent->vfs_inode);
  336. if (pd) {
  337. str.hash = full_name_hash(str.name, str.len);
  338. dentry = d_alloc(pd, &str);
  339. if (dentry) {
  340. alias = d_materialise_unique(dentry, &npi->vfs_inode);
  341. if (alias)
  342. dput(alias);
  343. }
  344. dput(dentry);
  345. dput(pd);
  346. }
  347. }
  348. }
  349. out:
  350. if (last) {
  351. set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
  352. set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
  353. wake_up(&st->psb->wait);
  354. }
  355. pohmelfs_put_inode(parent);
  356. return err;
  357. err_out_put:
  358. clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
  359. printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
  360. pohmelfs_put_inode(parent);
  361. wake_up(&st->psb->wait);
  362. return err;
  363. }
  364. /*
  365. * Lookup command response.
  366. * It searches for inode to be looked at (if it exists) and substitutes
  367. * its inode information (size, permission, mode and so on), if inode does
  368. * not exist, new one will be created and inserted into caches.
  369. */
  370. static int pohmelfs_lookup_response(struct netfs_state *st)
  371. {
  372. struct inode *inode = NULL;
  373. struct netfs_cmd *cmd = &st->cmd;
  374. struct netfs_inode_info *info;
  375. struct pohmelfs_inode *parent = NULL, *npi;
  376. int err = -EINVAL;
  377. char *name;
  378. inode = ilookup(st->psb->sb, cmd->id);
  379. if (!inode) {
  380. printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
  381. __func__, cmd->id, cmd->start, cmd->size);
  382. err = -ENOENT;
  383. goto err_out_exit;
  384. }
  385. parent = POHMELFS_I(inode);
  386. if (!cmd->size) {
  387. err = -cmd->start;
  388. goto err_out_put;
  389. }
  390. if (cmd->size < sizeof(struct netfs_inode_info)) {
  391. printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
  392. __func__, cmd->id, cmd->start, cmd->size);
  393. err = -EINVAL;
  394. goto err_out_put;
  395. }
  396. err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
  397. if (err)
  398. goto err_out_put;
  399. info = (struct netfs_inode_info *)(st->data);
  400. name = (char *)(info + 1);
  401. netfs_convert_inode_info(info);
  402. info->ino = cmd->start;
  403. if (!info->ino)
  404. info->ino = pohmelfs_new_ino(st->psb);
  405. dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
  406. __func__, parent->ino, info->ino, name, cmd->start);
  407. if (cmd->start)
  408. npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
  409. else {
  410. struct qstr str;
  411. str.name = name;
  412. str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
  413. str.hash = jhash(name, str.len, 0);
  414. npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
  415. }
  416. if (IS_ERR(npi)) {
  417. err = PTR_ERR(npi);
  418. if (err != -EEXIST)
  419. goto err_out_put;
  420. } else {
  421. set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
  422. clear_bit(NETFS_INODE_OWNED, &npi->state);
  423. }
  424. clear_bit(NETFS_COMMAND_PENDING, &parent->state);
  425. pohmelfs_put_inode(parent);
  426. wake_up(&st->psb->wait);
  427. return 0;
  428. err_out_put:
  429. pohmelfs_put_inode(parent);
  430. err_out_exit:
  431. clear_bit(NETFS_COMMAND_PENDING, &parent->state);
  432. wake_up(&st->psb->wait);
  433. printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
  434. __func__, inode, cmd->id, cmd->start, cmd->size, err);
  435. return err;
  436. }
  437. /*
  438. * Create response, just marks local inode as 'created', so that writeback
  439. * for any of its children (or own) would not try to sync it again.
  440. */
  441. static int pohmelfs_create_response(struct netfs_state *st)
  442. {
  443. struct inode *inode;
  444. struct netfs_cmd *cmd = &st->cmd;
  445. struct pohmelfs_inode *pi;
  446. inode = ilookup(st->psb->sb, cmd->id);
  447. if (!inode) {
  448. printk("%s: failed to find inode: id: %llu, start: %llu.\n",
  449. __func__, cmd->id, cmd->start);
  450. goto err_out_exit;
  451. }
  452. pi = POHMELFS_I(inode);
  453. /*
  454. * To lock or not to lock?
  455. * We actually do not care if it races...
  456. */
  457. if (cmd->start)
  458. make_bad_inode(inode);
  459. set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
  460. pohmelfs_put_inode(pi);
  461. wake_up(&st->psb->wait);
  462. return 0;
  463. err_out_exit:
  464. wake_up(&st->psb->wait);
  465. return -ENOENT;
  466. }
  467. /*
  468. * Object remove response. Just says that remove request has been received.
  469. * Used in cache coherency protocol.
  470. */
  471. static int pohmelfs_remove_response(struct netfs_state *st)
  472. {
  473. struct netfs_cmd *cmd = &st->cmd;
  474. int err;
  475. err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
  476. if (err)
  477. return err;
  478. dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
  479. return 0;
  480. }
  481. /*
  482. * Transaction reply processing.
  483. *
  484. * Find transaction based on its generation number, bump its reference counter,
  485. * so that none could free it under us, drop from the trees and lists and
  486. * drop reference counter. When it hits zero (when all destinations replied
  487. * and all timeout handled by async scanning code), completion will be called
  488. * and transaction will be freed.
  489. */
  490. static int pohmelfs_transaction_response(struct netfs_state *st)
  491. {
  492. struct netfs_trans_dst *dst;
  493. struct netfs_trans *t = NULL;
  494. struct netfs_cmd *cmd = &st->cmd;
  495. short err = (signed)cmd->ext;
  496. mutex_lock(&st->trans_lock);
  497. dst = netfs_trans_search(st, cmd->start);
  498. if (dst) {
  499. netfs_trans_remove_nolock(dst, st);
  500. t = dst->trans;
  501. }
  502. mutex_unlock(&st->trans_lock);
  503. if (!t) {
  504. printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n",
  505. __func__, cmd->start, cmd->id, cmd->size, cmd->ext);
  506. err = -EINVAL;
  507. goto out;
  508. }
  509. t->result = err;
  510. netfs_trans_drop_dst_nostate(dst);
  511. out:
  512. wake_up(&st->psb->wait);
  513. return err;
  514. }
  515. /*
  516. * Inode metadata cache coherency message.
  517. */
  518. static int pohmelfs_page_cache_response(struct netfs_state *st)
  519. {
  520. struct netfs_cmd *cmd = &st->cmd;
  521. struct inode *inode;
  522. dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
  523. inode = ilookup(st->psb->sb, cmd->id);
  524. if (!inode) {
  525. printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
  526. return -ENOENT;
  527. }
  528. set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
  529. pohmelfs_put_inode(POHMELFS_I(inode));
  530. return 0;
  531. }
  532. /*
  533. * Root capabilities response: export statistics
  534. * like used and available size, number of files and dirs,
  535. * permissions.
  536. */
  537. static int pohmelfs_root_cap_response(struct netfs_state *st)
  538. {
  539. struct netfs_cmd *cmd = &st->cmd;
  540. struct netfs_root_capabilities *cap;
  541. struct pohmelfs_sb *psb = st->psb;
  542. if (cmd->size != sizeof(struct netfs_root_capabilities)) {
  543. psb->flags = EPROTO;
  544. wake_up(&psb->wait);
  545. return -EPROTO;
  546. }
  547. cap = st->data;
  548. netfs_convert_root_capabilities(cap);
  549. if (psb->total_size < cap->used + cap->avail)
  550. psb->total_size = cap->used + cap->avail;
  551. if (cap->avail)
  552. psb->avail_size = cap->avail;
  553. psb->state_flags = cap->flags;
  554. if (psb->state_flags & POHMELFS_FLAGS_RO) {
  555. psb->sb->s_flags |= MS_RDONLY;
  556. printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
  557. }
  558. if (psb->state_flags & POHMELFS_FLAGS_XATTR)
  559. printk(KERN_INFO "Mounting POHMELFS (%d) "
  560. "with extended attributes support.\n", psb->idx);
  561. if (atomic_long_read(&psb->total_inodes) <= 1)
  562. atomic_long_set(&psb->total_inodes, cap->nr_files);
  563. dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
  564. __func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
  565. psb->flags = 0;
  566. wake_up(&psb->wait);
  567. return 0;
  568. }
  569. /*
  570. * Crypto capabilities of the server, where it says that
  571. * it supports or does not requested hash/cipher algorithms.
  572. */
  573. static int pohmelfs_crypto_cap_response(struct netfs_state *st)
  574. {
  575. struct netfs_cmd *cmd = &st->cmd;
  576. struct netfs_crypto_capabilities *cap;
  577. struct pohmelfs_sb *psb = st->psb;
  578. int err = 0;
  579. if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
  580. psb->flags = EPROTO;
  581. wake_up(&psb->wait);
  582. return -EPROTO;
  583. }
  584. cap = st->data;
  585. dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
  586. __func__,
  587. psb->cipher_string, (cap->cipher_strlen) ? "SUPPORTED" : "NOT SUPPORTED",
  588. psb->hash_string, (cap->hash_strlen) ? "SUPPORTED" : "NOT SUPPORTED");
  589. if (!cap->hash_strlen) {
  590. if (psb->hash_strlen && psb->crypto_fail_unsupported)
  591. err = -ENOTSUPP;
  592. psb->hash_strlen = 0;
  593. kfree(psb->hash_string);
  594. psb->hash_string = NULL;
  595. }
  596. if (!cap->cipher_strlen) {
  597. if (psb->cipher_strlen && psb->crypto_fail_unsupported)
  598. err = -ENOTSUPP;
  599. psb->cipher_strlen = 0;
  600. kfree(psb->cipher_string);
  601. psb->cipher_string = NULL;
  602. }
  603. return err;
  604. }
  605. /*
  606. * Capabilities handshake response.
  607. */
  608. static int pohmelfs_capabilities_response(struct netfs_state *st)
  609. {
  610. struct netfs_cmd *cmd = &st->cmd;
  611. int err = 0;
  612. err = pohmelfs_data_recv(st, st->data, cmd->size);
  613. if (err)
  614. return err;
  615. switch (cmd->id) {
  616. case POHMELFS_CRYPTO_CAPABILITIES:
  617. return pohmelfs_crypto_cap_response(st);
  618. case POHMELFS_ROOT_CAPABILITIES:
  619. return pohmelfs_root_cap_response(st);
  620. default:
  621. break;
  622. }
  623. return -EINVAL;
  624. }
  625. /*
  626. * Receiving extended attribute.
  627. * Does not work properly if received size is more than requested one,
  628. * it should not happen with current request/reply model though.
  629. */
  630. static int pohmelfs_getxattr_response(struct netfs_state *st)
  631. {
  632. struct pohmelfs_sb *psb = st->psb;
  633. struct netfs_cmd *cmd = &st->cmd;
  634. struct pohmelfs_mcache *m;
  635. short error = (signed short)cmd->ext, err;
  636. unsigned int sz, total_size;
  637. m = pohmelfs_mcache_search(psb, cmd->id);
  638. dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
  639. __func__, cmd->id, (m) ? m->gen : 0, error);
  640. if (!m) {
  641. printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
  642. return -ENOENT;
  643. }
  644. if (cmd->size) {
  645. sz = min_t(unsigned int, cmd->size, m->size);
  646. err = pohmelfs_data_recv_and_check(st, m->data, sz);
  647. if (err) {
  648. error = err;
  649. goto out;
  650. }
  651. m->size = sz;
  652. total_size = cmd->size - sz;
  653. while (total_size) {
  654. sz = min(total_size, st->size);
  655. err = pohmelfs_data_recv_and_check(st, st->data, sz);
  656. if (err) {
  657. error = err;
  658. break;
  659. }
  660. total_size -= sz;
  661. }
  662. }
  663. out:
  664. m->err = error;
  665. complete(&m->complete);
  666. pohmelfs_mcache_put(psb, m);
  667. return error;
  668. }
  669. int pohmelfs_data_lock_response(struct netfs_state *st)
  670. {
  671. struct pohmelfs_sb *psb = st->psb;
  672. struct netfs_cmd *cmd = &st->cmd;
  673. struct pohmelfs_mcache *m;
  674. short err = (signed short)cmd->ext;
  675. u64 id = cmd->id;
  676. m = pohmelfs_mcache_search(psb, id);
  677. dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
  678. __func__, cmd->id, (m) ? m->gen : 0, err);
  679. if (!m) {
  680. pohmelfs_data_recv(st, st->data, cmd->size);
  681. printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
  682. return -ENOENT;
  683. }
  684. if (cmd->size)
  685. err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
  686. m->err = err;
  687. complete(&m->complete);
  688. pohmelfs_mcache_put(psb, m);
  689. return err;
  690. }
  691. static void __inline__ netfs_state_reset(struct netfs_state *st)
  692. {
  693. netfs_state_lock_send(st);
  694. netfs_state_exit(st);
  695. netfs_state_init(st);
  696. netfs_state_unlock_send(st);
  697. }
  698. /*
  699. * Main receiving function, called from dedicated kernel thread.
  700. */
  701. static int pohmelfs_recv(void *data)
  702. {
  703. int err = -EINTR;
  704. struct netfs_state *st = data;
  705. struct netfs_cmd *cmd = &st->cmd;
  706. while (!kthread_should_stop()) {
  707. /*
  708. * If socket will be reset after this statement, then
  709. * pohmelfs_data_recv() will just fail and loop will
  710. * start again, so it can be done without any locks.
  711. *
  712. * st->read_socket is needed to prevents state machine
  713. * breaking between this data reading and subsequent one
  714. * in protocol specific functions during connection reset.
  715. * In case of reset we have to read next command and do
  716. * not expect data for old command to magically appear in
  717. * new connection.
  718. */
  719. st->read_socket = st->socket;
  720. err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
  721. if (err) {
  722. msleep(1000);
  723. continue;
  724. }
  725. netfs_convert_cmd(cmd);
  726. dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
  727. "ext: %u, csize: %u, cpad: %u.\n",
  728. __func__, cmd->cmd, cmd->id, cmd->start,
  729. cmd->size, cmd->ext, cmd->csize, cmd->cpad);
  730. if (cmd->csize) {
  731. struct pohmelfs_crypto_engine *e = &st->eng;
  732. if (unlikely(cmd->csize > e->size/2)) {
  733. netfs_state_reset(st);
  734. continue;
  735. }
  736. if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
  737. dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
  738. "csize: %u != digest size %u.\n",
  739. __func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
  740. cmd->csize, st->psb->crypto_attached_size);
  741. netfs_state_reset(st);
  742. continue;
  743. }
  744. err = pohmelfs_data_recv(st, e->data, cmd->csize);
  745. if (err) {
  746. netfs_state_reset(st);
  747. continue;
  748. }
  749. #ifdef CONFIG_POHMELFS_DEBUG
  750. {
  751. unsigned int i;
  752. unsigned char *hash = e->data;
  753. dprintk("%s: received hash: ", __func__);
  754. for (i = 0; i < cmd->csize; ++i)
  755. printk("%02x ", hash[i]);
  756. printk("\n");
  757. }
  758. #endif
  759. cmd->size -= cmd->csize;
  760. }
  761. /*
  762. * This should catch protocol breakage and random garbage instead of commands.
  763. */
  764. if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
  765. netfs_state_reset(st);
  766. continue;
  767. }
  768. switch (cmd->cmd) {
  769. case NETFS_READ_PAGE:
  770. err = pohmelfs_read_page_response(st);
  771. break;
  772. case NETFS_READDIR:
  773. err = pohmelfs_readdir_response(st);
  774. break;
  775. case NETFS_LOOKUP:
  776. err = pohmelfs_lookup_response(st);
  777. break;
  778. case NETFS_CREATE:
  779. err = pohmelfs_create_response(st);
  780. break;
  781. case NETFS_REMOVE:
  782. err = pohmelfs_remove_response(st);
  783. break;
  784. case NETFS_TRANS:
  785. err = pohmelfs_transaction_response(st);
  786. break;
  787. case NETFS_PAGE_CACHE:
  788. err = pohmelfs_page_cache_response(st);
  789. break;
  790. case NETFS_CAPABILITIES:
  791. err = pohmelfs_capabilities_response(st);
  792. break;
  793. case NETFS_LOCK:
  794. err = pohmelfs_data_lock_response(st);
  795. break;
  796. case NETFS_XATTR_GET:
  797. err = pohmelfs_getxattr_response(st);
  798. break;
  799. default:
  800. printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
  801. __func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
  802. netfs_state_reset(st);
  803. break;
  804. }
  805. }
  806. while (!kthread_should_stop())
  807. schedule_timeout_uninterruptible(msecs_to_jiffies(10));
  808. return err;
  809. }
  810. int netfs_state_init(struct netfs_state *st)
  811. {
  812. int err;
  813. struct pohmelfs_ctl *ctl = &st->ctl;
  814. err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
  815. if (err) {
  816. printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
  817. __func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
  818. goto err_out_exit;
  819. }
  820. st->socket->sk->sk_allocation = GFP_NOIO;
  821. st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
  822. err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
  823. if (err) {
  824. printk("%s: failed to connect to server: idx: %u, err: %d.\n",
  825. __func__, st->psb->idx, err);
  826. goto err_out_release;
  827. }
  828. st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
  829. err = netfs_poll_init(st);
  830. if (err)
  831. goto err_out_release;
  832. if (st->socket->ops->family == AF_INET) {
  833. struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
  834. printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
  835. &sin->sin_addr.s_addr, ntohs(sin->sin_port));
  836. } else if (st->socket->ops->family == AF_INET6) {
  837. struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
  838. printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
  839. &sin->sin6_addr, ntohs(sin->sin6_port));
  840. }
  841. return 0;
  842. err_out_release:
  843. sock_release(st->socket);
  844. err_out_exit:
  845. st->socket = NULL;
  846. return err;
  847. }
  848. void netfs_state_exit(struct netfs_state *st)
  849. {
  850. if (st->socket) {
  851. netfs_poll_exit(st);
  852. st->socket->ops->shutdown(st->socket, 2);
  853. if (st->socket->ops->family == AF_INET) {
  854. struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
  855. printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
  856. &sin->sin_addr.s_addr, ntohs(sin->sin_port));
  857. } else if (st->socket->ops->family == AF_INET6) {
  858. struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
  859. printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
  860. &sin->sin6_addr, ntohs(sin->sin6_port));
  861. }
  862. sock_release(st->socket);
  863. st->socket = NULL;
  864. st->read_socket = NULL;
  865. st->need_reset = 0;
  866. }
  867. }
  868. int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
  869. {
  870. struct netfs_state *st = &conf->state;
  871. int err = -ENOMEM;
  872. mutex_init(&st->__state_lock);
  873. mutex_init(&st->__state_send_lock);
  874. init_waitqueue_head(&st->thread_wait);
  875. st->psb = psb;
  876. st->trans_root = RB_ROOT;
  877. mutex_init(&st->trans_lock);
  878. st->size = psb->trans_data_size;
  879. st->data = kmalloc(st->size, GFP_KERNEL);
  880. if (!st->data)
  881. goto err_out_exit;
  882. if (psb->perform_crypto) {
  883. err = pohmelfs_crypto_engine_init(&st->eng, psb);
  884. if (err)
  885. goto err_out_free_data;
  886. }
  887. err = netfs_state_init(st);
  888. if (err)
  889. goto err_out_free_engine;
  890. st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
  891. if (IS_ERR(st->thread)) {
  892. err = PTR_ERR(st->thread);
  893. goto err_out_netfs_exit;
  894. }
  895. if (!psb->active_state)
  896. psb->active_state = conf;
  897. dprintk("%s: conf: %p, st: %p, socket: %p.\n",
  898. __func__, conf, st, st->socket);
  899. return 0;
  900. err_out_netfs_exit:
  901. netfs_state_exit(st);
  902. err_out_free_engine:
  903. pohmelfs_crypto_engine_exit(&st->eng);
  904. err_out_free_data:
  905. kfree(st->data);
  906. err_out_exit:
  907. return err;
  908. }
  909. void pohmelfs_state_flush_transactions(struct netfs_state *st)
  910. {
  911. struct rb_node *rb_node;
  912. struct netfs_trans_dst *dst;
  913. mutex_lock(&st->trans_lock);
  914. for (rb_node = rb_first(&st->trans_root); rb_node; ) {
  915. dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
  916. rb_node = rb_next(rb_node);
  917. dst->trans->result = -EINVAL;
  918. netfs_trans_remove_nolock(dst, st);
  919. netfs_trans_drop_dst_nostate(dst);
  920. }
  921. mutex_unlock(&st->trans_lock);
  922. }
  923. static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
  924. {
  925. struct netfs_state *st = &c->state;
  926. dprintk("%s: exiting, st: %p.\n", __func__, st);
  927. if (st->thread) {
  928. kthread_stop(st->thread);
  929. st->thread = NULL;
  930. }
  931. netfs_state_lock_send(st);
  932. netfs_state_exit(st);
  933. netfs_state_unlock_send(st);
  934. pohmelfs_state_flush_transactions(st);
  935. pohmelfs_crypto_engine_exit(&st->eng);
  936. kfree(st->data);
  937. kfree(c);
  938. }
  939. /*
  940. * Initialize network stack. It searches for given ID in global
  941. * configuration table, this contains information of the remote server
  942. * (address (any supported by socket interface) and port, protocol and so on).
  943. */
  944. int pohmelfs_state_init(struct pohmelfs_sb *psb)
  945. {
  946. int err = -ENOMEM;
  947. err = pohmelfs_copy_config(psb);
  948. if (err) {
  949. pohmelfs_state_exit(psb);
  950. return err;
  951. }
  952. return 0;
  953. }
  954. void pohmelfs_state_exit(struct pohmelfs_sb *psb)
  955. {
  956. struct pohmelfs_config *c, *tmp;
  957. list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
  958. list_del(&c->config_entry);
  959. pohmelfs_state_exit_one(c);
  960. }
  961. }
  962. void pohmelfs_switch_active(struct pohmelfs_sb *psb)
  963. {
  964. struct pohmelfs_config *c = psb->active_state;
  965. if (!list_empty(&psb->state_list)) {
  966. if (c->config_entry.next != &psb->state_list) {
  967. psb->active_state = list_entry(c->config_entry.next,
  968. struct pohmelfs_config, config_entry);
  969. } else {
  970. psb->active_state = list_entry(psb->state_list.next,
  971. struct pohmelfs_config, config_entry);
  972. }
  973. dprintk("%s: empty: %d, active %p -> %p.\n",
  974. __func__, list_empty(&psb->state_list), c,
  975. psb->active_state);
  976. } else
  977. psb->active_state = NULL;
  978. }
  979. void pohmelfs_check_states(struct pohmelfs_sb *psb)
  980. {
  981. struct pohmelfs_config *c, *tmp;
  982. LIST_HEAD(delete_list);
  983. mutex_lock(&psb->state_lock);
  984. list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
  985. if (pohmelfs_config_check(c, psb->idx)) {
  986. if (psb->active_state == c)
  987. pohmelfs_switch_active(psb);
  988. list_move(&c->config_entry, &delete_list);
  989. }
  990. }
  991. pohmelfs_copy_config(psb);
  992. mutex_unlock(&psb->state_lock);
  993. list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
  994. list_del(&c->config_entry);
  995. pohmelfs_state_exit_one(c);
  996. }
  997. }