aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/client.c')
-rw-r--r--net/9p/client.c233
1 files changed, 160 insertions, 73 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 9eb72505308f..a848bca9fbff 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -61,13 +61,13 @@ static const match_table_t tokens = {
61 61
62inline int p9_is_proto_dotl(struct p9_client *clnt) 62inline int p9_is_proto_dotl(struct p9_client *clnt)
63{ 63{
64 return (clnt->proto_version == p9_proto_2000L); 64 return clnt->proto_version == p9_proto_2000L;
65} 65}
66EXPORT_SYMBOL(p9_is_proto_dotl); 66EXPORT_SYMBOL(p9_is_proto_dotl);
67 67
68inline int p9_is_proto_dotu(struct p9_client *clnt) 68inline int p9_is_proto_dotu(struct p9_client *clnt)
69{ 69{
70 return (clnt->proto_version == p9_proto_2000u); 70 return clnt->proto_version == p9_proto_2000u;
71} 71}
72EXPORT_SYMBOL(p9_is_proto_dotu); 72EXPORT_SYMBOL(p9_is_proto_dotu);
73 73
@@ -450,32 +450,43 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
450 return err; 450 return err;
451 } 451 }
452 452
453 if (type == P9_RERROR) { 453 if (type == P9_RERROR || type == P9_RLERROR) {
454 int ecode; 454 int ecode;
455 char *ename;
456 455
457 err = p9pdu_readf(req->rc, c->proto_version, "s?d", 456 if (!p9_is_proto_dotl(c)) {
458 &ename, &ecode); 457 char *ename;
459 if (err) {
460 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
461 err);
462 return err;
463 }
464 458
465 if (p9_is_proto_dotu(c) || 459 err = p9pdu_readf(req->rc, c->proto_version, "s?d",
466 p9_is_proto_dotl(c)) 460 &ename, &ecode);
467 err = -ecode; 461 if (err)
462 goto out_err;
463
464 if (p9_is_proto_dotu(c))
465 err = -ecode;
468 466
469 if (!err || !IS_ERR_VALUE(err)) 467 if (!err || !IS_ERR_VALUE(err)) {
470 err = p9_errstr2errno(ename, strlen(ename)); 468 err = p9_errstr2errno(ename, strlen(ename));
469
470 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
471
472 kfree(ename);
473 }
474 } else {
475 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
476 err = -ecode;
471 477
472 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename); 478 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
479 }
473 480
474 kfree(ename);
475 } else 481 } else
476 err = 0; 482 err = 0;
477 483
478 return err; 484 return err;
485
486out_err:
487 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
488
489 return err;
479} 490}
480 491
481/** 492/**
@@ -568,11 +579,14 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
568 va_start(ap, fmt); 579 va_start(ap, fmt);
569 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); 580 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
570 va_end(ap); 581 va_end(ap);
582 if (err)
583 goto reterr;
571 p9pdu_finalize(req->tc); 584 p9pdu_finalize(req->tc);
572 585
573 err = c->trans_mod->request(c, req); 586 err = c->trans_mod->request(c, req);
574 if (err < 0) { 587 if (err < 0) {
575 c->status = Disconnected; 588 if (err != -ERESTARTSYS)
589 c->status = Disconnected;
576 goto reterr; 590 goto reterr;
577 } 591 }
578 592
@@ -671,7 +685,7 @@ static void p9_fid_destroy(struct p9_fid *fid)
671 kfree(fid); 685 kfree(fid);
672} 686}
673 687
674int p9_client_version(struct p9_client *c) 688static int p9_client_version(struct p9_client *c)
675{ 689{
676 int err = 0; 690 int err = 0;
677 struct p9_req_t *req; 691 struct p9_req_t *req;
@@ -730,7 +744,6 @@ error:
730 744
731 return err; 745 return err;
732} 746}
733EXPORT_SYMBOL(p9_client_version);
734 747
735struct p9_client *p9_client_create(const char *dev_name, char *options) 748struct p9_client *p9_client_create(const char *dev_name, char *options)
736{ 749{
@@ -887,54 +900,6 @@ error:
887} 900}
888EXPORT_SYMBOL(p9_client_attach); 901EXPORT_SYMBOL(p9_client_attach);
889 902
890struct p9_fid *
891p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
892{
893 int err;
894 struct p9_req_t *req;
895 struct p9_qid qid;
896 struct p9_fid *afid;
897
898 P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
899 err = 0;
900
901 afid = p9_fid_create(clnt);
902 if (IS_ERR(afid)) {
903 err = PTR_ERR(afid);
904 afid = NULL;
905 goto error;
906 }
907
908 req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
909 afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
910 if (IS_ERR(req)) {
911 err = PTR_ERR(req);
912 goto error;
913 }
914
915 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
916 if (err) {
917 p9pdu_dump(1, req->rc);
918 p9_free_req(clnt, req);
919 goto error;
920 }
921
922 P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
923 qid.type,
924 (unsigned long long)qid.path,
925 qid.version);
926
927 memmove(&afid->qid, &qid, sizeof(struct p9_qid));
928 p9_free_req(clnt, req);
929 return afid;
930
931error:
932 if (afid)
933 p9_fid_destroy(afid);
934 return ERR_PTR(err);
935}
936EXPORT_SYMBOL(p9_client_auth);
937
938struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, 903struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
939 int clone) 904 int clone)
940{ 905{
@@ -1200,12 +1165,44 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname)
1200} 1165}
1201EXPORT_SYMBOL(p9_client_link); 1166EXPORT_SYMBOL(p9_client_link);
1202 1167
1168int p9_client_fsync(struct p9_fid *fid, int datasync)
1169{
1170 int err;
1171 struct p9_client *clnt;
1172 struct p9_req_t *req;
1173
1174 P9_DPRINTK(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
1175 fid->fid, datasync);
1176 err = 0;
1177 clnt = fid->clnt;
1178
1179 req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
1180 if (IS_ERR(req)) {
1181 err = PTR_ERR(req);
1182 goto error;
1183 }
1184
1185 P9_DPRINTK(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
1186
1187 p9_free_req(clnt, req);
1188
1189error:
1190 return err;
1191}
1192EXPORT_SYMBOL(p9_client_fsync);
1193
1203int p9_client_clunk(struct p9_fid *fid) 1194int p9_client_clunk(struct p9_fid *fid)
1204{ 1195{
1205 int err; 1196 int err;
1206 struct p9_client *clnt; 1197 struct p9_client *clnt;
1207 struct p9_req_t *req; 1198 struct p9_req_t *req;
1208 1199
1200 if (!fid) {
1201 P9_EPRINTK(KERN_WARNING, "Trying to clunk with NULL fid\n");
1202 dump_stack();
1203 return 0;
1204 }
1205
1209 P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid); 1206 P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
1210 err = 0; 1207 err = 0;
1211 clnt = fid->clnt; 1208 clnt = fid->clnt;
@@ -1289,16 +1286,13 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1289 1286
1290 if (data) { 1287 if (data) {
1291 memmove(data, dataptr, count); 1288 memmove(data, dataptr, count);
1292 } 1289 } else {
1293
1294 if (udata) {
1295 err = copy_to_user(udata, dataptr, count); 1290 err = copy_to_user(udata, dataptr, count);
1296 if (err) { 1291 if (err) {
1297 err = -EFAULT; 1292 err = -EFAULT;
1298 goto free_and_error; 1293 goto free_and_error;
1299 } 1294 }
1300 } 1295 }
1301
1302 p9_free_req(clnt, req); 1296 p9_free_req(clnt, req);
1303 return count; 1297 return count;
1304 1298
@@ -1810,3 +1804,96 @@ error:
1810 1804
1811} 1805}
1812EXPORT_SYMBOL(p9_client_mkdir_dotl); 1806EXPORT_SYMBOL(p9_client_mkdir_dotl);
1807
1808int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
1809{
1810 int err;
1811 struct p9_client *clnt;
1812 struct p9_req_t *req;
1813
1814 err = 0;
1815 clnt = fid->clnt;
1816 P9_DPRINTK(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
1817 "start %lld length %lld proc_id %d client_id %s\n",
1818 fid->fid, flock->type, flock->flags, flock->start,
1819 flock->length, flock->proc_id, flock->client_id);
1820
1821 req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
1822 flock->flags, flock->start, flock->length,
1823 flock->proc_id, flock->client_id);
1824
1825 if (IS_ERR(req))
1826 return PTR_ERR(req);
1827
1828 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
1829 if (err) {
1830 p9pdu_dump(1, req->rc);
1831 goto error;
1832 }
1833 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
1834error:
1835 p9_free_req(clnt, req);
1836 return err;
1837
1838}
1839EXPORT_SYMBOL(p9_client_lock_dotl);
1840
1841int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
1842{
1843 int err;
1844 struct p9_client *clnt;
1845 struct p9_req_t *req;
1846
1847 err = 0;
1848 clnt = fid->clnt;
1849 P9_DPRINTK(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
1850 "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
1851 glock->start, glock->length, glock->proc_id, glock->client_id);
1852
1853 req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid, glock->type,
1854 glock->start, glock->length, glock->proc_id, glock->client_id);
1855
1856 if (IS_ERR(req))
1857 return PTR_ERR(req);
1858
1859 err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
1860 &glock->start, &glock->length, &glock->proc_id,
1861 &glock->client_id);
1862 if (err) {
1863 p9pdu_dump(1, req->rc);
1864 goto error;
1865 }
1866 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
1867 "proc_id %d client_id %s\n", glock->type, glock->start,
1868 glock->length, glock->proc_id, glock->client_id);
1869error:
1870 p9_free_req(clnt, req);
1871 return err;
1872}
1873EXPORT_SYMBOL(p9_client_getlock_dotl);
1874
1875int p9_client_readlink(struct p9_fid *fid, char **target)
1876{
1877 int err;
1878 struct p9_client *clnt;
1879 struct p9_req_t *req;
1880
1881 err = 0;
1882 clnt = fid->clnt;
1883 P9_DPRINTK(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
1884
1885 req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
1886 if (IS_ERR(req))
1887 return PTR_ERR(req);
1888
1889 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
1890 if (err) {
1891 p9pdu_dump(1, req->rc);
1892 goto error;
1893 }
1894 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
1895error:
1896 p9_free_req(clnt, req);
1897 return err;
1898}
1899EXPORT_SYMBOL(p9_client_readlink);