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.c155
1 files changed, 116 insertions, 39 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 9e3b0e640da..0505a03c374 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -72,23 +72,22 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
72EXPORT_SYMBOL(p9_is_proto_dotu); 72EXPORT_SYMBOL(p9_is_proto_dotu);
73 73
74/* Interpret mount option for protocol version */ 74/* Interpret mount option for protocol version */
75static int get_protocol_version(const substring_t *name) 75static int get_protocol_version(char *s)
76{ 76{
77 int version = -EINVAL; 77 int version = -EINVAL;
78 78
79 if (!strncmp("9p2000", name->from, name->to-name->from)) { 79 if (!strcmp(s, "9p2000")) {
80 version = p9_proto_legacy; 80 version = p9_proto_legacy;
81 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n"); 81 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
82 } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { 82 } else if (!strcmp(s, "9p2000.u")) {
83 version = p9_proto_2000u; 83 version = p9_proto_2000u;
84 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); 84 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
85 } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) { 85 } else if (!strcmp(s, "9p2000.L")) {
86 version = p9_proto_2000L; 86 version = p9_proto_2000L;
87 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n"); 87 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
88 } else { 88 } else
89 P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", 89 printk(KERN_INFO "9p: Unknown protocol version %s.\n", s);
90 name->from); 90
91 }
92 return version; 91 return version;
93} 92}
94 93
@@ -106,6 +105,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
106 char *p; 105 char *p;
107 substring_t args[MAX_OPT_ARGS]; 106 substring_t args[MAX_OPT_ARGS];
108 int option; 107 int option;
108 char *s;
109 int ret = 0; 109 int ret = 0;
110 110
111 clnt->proto_version = p9_proto_2000u; 111 clnt->proto_version = p9_proto_2000u;
@@ -141,22 +141,41 @@ static int parse_opts(char *opts, struct p9_client *clnt)
141 clnt->msize = option; 141 clnt->msize = option;
142 break; 142 break;
143 case Opt_trans: 143 case Opt_trans:
144 clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); 144 s = match_strdup(&args[0]);
145 if(clnt->trans_mod == NULL) { 145 if (!s) {
146 ret = -ENOMEM;
146 P9_DPRINTK(P9_DEBUG_ERROR, 147 P9_DPRINTK(P9_DEBUG_ERROR,
147 "Could not find request transport: %s\n", 148 "problem allocating copy of trans arg\n");
148 (char *) &args[0]); 149 goto free_and_return;
150 }
151 clnt->trans_mod = v9fs_get_trans_by_name(s);
152 if (clnt->trans_mod == NULL) {
153 printk(KERN_INFO
154 "9p: Could not find "
155 "request transport: %s\n", s);
149 ret = -EINVAL; 156 ret = -EINVAL;
157 kfree(s);
150 goto free_and_return; 158 goto free_and_return;
151 } 159 }
160 kfree(s);
152 break; 161 break;
153 case Opt_legacy: 162 case Opt_legacy:
154 clnt->proto_version = p9_proto_legacy; 163 clnt->proto_version = p9_proto_legacy;
155 break; 164 break;
156 case Opt_version: 165 case Opt_version:
157 ret = get_protocol_version(&args[0]); 166 s = match_strdup(&args[0]);
158 if (ret == -EINVAL) 167 if (!s) {
168 ret = -ENOMEM;
169 P9_DPRINTK(P9_DEBUG_ERROR,
170 "problem allocating copy of version arg\n");
159 goto free_and_return; 171 goto free_and_return;
172 }
173 ret = get_protocol_version(s);
174 if (ret == -EINVAL) {
175 kfree(s);
176 goto free_and_return;
177 }
178 kfree(s);
160 clnt->proto_version = ret; 179 clnt->proto_version = ret;
161 break; 180 break;
162 default: 181 default:
@@ -280,7 +299,8 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
280 * buffer to read the data into */ 299 * buffer to read the data into */
281 tag++; 300 tag++;
282 301
283 BUG_ON(tag >= c->max_tag); 302 if(tag >= c->max_tag)
303 return NULL;
284 304
285 row = tag / P9_ROW_MAXTAG; 305 row = tag / P9_ROW_MAXTAG;
286 col = tag % P9_ROW_MAXTAG; 306 col = tag % P9_ROW_MAXTAG;
@@ -749,7 +769,7 @@ static int p9_client_version(struct p9_client *c)
749 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); 769 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
750 if (err) { 770 if (err) {
751 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); 771 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
752 p9pdu_dump(1, req->rc); 772 P9_DUMP_PKT(1, req->rc);
753 goto error; 773 goto error;
754 } 774 }
755 775
@@ -821,8 +841,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
821 if (err) 841 if (err)
822 goto destroy_fidpool; 842 goto destroy_fidpool;
823 843
824 if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) 844 if (clnt->msize > clnt->trans_mod->maxsize)
825 clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; 845 clnt->msize = clnt->trans_mod->maxsize;
826 846
827 err = p9_client_version(clnt); 847 err = p9_client_version(clnt);
828 if (err) 848 if (err)
@@ -911,7 +931,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
911 931
912 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); 932 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
913 if (err) { 933 if (err) {
914 p9pdu_dump(1, req->rc); 934 P9_DUMP_PKT(1, req->rc);
915 p9_free_req(clnt, req); 935 p9_free_req(clnt, req);
916 goto error; 936 goto error;
917 } 937 }
@@ -971,7 +991,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
971 991
972 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); 992 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
973 if (err) { 993 if (err) {
974 p9pdu_dump(1, req->rc); 994 P9_DUMP_PKT(1, req->rc);
975 p9_free_req(clnt, req); 995 p9_free_req(clnt, req);
976 goto clunk_fid; 996 goto clunk_fid;
977 } 997 }
@@ -1038,7 +1058,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
1038 1058
1039 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1059 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1040 if (err) { 1060 if (err) {
1041 p9pdu_dump(1, req->rc); 1061 P9_DUMP_PKT(1, req->rc);
1042 goto free_and_error; 1062 goto free_and_error;
1043 } 1063 }
1044 1064
@@ -1081,7 +1101,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1081 1101
1082 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); 1102 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
1083 if (err) { 1103 if (err) {
1084 p9pdu_dump(1, req->rc); 1104 P9_DUMP_PKT(1, req->rc);
1085 goto free_and_error; 1105 goto free_and_error;
1086 } 1106 }
1087 1107
@@ -1126,7 +1146,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
1126 1146
1127 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1147 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1128 if (err) { 1148 if (err) {
1129 p9pdu_dump(1, req->rc); 1149 P9_DUMP_PKT(1, req->rc);
1130 goto free_and_error; 1150 goto free_and_error;
1131 } 1151 }
1132 1152
@@ -1165,7 +1185,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
1165 1185
1166 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1186 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1167 if (err) { 1187 if (err) {
1168 p9pdu_dump(1, req->rc); 1188 P9_DUMP_PKT(1, req->rc);
1169 goto free_and_error; 1189 goto free_and_error;
1170 } 1190 }
1171 1191
@@ -1249,9 +1269,11 @@ int p9_client_clunk(struct p9_fid *fid)
1249 P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid); 1269 P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
1250 1270
1251 p9_free_req(clnt, req); 1271 p9_free_req(clnt, req);
1252 p9_fid_destroy(fid);
1253
1254error: 1272error:
1273 /*
1274 * Fid is not valid even after a failed clunk
1275 */
1276 p9_fid_destroy(fid);
1255 return err; 1277 return err;
1256} 1278}
1257EXPORT_SYMBOL(p9_client_clunk); 1279EXPORT_SYMBOL(p9_client_clunk);
@@ -1281,6 +1303,29 @@ error:
1281} 1303}
1282EXPORT_SYMBOL(p9_client_remove); 1304EXPORT_SYMBOL(p9_client_remove);
1283 1305
1306int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
1307{
1308 int err = 0;
1309 struct p9_req_t *req;
1310 struct p9_client *clnt;
1311
1312 P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
1313 dfid->fid, name, flags);
1314
1315 clnt = dfid->clnt;
1316 req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
1317 if (IS_ERR(req)) {
1318 err = PTR_ERR(req);
1319 goto error;
1320 }
1321 P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
1322
1323 p9_free_req(clnt, req);
1324error:
1325 return err;
1326}
1327EXPORT_SYMBOL(p9_client_unlinkat);
1328
1284int 1329int
1285p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, 1330p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1286 u32 count) 1331 u32 count)
@@ -1318,11 +1363,12 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1318 1363
1319 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1364 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1320 if (err) { 1365 if (err) {
1321 p9pdu_dump(1, req->rc); 1366 P9_DUMP_PKT(1, req->rc);
1322 goto free_and_error; 1367 goto free_and_error;
1323 } 1368 }
1324 1369
1325 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1370 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1371 P9_DUMP_PKT(1, req->rc);
1326 1372
1327 if (!req->tc->pbuf_size) { 1373 if (!req->tc->pbuf_size) {
1328 if (data) { 1374 if (data) {
@@ -1386,7 +1432,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1386 1432
1387 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); 1433 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1388 if (err) { 1434 if (err) {
1389 p9pdu_dump(1, req->rc); 1435 P9_DUMP_PKT(1, req->rc);
1390 goto free_and_error; 1436 goto free_and_error;
1391 } 1437 }
1392 1438
@@ -1426,7 +1472,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1426 1472
1427 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); 1473 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
1428 if (err) { 1474 if (err) {
1429 p9pdu_dump(1, req->rc); 1475 P9_DUMP_PKT(1, req->rc);
1430 p9_free_req(clnt, req); 1476 p9_free_req(clnt, req);
1431 goto error; 1477 goto error;
1432 } 1478 }
@@ -1477,7 +1523,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1477 1523
1478 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); 1524 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
1479 if (err) { 1525 if (err) {
1480 p9pdu_dump(1, req->rc); 1526 P9_DUMP_PKT(1, req->rc);
1481 p9_free_req(clnt, req); 1527 p9_free_req(clnt, req);
1482 goto error; 1528 goto error;
1483 } 1529 }
@@ -1625,7 +1671,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1625 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, 1671 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1626 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); 1672 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1627 if (err) { 1673 if (err) {
1628 p9pdu_dump(1, req->rc); 1674 P9_DUMP_PKT(1, req->rc);
1629 p9_free_req(clnt, req); 1675 p9_free_req(clnt, req);
1630 goto error; 1676 goto error;
1631 } 1677 }
@@ -1643,7 +1689,8 @@ error:
1643} 1689}
1644EXPORT_SYMBOL(p9_client_statfs); 1690EXPORT_SYMBOL(p9_client_statfs);
1645 1691
1646int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name) 1692int p9_client_rename(struct p9_fid *fid,
1693 struct p9_fid *newdirfid, const char *name)
1647{ 1694{
1648 int err; 1695 int err;
1649 struct p9_req_t *req; 1696 struct p9_req_t *req;
@@ -1670,6 +1717,36 @@ error:
1670} 1717}
1671EXPORT_SYMBOL(p9_client_rename); 1718EXPORT_SYMBOL(p9_client_rename);
1672 1719
1720int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
1721 struct p9_fid *newdirfid, const char *new_name)
1722{
1723 int err;
1724 struct p9_req_t *req;
1725 struct p9_client *clnt;
1726
1727 err = 0;
1728 clnt = olddirfid->clnt;
1729
1730 P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
1731 " newdirfid %d new name %s\n", olddirfid->fid, old_name,
1732 newdirfid->fid, new_name);
1733
1734 req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
1735 old_name, newdirfid->fid, new_name);
1736 if (IS_ERR(req)) {
1737 err = PTR_ERR(req);
1738 goto error;
1739 }
1740
1741 P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
1742 newdirfid->fid, new_name);
1743
1744 p9_free_req(clnt, req);
1745error:
1746 return err;
1747}
1748EXPORT_SYMBOL(p9_client_renameat);
1749
1673/* 1750/*
1674 * An xattrwalk without @attr_name gives the fid for the lisxattr namespace 1751 * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
1675 */ 1752 */
@@ -1701,7 +1778,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
1701 } 1778 }
1702 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); 1779 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
1703 if (err) { 1780 if (err) {
1704 p9pdu_dump(1, req->rc); 1781 P9_DUMP_PKT(1, req->rc);
1705 p9_free_req(clnt, req); 1782 p9_free_req(clnt, req);
1706 goto clunk_fid; 1783 goto clunk_fid;
1707 } 1784 }
@@ -1780,7 +1857,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1780 1857
1781 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1858 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1782 if (err) { 1859 if (err) {
1783 p9pdu_dump(1, req->rc); 1860 P9_DUMP_PKT(1, req->rc);
1784 goto free_and_error; 1861 goto free_and_error;
1785 } 1862 }
1786 1863
@@ -1817,7 +1894,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
1817 1894
1818 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1895 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1819 if (err) { 1896 if (err) {
1820 p9pdu_dump(1, req->rc); 1897 P9_DUMP_PKT(1, req->rc);
1821 goto error; 1898 goto error;
1822 } 1899 }
1823 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, 1900 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
@@ -1848,7 +1925,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
1848 1925
1849 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1926 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1850 if (err) { 1927 if (err) {
1851 p9pdu_dump(1, req->rc); 1928 P9_DUMP_PKT(1, req->rc);
1852 goto error; 1929 goto error;
1853 } 1930 }
1854 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, 1931 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
@@ -1883,7 +1960,7 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
1883 1960
1884 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status); 1961 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
1885 if (err) { 1962 if (err) {
1886 p9pdu_dump(1, req->rc); 1963 P9_DUMP_PKT(1, req->rc);
1887 goto error; 1964 goto error;
1888 } 1965 }
1889 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status); 1966 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
@@ -1916,7 +1993,7 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
1916 &glock->start, &glock->length, &glock->proc_id, 1993 &glock->start, &glock->length, &glock->proc_id,
1917 &glock->client_id); 1994 &glock->client_id);
1918 if (err) { 1995 if (err) {
1919 p9pdu_dump(1, req->rc); 1996 P9_DUMP_PKT(1, req->rc);
1920 goto error; 1997 goto error;
1921 } 1998 }
1922 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " 1999 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
@@ -1944,7 +2021,7 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
1944 2021
1945 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target); 2022 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
1946 if (err) { 2023 if (err) {
1947 p9pdu_dump(1, req->rc); 2024 P9_DUMP_PKT(1, req->rc);
1948 goto error; 2025 goto error;
1949 } 2026 }
1950 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target); 2027 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);