summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/9p/9p.h2
-rw-r--r--include/net/9p/client.h1
-rw-r--r--net/9p/client.c50
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 {
P9_RGETATTR,
P9_TSETATTR = 26,
P9_RSETATTR,
+ P9_TXATTRWALK = 30,
+ P9_RXATTRWALK,
P9_TREADDIR = 40,
P9_RREADDIR,
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 *);
int p9_is_proto_dotu(struct p9_client *clnt);
int p9_is_proto_dotl(struct p9_client *clnt);
+struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *);
#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:
}
EXPORT_SYMBOL(p9_client_rename);
+/*
+ * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
+ */
+struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
+ const char *attr_name, u64 *attr_size)
+{
+ int err;
+ struct p9_req_t *req;
+ struct p9_client *clnt;
+ struct p9_fid *attr_fid;
+
+ err = 0;
+ clnt = file_fid->clnt;
+ attr_fid = p9_fid_create(clnt);
+ if (IS_ERR(attr_fid)) {
+ err = PTR_ERR(attr_fid);
+ attr_fid = NULL;
+ goto error;
+ }
+ P9_DPRINTK(P9_DEBUG_9P,
+ ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
+ file_fid->fid, attr_fid->fid, attr_name);
+
+ req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
+ file_fid->fid, attr_fid->fid, attr_name);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
+ err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ p9_free_req(clnt, req);
+ goto clunk_fid;
+ }
+ p9_free_req(clnt, req);
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
+ attr_fid->fid, *attr_size);
+ return attr_fid;
+clunk_fid:
+ p9_client_clunk(attr_fid);
+ attr_fid = NULL;
+error:
+ if (attr_fid && (attr_fid != file_fid))
+ p9_fid_destroy(attr_fid);
+
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
+
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
{
int err, rsize, total;