diff options
-rw-r--r-- | include/net/9p/9p.h | 2 | ||||
-rw-r--r-- | include/net/9p/client.h | 1 | ||||
-rw-r--r-- | net/9p/client.c | 50 |
3 files changed, 53 insertions, 0 deletions
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index cf580a40e299..6fabb5e559ba 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
@@ -153,6 +153,8 @@ enum p9_msg_t { | |||
153 | P9_RGETATTR, | 153 | P9_RGETATTR, |
154 | P9_TSETATTR = 26, | 154 | P9_TSETATTR = 26, |
155 | P9_RSETATTR, | 155 | P9_RSETATTR, |
156 | P9_TXATTRWALK = 30, | ||
157 | P9_RXATTRWALK, | ||
156 | P9_TREADDIR = 40, | 158 | P9_TREADDIR = 40, |
157 | P9_RREADDIR, | 159 | P9_RREADDIR, |
158 | P9_TLINK = 70, | 160 | P9_TLINK = 70, |
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index d755c0ed6750..60398b1a3f75 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -260,5 +260,6 @@ void p9stat_free(struct p9_wstat *); | |||
260 | 260 | ||
261 | int p9_is_proto_dotu(struct p9_client *clnt); | 261 | int p9_is_proto_dotu(struct p9_client *clnt); |
262 | int p9_is_proto_dotl(struct p9_client *clnt); | 262 | int p9_is_proto_dotl(struct p9_client *clnt); |
263 | struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *); | ||
263 | 264 | ||
264 | #endif /* NET_9P_CLIENT_H */ | 265 | #endif /* NET_9P_CLIENT_H */ |
diff --git a/net/9p/client.c b/net/9p/client.c index c458e042d384..ec80ee71d453 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -1622,6 +1622,56 @@ error: | |||
1622 | } | 1622 | } |
1623 | EXPORT_SYMBOL(p9_client_rename); | 1623 | EXPORT_SYMBOL(p9_client_rename); |
1624 | 1624 | ||
1625 | /* | ||
1626 | * An xattrwalk without @attr_name gives the fid for the lisxattr namespace | ||
1627 | */ | ||
1628 | struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, | ||
1629 | const char *attr_name, u64 *attr_size) | ||
1630 | { | ||
1631 | int err; | ||
1632 | struct p9_req_t *req; | ||
1633 | struct p9_client *clnt; | ||
1634 | struct p9_fid *attr_fid; | ||
1635 | |||
1636 | err = 0; | ||
1637 | clnt = file_fid->clnt; | ||
1638 | attr_fid = p9_fid_create(clnt); | ||
1639 | if (IS_ERR(attr_fid)) { | ||
1640 | err = PTR_ERR(attr_fid); | ||
1641 | attr_fid = NULL; | ||
1642 | goto error; | ||
1643 | } | ||
1644 | P9_DPRINTK(P9_DEBUG_9P, | ||
1645 | ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", | ||
1646 | file_fid->fid, attr_fid->fid, attr_name); | ||
1647 | |||
1648 | req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds", | ||
1649 | file_fid->fid, attr_fid->fid, attr_name); | ||
1650 | if (IS_ERR(req)) { | ||
1651 | err = PTR_ERR(req); | ||
1652 | goto error; | ||
1653 | } | ||
1654 | err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); | ||
1655 | if (err) { | ||
1656 | p9pdu_dump(1, req->rc); | ||
1657 | p9_free_req(clnt, req); | ||
1658 | goto clunk_fid; | ||
1659 | } | ||
1660 | p9_free_req(clnt, req); | ||
1661 | P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n", | ||
1662 | attr_fid->fid, *attr_size); | ||
1663 | return attr_fid; | ||
1664 | clunk_fid: | ||
1665 | p9_client_clunk(attr_fid); | ||
1666 | attr_fid = NULL; | ||
1667 | error: | ||
1668 | if (attr_fid && (attr_fid != file_fid)) | ||
1669 | p9_fid_destroy(attr_fid); | ||
1670 | |||
1671 | return ERR_PTR(err); | ||
1672 | } | ||
1673 | EXPORT_SYMBOL_GPL(p9_client_xattrwalk); | ||
1674 | |||
1625 | int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) | 1675 | int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) |
1626 | { | 1676 | { |
1627 | int err, rsize, total; | 1677 | int err, rsize, total; |