client.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  1. /*
  2. * net/9p/clnt.c
  3. *
  4. * 9P Client
  5. *
  6. * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
  7. * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
  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 version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to:
  20. * Free Software Foundation
  21. * 51 Franklin Street, Fifth Floor
  22. * Boston, MA 02111-1301 USA
  23. *
  24. */
  25. #include <linux/module.h>
  26. #include <linux/errno.h>
  27. #include <linux/fs.h>
  28. #include <linux/poll.h>
  29. #include <linux/idr.h>
  30. #include <linux/mutex.h>
  31. #include <linux/sched.h>
  32. #include <linux/uaccess.h>
  33. #include <net/9p/9p.h>
  34. #include <linux/parser.h>
  35. #include <net/9p/client.h>
  36. #include <net/9p/transport.h>
  37. #include "protocol.h"
  38. /*
  39. * Client Option Parsing (code inspired by NFS code)
  40. * - a little lazy - parse all client options
  41. */
  42. enum {
  43. Opt_msize,
  44. Opt_trans,
  45. Opt_legacy,
  46. Opt_err,
  47. };
  48. static const match_table_t tokens = {
  49. {Opt_msize, "msize=%u"},
  50. {Opt_legacy, "noextend"},
  51. {Opt_trans, "trans=%s"},
  52. {Opt_err, NULL},
  53. };
  54. static struct p9_req_t *
  55. p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
  56. /**
  57. * parse_options - parse mount options into client structure
  58. * @opts: options string passed from mount
  59. * @clnt: existing v9fs client information
  60. *
  61. * Return 0 upon success, -ERRNO upon failure
  62. */
  63. static int parse_opts(char *opts, struct p9_client *clnt)
  64. {
  65. char *options, *tmp_options;
  66. char *p;
  67. substring_t args[MAX_OPT_ARGS];
  68. int option;
  69. int ret = 0;
  70. clnt->dotu = 1;
  71. clnt->msize = 8192;
  72. if (!opts)
  73. return 0;
  74. tmp_options = kstrdup(opts, GFP_KERNEL);
  75. if (!tmp_options) {
  76. P9_DPRINTK(P9_DEBUG_ERROR,
  77. "failed to allocate copy of option string\n");
  78. return -ENOMEM;
  79. }
  80. options = tmp_options;
  81. while ((p = strsep(&options, ",")) != NULL) {
  82. int token;
  83. if (!*p)
  84. continue;
  85. token = match_token(p, tokens, args);
  86. if (token < Opt_trans) {
  87. int r = match_int(&args[0], &option);
  88. if (r < 0) {
  89. P9_DPRINTK(P9_DEBUG_ERROR,
  90. "integer field, but no integer?\n");
  91. ret = r;
  92. continue;
  93. }
  94. }
  95. switch (token) {
  96. case Opt_msize:
  97. clnt->msize = option;
  98. break;
  99. case Opt_trans:
  100. clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
  101. if(clnt->trans_mod == NULL) {
  102. P9_DPRINTK(P9_DEBUG_ERROR,
  103. "Could not find request transport: %s\n",
  104. (char *) &args[0]);
  105. ret = -EINVAL;
  106. goto free_and_return;
  107. }
  108. break;
  109. case Opt_legacy:
  110. clnt->dotu = 0;
  111. break;
  112. default:
  113. continue;
  114. }
  115. }
  116. free_and_return:
  117. kfree(tmp_options);
  118. return ret;
  119. }
  120. /**
  121. * p9_tag_alloc - lookup/allocate a request by tag
  122. * @c: client session to lookup tag within
  123. * @tag: numeric id for transaction
  124. *
  125. * this is a simple array lookup, but will grow the
  126. * request_slots as necessary to accomodate transaction
  127. * ids which did not previously have a slot.
  128. *
  129. * this code relies on the client spinlock to manage locks, its
  130. * possible we should switch to something else, but I'd rather
  131. * stick with something low-overhead for the common case.
  132. *
  133. */
  134. static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
  135. {
  136. unsigned long flags;
  137. int row, col;
  138. struct p9_req_t *req;
  139. /* This looks up the original request by tag so we know which
  140. * buffer to read the data into */
  141. tag++;
  142. if (tag >= c->max_tag) {
  143. spin_lock_irqsave(&c->lock, flags);
  144. /* check again since original check was outside of lock */
  145. while (tag >= c->max_tag) {
  146. row = (tag / P9_ROW_MAXTAG);
  147. c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
  148. sizeof(struct p9_req_t), GFP_ATOMIC);
  149. if (!c->reqs[row]) {
  150. printk(KERN_ERR "Couldn't grow tag array\n");
  151. spin_unlock_irqrestore(&c->lock, flags);
  152. return ERR_PTR(-ENOMEM);
  153. }
  154. for (col = 0; col < P9_ROW_MAXTAG; col++) {
  155. c->reqs[row][col].status = REQ_STATUS_IDLE;
  156. c->reqs[row][col].tc = NULL;
  157. }
  158. c->max_tag += P9_ROW_MAXTAG;
  159. }
  160. spin_unlock_irqrestore(&c->lock, flags);
  161. }
  162. row = tag / P9_ROW_MAXTAG;
  163. col = tag % P9_ROW_MAXTAG;
  164. req = &c->reqs[row][col];
  165. if (!req->tc) {
  166. req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
  167. if (!req->wq) {
  168. printk(KERN_ERR "Couldn't grow tag array\n");
  169. return ERR_PTR(-ENOMEM);
  170. }
  171. init_waitqueue_head(req->wq);
  172. req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
  173. GFP_KERNEL);
  174. req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
  175. GFP_KERNEL);
  176. if ((!req->tc) || (!req->rc)) {
  177. printk(KERN_ERR "Couldn't grow tag array\n");
  178. kfree(req->tc);
  179. kfree(req->rc);
  180. kfree(req->wq);
  181. req->tc = req->rc = NULL;
  182. req->wq = NULL;
  183. return ERR_PTR(-ENOMEM);
  184. }
  185. req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
  186. req->tc->capacity = c->msize;
  187. req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
  188. req->rc->capacity = c->msize;
  189. }
  190. p9pdu_reset(req->tc);
  191. p9pdu_reset(req->rc);
  192. req->tc->tag = tag-1;
  193. req->status = REQ_STATUS_ALLOC;
  194. return &c->reqs[row][col];
  195. }
  196. /**
  197. * p9_tag_lookup - lookup a request by tag
  198. * @c: client session to lookup tag within
  199. * @tag: numeric id for transaction
  200. *
  201. */
  202. struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
  203. {
  204. int row, col;
  205. /* This looks up the original request by tag so we know which
  206. * buffer to read the data into */
  207. tag++;
  208. BUG_ON(tag >= c->max_tag);
  209. row = tag / P9_ROW_MAXTAG;
  210. col = tag % P9_ROW_MAXTAG;
  211. return &c->reqs[row][col];
  212. }
  213. EXPORT_SYMBOL(p9_tag_lookup);
  214. /**
  215. * p9_tag_init - setup tags structure and contents
  216. * @c: v9fs client struct
  217. *
  218. * This initializes the tags structure for each client instance.
  219. *
  220. */
  221. static int p9_tag_init(struct p9_client *c)
  222. {
  223. int err = 0;
  224. c->tagpool = p9_idpool_create();
  225. if (IS_ERR(c->tagpool)) {
  226. err = PTR_ERR(c->tagpool);
  227. c->tagpool = NULL;
  228. goto error;
  229. }
  230. p9_idpool_get(c->tagpool); /* reserve tag 0 */
  231. c->max_tag = 0;
  232. error:
  233. return err;
  234. }
  235. /**
  236. * p9_tag_cleanup - cleans up tags structure and reclaims resources
  237. * @c: v9fs client struct
  238. *
  239. * This frees resources associated with the tags structure
  240. *
  241. */
  242. static void p9_tag_cleanup(struct p9_client *c)
  243. {
  244. int row, col;
  245. /* check to insure all requests are idle */
  246. for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
  247. for (col = 0; col < P9_ROW_MAXTAG; col++) {
  248. if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
  249. P9_DPRINTK(P9_DEBUG_MUX,
  250. "Attempting to cleanup non-free tag %d,%d\n",
  251. row, col);
  252. /* TODO: delay execution of cleanup */
  253. return;
  254. }
  255. }
  256. }
  257. if (c->tagpool)
  258. p9_idpool_destroy(c->tagpool);
  259. /* free requests associated with tags */
  260. for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
  261. for (col = 0; col < P9_ROW_MAXTAG; col++) {
  262. kfree(c->reqs[row][col].wq);
  263. kfree(c->reqs[row][col].tc);
  264. kfree(c->reqs[row][col].rc);
  265. }
  266. kfree(c->reqs[row]);
  267. }
  268. c->max_tag = 0;
  269. }
  270. /**
  271. * p9_free_req - free a request and clean-up as necessary
  272. * c: client state
  273. * r: request to release
  274. *
  275. */
  276. static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
  277. {
  278. int tag = r->tc->tag;
  279. P9_DPRINTK(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
  280. r->status = REQ_STATUS_IDLE;
  281. if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
  282. p9_idpool_put(tag, c->tagpool);
  283. }
  284. /**
  285. * p9_client_cb - call back from transport to client
  286. * c: client state
  287. * req: request received
  288. *
  289. */
  290. void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
  291. {
  292. P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
  293. wake_up(req->wq);
  294. P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
  295. }
  296. EXPORT_SYMBOL(p9_client_cb);
  297. /**
  298. * p9_parse_header - parse header arguments out of a packet
  299. * @pdu: packet to parse
  300. * @size: size of packet
  301. * @type: type of request
  302. * @tag: tag of packet
  303. * @rewind: set if we need to rewind offset afterwards
  304. */
  305. int
  306. p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
  307. int rewind)
  308. {
  309. int8_t r_type;
  310. int16_t r_tag;
  311. int32_t r_size;
  312. int offset = pdu->offset;
  313. int err;
  314. pdu->offset = 0;
  315. if (pdu->size == 0)
  316. pdu->size = 7;
  317. err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
  318. if (err)
  319. goto rewind_and_exit;
  320. pdu->size = r_size;
  321. pdu->id = r_type;
  322. pdu->tag = r_tag;
  323. P9_DPRINTK(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", pdu->size,
  324. pdu->id, pdu->tag);
  325. if (type)
  326. *type = r_type;
  327. if (tag)
  328. *tag = r_tag;
  329. if (size)
  330. *size = r_size;
  331. rewind_and_exit:
  332. if (rewind)
  333. pdu->offset = offset;
  334. return err;
  335. }
  336. EXPORT_SYMBOL(p9_parse_header);
  337. /**
  338. * p9_check_errors - check 9p packet for error return and process it
  339. * @c: current client instance
  340. * @req: request to parse and check for error conditions
  341. *
  342. * returns error code if one is discovered, otherwise returns 0
  343. *
  344. * this will have to be more complicated if we have multiple
  345. * error packet types
  346. */
  347. static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
  348. {
  349. int8_t type;
  350. int err;
  351. err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
  352. if (err) {
  353. P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
  354. return err;
  355. }
  356. if (type == P9_RERROR) {
  357. int ecode;
  358. char *ename;
  359. err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
  360. if (err) {
  361. P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
  362. err);
  363. return err;
  364. }
  365. if (c->dotu)
  366. err = -ecode;
  367. if (!err || !IS_ERR_VALUE(err))
  368. err = p9_errstr2errno(ename, strlen(ename));
  369. P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
  370. kfree(ename);
  371. } else
  372. err = 0;
  373. return err;
  374. }
  375. /**
  376. * p9_client_flush - flush (cancel) a request
  377. * @c: client state
  378. * @oldreq: request to cancel
  379. *
  380. * This sents a flush for a particular requests and links
  381. * the flush request to the original request. The current
  382. * code only supports a single flush request although the protocol
  383. * allows for multiple flush requests to be sent for a single request.
  384. *
  385. */
  386. static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
  387. {
  388. struct p9_req_t *req;
  389. int16_t oldtag;
  390. int err;
  391. err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
  392. if (err)
  393. return err;
  394. P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
  395. req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
  396. if (IS_ERR(req))
  397. return PTR_ERR(req);
  398. /* if we haven't received a response for oldreq,
  399. remove it from the list. */
  400. spin_lock(&c->lock);
  401. if (oldreq->status == REQ_STATUS_FLSH)
  402. list_del(&oldreq->req_list);
  403. spin_unlock(&c->lock);
  404. p9_free_req(c, req);
  405. return 0;
  406. }
  407. /**
  408. * p9_client_rpc - issue a request and wait for a response
  409. * @c: client session
  410. * @type: type of request
  411. * @fmt: protocol format string (see protocol.c)
  412. *
  413. * Returns request structure (which client must free using p9_free_req)
  414. */
  415. static struct p9_req_t *
  416. p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
  417. {
  418. va_list ap;
  419. int tag, err;
  420. struct p9_req_t *req;
  421. unsigned long flags;
  422. int sigpending;
  423. P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
  424. if (c->status != Connected)
  425. return ERR_PTR(-EIO);
  426. if (signal_pending(current)) {
  427. sigpending = 1;
  428. clear_thread_flag(TIF_SIGPENDING);
  429. } else
  430. sigpending = 0;
  431. tag = P9_NOTAG;
  432. if (type != P9_TVERSION) {
  433. tag = p9_idpool_get(c->tagpool);
  434. if (tag < 0)
  435. return ERR_PTR(-ENOMEM);
  436. }
  437. req = p9_tag_alloc(c, tag);
  438. if (IS_ERR(req))
  439. return req;
  440. /* marshall the data */
  441. p9pdu_prepare(req->tc, tag, type);
  442. va_start(ap, fmt);
  443. err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
  444. va_end(ap);
  445. p9pdu_finalize(req->tc);
  446. err = c->trans_mod->request(c, req);
  447. if (err < 0) {
  448. c->status = Disconnected;
  449. goto reterr;
  450. }
  451. P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
  452. err = wait_event_interruptible(*req->wq,
  453. req->status >= REQ_STATUS_RCVD);
  454. P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n",
  455. req->wq, tag, err);
  456. if (req->status == REQ_STATUS_ERROR) {
  457. P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
  458. err = req->t_err;
  459. }
  460. if ((err == -ERESTARTSYS) && (c->status == Connected)) {
  461. P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
  462. sigpending = 1;
  463. clear_thread_flag(TIF_SIGPENDING);
  464. if (c->trans_mod->cancel(c, req))
  465. p9_client_flush(c, req);
  466. /* if we received the response anyway, don't signal error */
  467. if (req->status == REQ_STATUS_RCVD)
  468. err = 0;
  469. }
  470. if (sigpending) {
  471. spin_lock_irqsave(&current->sighand->siglock, flags);
  472. recalc_sigpending();
  473. spin_unlock_irqrestore(&current->sighand->siglock, flags);
  474. }
  475. if (err < 0)
  476. goto reterr;
  477. err = p9_check_errors(c, req);
  478. if (!err) {
  479. P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
  480. return req;
  481. }
  482. reterr:
  483. P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
  484. err);
  485. p9_free_req(c, req);
  486. return ERR_PTR(err);
  487. }
  488. static struct p9_fid *p9_fid_create(struct p9_client *clnt)
  489. {
  490. int ret;
  491. struct p9_fid *fid;
  492. unsigned long flags;
  493. P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt);
  494. fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
  495. if (!fid)
  496. return ERR_PTR(-ENOMEM);
  497. ret = p9_idpool_get(clnt->fidpool);
  498. if (ret < 0) {
  499. ret = -ENOSPC;
  500. goto error;
  501. }
  502. fid->fid = ret;
  503. memset(&fid->qid, 0, sizeof(struct p9_qid));
  504. fid->mode = -1;
  505. fid->uid = current_fsuid();
  506. fid->clnt = clnt;
  507. fid->rdir = NULL;
  508. spin_lock_irqsave(&clnt->lock, flags);
  509. list_add(&fid->flist, &clnt->fidlist);
  510. spin_unlock_irqrestore(&clnt->lock, flags);
  511. return fid;
  512. error:
  513. kfree(fid);
  514. return ERR_PTR(ret);
  515. }
  516. static void p9_fid_destroy(struct p9_fid *fid)
  517. {
  518. struct p9_client *clnt;
  519. unsigned long flags;
  520. P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid);
  521. clnt = fid->clnt;
  522. p9_idpool_put(fid->fid, clnt->fidpool);
  523. spin_lock_irqsave(&clnt->lock, flags);
  524. list_del(&fid->flist);
  525. spin_unlock_irqrestore(&clnt->lock, flags);
  526. kfree(fid->rdir);
  527. kfree(fid);
  528. }
  529. int p9_client_version(struct p9_client *c)
  530. {
  531. int err = 0;
  532. struct p9_req_t *req;
  533. char *version;
  534. int msize;
  535. P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
  536. c->msize, c->dotu);
  537. req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
  538. c->dotu ? "9P2000.u" : "9P2000");
  539. if (IS_ERR(req))
  540. return PTR_ERR(req);
  541. err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
  542. if (err) {
  543. P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
  544. p9pdu_dump(1, req->rc);
  545. goto error;
  546. }
  547. P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
  548. if (!memcmp(version, "9P2000.u", 8))
  549. c->dotu = 1;
  550. else if (!memcmp(version, "9P2000", 6))
  551. c->dotu = 0;
  552. else {
  553. err = -EREMOTEIO;
  554. goto error;
  555. }
  556. if (msize < c->msize)
  557. c->msize = msize;
  558. error:
  559. kfree(version);
  560. p9_free_req(c, req);
  561. return err;
  562. }
  563. EXPORT_SYMBOL(p9_client_version);
  564. struct p9_client *p9_client_create(const char *dev_name, char *options)
  565. {
  566. int err;
  567. struct p9_client *clnt;
  568. err = 0;
  569. clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
  570. if (!clnt)
  571. return ERR_PTR(-ENOMEM);
  572. clnt->trans_mod = NULL;
  573. clnt->trans = NULL;
  574. spin_lock_init(&clnt->lock);
  575. INIT_LIST_HEAD(&clnt->fidlist);
  576. p9_tag_init(clnt);
  577. err = parse_opts(options, clnt);
  578. if (err < 0)
  579. goto free_client;
  580. if (!clnt->trans_mod)
  581. clnt->trans_mod = v9fs_get_default_trans();
  582. if (clnt->trans_mod == NULL) {
  583. err = -EPROTONOSUPPORT;
  584. P9_DPRINTK(P9_DEBUG_ERROR,
  585. "No transport defined or default transport\n");
  586. goto free_client;
  587. }
  588. clnt->fidpool = p9_idpool_create();
  589. if (IS_ERR(clnt->fidpool)) {
  590. err = PTR_ERR(clnt->fidpool);
  591. clnt->fidpool = NULL;
  592. goto put_trans;
  593. }
  594. P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
  595. clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
  596. err = clnt->trans_mod->create(clnt, dev_name, options);
  597. if (err)
  598. goto destroy_fidpool;
  599. if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
  600. clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
  601. err = p9_client_version(clnt);
  602. if (err)
  603. goto close_trans;
  604. return clnt;
  605. close_trans:
  606. clnt->trans_mod->close(clnt);
  607. destroy_fidpool:
  608. p9_idpool_destroy(clnt->fidpool);
  609. put_trans:
  610. v9fs_put_trans(clnt->trans_mod);
  611. free_client:
  612. kfree(clnt);
  613. return ERR_PTR(err);
  614. }
  615. EXPORT_SYMBOL(p9_client_create);
  616. void p9_client_destroy(struct p9_client *clnt)
  617. {
  618. struct p9_fid *fid, *fidptr;
  619. P9_DPRINTK(P9_DEBUG_MUX, "clnt %p\n", clnt);
  620. if (clnt->trans_mod)
  621. clnt->trans_mod->close(clnt);
  622. v9fs_put_trans(clnt->trans_mod);
  623. list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
  624. p9_fid_destroy(fid);
  625. if (clnt->fidpool)
  626. p9_idpool_destroy(clnt->fidpool);
  627. p9_tag_cleanup(clnt);
  628. kfree(clnt);
  629. }
  630. EXPORT_SYMBOL(p9_client_destroy);
  631. void p9_client_disconnect(struct p9_client *clnt)
  632. {
  633. P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
  634. clnt->status = Disconnected;
  635. }
  636. EXPORT_SYMBOL(p9_client_disconnect);
  637. struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
  638. char *uname, u32 n_uname, char *aname)
  639. {
  640. int err;
  641. struct p9_req_t *req;
  642. struct p9_fid *fid;
  643. struct p9_qid qid;
  644. P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
  645. afid ? afid->fid : -1, uname, aname);
  646. err = 0;
  647. fid = p9_fid_create(clnt);
  648. if (IS_ERR(fid)) {
  649. err = PTR_ERR(fid);
  650. fid = NULL;
  651. goto error;
  652. }
  653. req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
  654. afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
  655. if (IS_ERR(req)) {
  656. err = PTR_ERR(req);
  657. goto error;
  658. }
  659. err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
  660. if (err) {
  661. p9pdu_dump(1, req->rc);
  662. p9_free_req(clnt, req);
  663. goto error;
  664. }
  665. P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
  666. qid.type,
  667. (unsigned long long)qid.path,
  668. qid.version);
  669. memmove(&fid->qid, &qid, sizeof(struct p9_qid));
  670. p9_free_req(clnt, req);
  671. return fid;
  672. error:
  673. if (fid)
  674. p9_fid_destroy(fid);
  675. return ERR_PTR(err);
  676. }
  677. EXPORT_SYMBOL(p9_client_attach);
  678. struct p9_fid *
  679. p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
  680. {
  681. int err;
  682. struct p9_req_t *req;
  683. struct p9_qid qid;
  684. struct p9_fid *afid;
  685. P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
  686. err = 0;
  687. afid = p9_fid_create(clnt);
  688. if (IS_ERR(afid)) {
  689. err = PTR_ERR(afid);
  690. afid = NULL;
  691. goto error;
  692. }
  693. req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
  694. afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
  695. if (IS_ERR(req)) {
  696. err = PTR_ERR(req);
  697. goto error;
  698. }
  699. err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
  700. if (err) {
  701. p9pdu_dump(1, req->rc);
  702. p9_free_req(clnt, req);
  703. goto error;
  704. }
  705. P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
  706. qid.type,
  707. (unsigned long long)qid.path,
  708. qid.version);
  709. memmove(&afid->qid, &qid, sizeof(struct p9_qid));
  710. p9_free_req(clnt, req);
  711. return afid;
  712. error:
  713. if (afid)
  714. p9_fid_destroy(afid);
  715. return ERR_PTR(err);
  716. }
  717. EXPORT_SYMBOL(p9_client_auth);
  718. struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
  719. int clone)
  720. {
  721. int err;
  722. struct p9_client *clnt;
  723. struct p9_fid *fid;
  724. struct p9_qid *wqids;
  725. struct p9_req_t *req;
  726. int16_t nwqids, count;
  727. err = 0;
  728. clnt = oldfid->clnt;
  729. if (clone) {
  730. fid = p9_fid_create(clnt);
  731. if (IS_ERR(fid)) {
  732. err = PTR_ERR(fid);
  733. fid = NULL;
  734. goto error;
  735. }
  736. fid->uid = oldfid->uid;
  737. } else
  738. fid = oldfid;
  739. P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n",
  740. oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
  741. req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
  742. nwname, wnames);
  743. if (IS_ERR(req)) {
  744. err = PTR_ERR(req);
  745. goto error;
  746. }
  747. err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
  748. if (err) {
  749. p9pdu_dump(1, req->rc);
  750. p9_free_req(clnt, req);
  751. goto clunk_fid;
  752. }
  753. p9_free_req(clnt, req);
  754. P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
  755. if (nwqids != nwname) {
  756. err = -ENOENT;
  757. goto clunk_fid;
  758. }
  759. for (count = 0; count < nwqids; count++)
  760. P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n",
  761. count, wqids[count].type,
  762. (unsigned long long)wqids[count].path,
  763. wqids[count].version);
  764. if (nwname)
  765. memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
  766. else
  767. fid->qid = oldfid->qid;
  768. return fid;
  769. clunk_fid:
  770. p9_client_clunk(fid);
  771. fid = NULL;
  772. error:
  773. if (fid && (fid != oldfid))
  774. p9_fid_destroy(fid);
  775. return ERR_PTR(err);
  776. }
  777. EXPORT_SYMBOL(p9_client_walk);
  778. int p9_client_open(struct p9_fid *fid, int mode)
  779. {
  780. int err;
  781. struct p9_client *clnt;
  782. struct p9_req_t *req;
  783. struct p9_qid qid;
  784. int iounit;
  785. P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode);
  786. err = 0;
  787. clnt = fid->clnt;
  788. if (fid->mode != -1)
  789. return -EINVAL;
  790. req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
  791. if (IS_ERR(req)) {
  792. err = PTR_ERR(req);
  793. goto error;
  794. }
  795. err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
  796. if (err) {
  797. p9pdu_dump(1, req->rc);
  798. goto free_and_error;
  799. }
  800. P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n",
  801. qid.type,
  802. (unsigned long long)qid.path,
  803. qid.version, iounit);
  804. fid->mode = mode;
  805. fid->iounit = iounit;
  806. free_and_error:
  807. p9_free_req(clnt, req);
  808. error:
  809. return err;
  810. }
  811. EXPORT_SYMBOL(p9_client_open);
  812. int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
  813. char *extension)
  814. {
  815. int err;
  816. struct p9_client *clnt;
  817. struct p9_req_t *req;
  818. struct p9_qid qid;
  819. int iounit;
  820. P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
  821. fid->fid, name, perm, mode);
  822. err = 0;
  823. clnt = fid->clnt;
  824. if (fid->mode != -1)
  825. return -EINVAL;
  826. req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
  827. mode, extension);
  828. if (IS_ERR(req)) {
  829. err = PTR_ERR(req);
  830. goto error;
  831. }
  832. err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
  833. if (err) {
  834. p9pdu_dump(1, req->rc);
  835. goto free_and_error;
  836. }
  837. P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
  838. qid.type,
  839. (unsigned long long)qid.path,
  840. qid.version, iounit);
  841. fid->mode = mode;
  842. fid->iounit = iounit;
  843. free_and_error:
  844. p9_free_req(clnt, req);
  845. error:
  846. return err;
  847. }
  848. EXPORT_SYMBOL(p9_client_fcreate);
  849. int p9_client_clunk(struct p9_fid *fid)
  850. {
  851. int err;
  852. struct p9_client *clnt;
  853. struct p9_req_t *req;
  854. P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
  855. err = 0;
  856. clnt = fid->clnt;
  857. req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
  858. if (IS_ERR(req)) {
  859. err = PTR_ERR(req);
  860. goto error;
  861. }
  862. P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
  863. p9_free_req(clnt, req);
  864. p9_fid_destroy(fid);
  865. error:
  866. return err;
  867. }
  868. EXPORT_SYMBOL(p9_client_clunk);
  869. int p9_client_remove(struct p9_fid *fid)
  870. {
  871. int err;
  872. struct p9_client *clnt;
  873. struct p9_req_t *req;
  874. P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
  875. err = 0;
  876. clnt = fid->clnt;
  877. req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
  878. if (IS_ERR(req)) {
  879. err = PTR_ERR(req);
  880. goto error;
  881. }
  882. P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
  883. p9_free_req(clnt, req);
  884. p9_fid_destroy(fid);
  885. error:
  886. return err;
  887. }
  888. EXPORT_SYMBOL(p9_client_remove);
  889. int
  890. p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
  891. u32 count)
  892. {
  893. int err, rsize, total;
  894. struct p9_client *clnt;
  895. struct p9_req_t *req;
  896. char *dataptr;
  897. P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid,
  898. (long long unsigned) offset, count);
  899. err = 0;
  900. clnt = fid->clnt;
  901. total = 0;
  902. rsize = fid->iounit;
  903. if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
  904. rsize = clnt->msize - P9_IOHDRSZ;
  905. if (count < rsize)
  906. rsize = count;
  907. req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize);
  908. if (IS_ERR(req)) {
  909. err = PTR_ERR(req);
  910. goto error;
  911. }
  912. err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
  913. if (err) {
  914. p9pdu_dump(1, req->rc);
  915. goto free_and_error;
  916. }
  917. P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
  918. if (data) {
  919. memmove(data, dataptr, count);
  920. }
  921. if (udata) {
  922. err = copy_to_user(udata, dataptr, count);
  923. if (err) {
  924. err = -EFAULT;
  925. goto free_and_error;
  926. }
  927. }
  928. p9_free_req(clnt, req);
  929. return count;
  930. free_and_error:
  931. p9_free_req(clnt, req);
  932. error:
  933. return err;
  934. }
  935. EXPORT_SYMBOL(p9_client_read);
  936. int
  937. p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
  938. u64 offset, u32 count)
  939. {
  940. int err, rsize, total;
  941. struct p9_client *clnt;
  942. struct p9_req_t *req;
  943. P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
  944. fid->fid, (long long unsigned) offset, count);
  945. err = 0;
  946. clnt = fid->clnt;
  947. total = 0;
  948. rsize = fid->iounit;
  949. if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
  950. rsize = clnt->msize - P9_IOHDRSZ;
  951. if (count < rsize)
  952. rsize = count;
  953. if (data)
  954. req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, offset,
  955. rsize, data);
  956. else
  957. req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, offset,
  958. rsize, udata);
  959. if (IS_ERR(req)) {
  960. err = PTR_ERR(req);
  961. goto error;
  962. }
  963. err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
  964. if (err) {
  965. p9pdu_dump(1, req->rc);
  966. goto free_and_error;
  967. }
  968. P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
  969. p9_free_req(clnt, req);
  970. return count;
  971. free_and_error:
  972. p9_free_req(clnt, req);
  973. error:
  974. return err;
  975. }
  976. EXPORT_SYMBOL(p9_client_write);
  977. struct p9_wstat *p9_client_stat(struct p9_fid *fid)
  978. {
  979. int err;
  980. struct p9_client *clnt;
  981. struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
  982. struct p9_req_t *req;
  983. u16 ignored;
  984. P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
  985. if (!ret)
  986. return ERR_PTR(-ENOMEM);
  987. err = 0;
  988. clnt = fid->clnt;
  989. req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
  990. if (IS_ERR(req)) {
  991. err = PTR_ERR(req);
  992. goto error;
  993. }
  994. err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
  995. if (err) {
  996. p9pdu_dump(1, req->rc);
  997. p9_free_req(clnt, req);
  998. goto error;
  999. }
  1000. P9_DPRINTK(P9_DEBUG_9P,
  1001. "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
  1002. "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
  1003. "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
  1004. "<<< uid=%d gid=%d n_muid=%d\n",
  1005. ret->size, ret->type, ret->dev, ret->qid.type,
  1006. (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
  1007. ret->atime, ret->mtime, (unsigned long long)ret->length,
  1008. ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
  1009. ret->n_uid, ret->n_gid, ret->n_muid);
  1010. p9_free_req(clnt, req);
  1011. return ret;
  1012. error:
  1013. kfree(ret);
  1014. return ERR_PTR(err);
  1015. }
  1016. EXPORT_SYMBOL(p9_client_stat);
  1017. static int p9_client_statsize(struct p9_wstat *wst, int optional)
  1018. {
  1019. int ret;
  1020. /* NOTE: size shouldn't include its own length */
  1021. /* size[2] type[2] dev[4] qid[13] */
  1022. /* mode[4] atime[4] mtime[4] length[8]*/
  1023. /* name[s] uid[s] gid[s] muid[s] */
  1024. ret = 2+4+13+4+4+4+8+2+2+2+2;
  1025. if (wst->name)
  1026. ret += strlen(wst->name);
  1027. if (wst->uid)
  1028. ret += strlen(wst->uid);
  1029. if (wst->gid)
  1030. ret += strlen(wst->gid);
  1031. if (wst->muid)
  1032. ret += strlen(wst->muid);
  1033. if (optional) {
  1034. ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
  1035. if (wst->extension)
  1036. ret += strlen(wst->extension);
  1037. }
  1038. return ret;
  1039. }
  1040. int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
  1041. {
  1042. int err;
  1043. struct p9_req_t *req;
  1044. struct p9_client *clnt;
  1045. err = 0;
  1046. clnt = fid->clnt;
  1047. wst->size = p9_client_statsize(wst, clnt->dotu);
  1048. P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
  1049. P9_DPRINTK(P9_DEBUG_9P,
  1050. " sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
  1051. " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
  1052. " name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
  1053. " uid=%d gid=%d n_muid=%d\n",
  1054. wst->size, wst->type, wst->dev, wst->qid.type,
  1055. (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
  1056. wst->atime, wst->mtime, (unsigned long long)wst->length,
  1057. wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
  1058. wst->n_uid, wst->n_gid, wst->n_muid);
  1059. req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
  1060. if (IS_ERR(req)) {
  1061. err = PTR_ERR(req);
  1062. goto error;
  1063. }
  1064. P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
  1065. p9_free_req(clnt, req);
  1066. error:
  1067. return err;
  1068. }
  1069. EXPORT_SYMBOL(p9_client_wstat);