LCOV - code coverage report
Current view: top level - net/9p - protocol.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 316 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 13 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * net/9p/protocol.c
       4             :  *
       5             :  * 9P Protocol Support Code
       6             :  *
       7             :  *  Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
       8             :  *
       9             :  *  Base on code from Anthony Liguori <aliguori@us.ibm.com>
      10             :  *  Copyright (C) 2008 by IBM, Corp.
      11             :  */
      12             : 
      13             : #include <linux/module.h>
      14             : #include <linux/errno.h>
      15             : #include <linux/kernel.h>
      16             : #include <linux/uaccess.h>
      17             : #include <linux/slab.h>
      18             : #include <linux/sched.h>
      19             : #include <linux/stddef.h>
      20             : #include <linux/types.h>
      21             : #include <linux/uio.h>
      22             : #include <net/9p/9p.h>
      23             : #include <net/9p/client.h>
      24             : #include "protocol.h"
      25             : 
      26             : #include <trace/events/9p.h>
      27             : 
      28             : static int
      29             : p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
      30             : 
      31           0 : void p9stat_free(struct p9_wstat *stbuf)
      32             : {
      33           0 :         kfree(stbuf->name);
      34           0 :         stbuf->name = NULL;
      35           0 :         kfree(stbuf->uid);
      36           0 :         stbuf->uid = NULL;
      37           0 :         kfree(stbuf->gid);
      38           0 :         stbuf->gid = NULL;
      39           0 :         kfree(stbuf->muid);
      40           0 :         stbuf->muid = NULL;
      41           0 :         kfree(stbuf->extension);
      42           0 :         stbuf->extension = NULL;
      43           0 : }
      44             : EXPORT_SYMBOL(p9stat_free);
      45             : 
      46           0 : size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
      47             : {
      48           0 :         size_t len = min(pdu->size - pdu->offset, size);
      49           0 :         memcpy(data, &pdu->sdata[pdu->offset], len);
      50           0 :         pdu->offset += len;
      51           0 :         return size - len;
      52             : }
      53             : 
      54           0 : static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
      55             : {
      56           0 :         size_t len = min(pdu->capacity - pdu->size, size);
      57           0 :         memcpy(&pdu->sdata[pdu->size], data, len);
      58           0 :         pdu->size += len;
      59           0 :         return size - len;
      60             : }
      61             : 
      62             : static size_t
      63           0 : pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
      64             : {
      65           0 :         size_t len = min(pdu->capacity - pdu->size, size);
      66           0 :         struct iov_iter i = *from;
      67           0 :         if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, &i))
      68             :                 len = 0;
      69             : 
      70           0 :         pdu->size += len;
      71           0 :         return size - len;
      72             : }
      73             : 
      74             : /*
      75             :         b - int8_t
      76             :         w - int16_t
      77             :         d - int32_t
      78             :         q - int64_t
      79             :         s - string
      80             :         u - numeric uid
      81             :         g - numeric gid
      82             :         S - stat
      83             :         Q - qid
      84             :         D - data blob (int32_t size followed by void *, results are not freed)
      85             :         T - array of strings (int16_t count, followed by strings)
      86             :         R - array of qids (int16_t count, followed by qids)
      87             :         A - stat for 9p2000.L (p9_stat_dotl)
      88             :         ? - if optional = 1, continue parsing
      89             : */
      90             : 
      91             : static int
      92           0 : p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
      93             :         va_list ap)
      94             : {
      95           0 :         const char *ptr;
      96           0 :         int errcode = 0;
      97             : 
      98           0 :         for (ptr = fmt; *ptr; ptr++) {
      99           0 :                 switch (*ptr) {
     100           0 :                 case 'b':{
     101           0 :                                 int8_t *val = va_arg(ap, int8_t *);
     102           0 :                                 if (pdu_read(pdu, val, sizeof(*val))) {
     103             :                                         errcode = -EFAULT;
     104             :                                         break;
     105             :                                 }
     106             :                         }
     107             :                         break;
     108           0 :                 case 'w':{
     109           0 :                                 int16_t *val = va_arg(ap, int16_t *);
     110           0 :                                 __le16 le_val;
     111           0 :                                 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
     112           0 :                                         errcode = -EFAULT;
     113           0 :                                         break;
     114             :                                 }
     115           0 :                                 *val = le16_to_cpu(le_val);
     116             :                         }
     117           0 :                         break;
     118           0 :                 case 'd':{
     119           0 :                                 int32_t *val = va_arg(ap, int32_t *);
     120           0 :                                 __le32 le_val;
     121           0 :                                 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
     122           0 :                                         errcode = -EFAULT;
     123           0 :                                         break;
     124             :                                 }
     125           0 :                                 *val = le32_to_cpu(le_val);
     126             :                         }
     127           0 :                         break;
     128           0 :                 case 'q':{
     129           0 :                                 int64_t *val = va_arg(ap, int64_t *);
     130           0 :                                 __le64 le_val;
     131           0 :                                 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
     132           0 :                                         errcode = -EFAULT;
     133           0 :                                         break;
     134             :                                 }
     135           0 :                                 *val = le64_to_cpu(le_val);
     136             :                         }
     137           0 :                         break;
     138           0 :                 case 's':{
     139           0 :                                 char **sptr = va_arg(ap, char **);
     140           0 :                                 uint16_t len;
     141             : 
     142           0 :                                 errcode = p9pdu_readf(pdu, proto_version,
     143             :                                                                 "w", &len);
     144           0 :                                 if (errcode)
     145             :                                         break;
     146             : 
     147           0 :                                 *sptr = kmalloc(len + 1, GFP_NOFS);
     148           0 :                                 if (*sptr == NULL) {
     149             :                                         errcode = -ENOMEM;
     150             :                                         break;
     151             :                                 }
     152           0 :                                 if (pdu_read(pdu, *sptr, len)) {
     153           0 :                                         errcode = -EFAULT;
     154           0 :                                         kfree(*sptr);
     155           0 :                                         *sptr = NULL;
     156             :                                 } else
     157           0 :                                         (*sptr)[len] = 0;
     158             :                         }
     159           0 :                         break;
     160           0 :                 case 'u': {
     161           0 :                                 kuid_t *uid = va_arg(ap, kuid_t *);
     162           0 :                                 __le32 le_val;
     163           0 :                                 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
     164           0 :                                         errcode = -EFAULT;
     165           0 :                                         break;
     166             :                                 }
     167           0 :                                 *uid = make_kuid(&init_user_ns,
     168             :                                                  le32_to_cpu(le_val));
     169           0 :                         } break;
     170           0 :                 case 'g': {
     171           0 :                                 kgid_t *gid = va_arg(ap, kgid_t *);
     172           0 :                                 __le32 le_val;
     173           0 :                                 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
     174           0 :                                         errcode = -EFAULT;
     175           0 :                                         break;
     176             :                                 }
     177           0 :                                 *gid = make_kgid(&init_user_ns,
     178             :                                                  le32_to_cpu(le_val));
     179           0 :                         } break;
     180           0 :                 case 'Q':{
     181           0 :                                 struct p9_qid *qid =
     182             :                                     va_arg(ap, struct p9_qid *);
     183             : 
     184           0 :                                 errcode = p9pdu_readf(pdu, proto_version, "bdq",
     185             :                                                       &qid->type, &qid->version,
     186             :                                                       &qid->path);
     187             :                         }
     188           0 :                         break;
     189           0 :                 case 'S':{
     190           0 :                                 struct p9_wstat *stbuf =
     191             :                                     va_arg(ap, struct p9_wstat *);
     192             : 
     193           0 :                                 memset(stbuf, 0, sizeof(struct p9_wstat));
     194           0 :                                 stbuf->n_uid = stbuf->n_muid = INVALID_UID;
     195           0 :                                 stbuf->n_gid = INVALID_GID;
     196             : 
     197           0 :                                 errcode =
     198           0 :                                     p9pdu_readf(pdu, proto_version,
     199             :                                                 "wwdQdddqssss?sugu",
     200             :                                                 &stbuf->size, &stbuf->type,
     201             :                                                 &stbuf->dev, &stbuf->qid,
     202             :                                                 &stbuf->mode, &stbuf->atime,
     203             :                                                 &stbuf->mtime, &stbuf->length,
     204             :                                                 &stbuf->name, &stbuf->uid,
     205             :                                                 &stbuf->gid, &stbuf->muid,
     206             :                                                 &stbuf->extension,
     207             :                                                 &stbuf->n_uid, &stbuf->n_gid,
     208             :                                                 &stbuf->n_muid);
     209           0 :                                 if (errcode)
     210           0 :                                         p9stat_free(stbuf);
     211             :                         }
     212             :                         break;
     213           0 :                 case 'D':{
     214           0 :                                 uint32_t *count = va_arg(ap, uint32_t *);
     215           0 :                                 void **data = va_arg(ap, void **);
     216             : 
     217           0 :                                 errcode =
     218           0 :                                     p9pdu_readf(pdu, proto_version, "d", count);
     219           0 :                                 if (!errcode) {
     220           0 :                                         *count =
     221           0 :                                             min_t(uint32_t, *count,
     222             :                                                   pdu->size - pdu->offset);
     223           0 :                                         *data = &pdu->sdata[pdu->offset];
     224             :                                 }
     225             :                         }
     226             :                         break;
     227           0 :                 case 'T':{
     228           0 :                                 uint16_t *nwname = va_arg(ap, uint16_t *);
     229           0 :                                 char ***wnames = va_arg(ap, char ***);
     230             : 
     231           0 :                                 errcode = p9pdu_readf(pdu, proto_version,
     232             :                                                                 "w", nwname);
     233           0 :                                 if (!errcode) {
     234           0 :                                         *wnames =
     235           0 :                                             kmalloc_array(*nwname,
     236             :                                                           sizeof(char *),
     237             :                                                           GFP_NOFS);
     238           0 :                                         if (!*wnames)
     239             :                                                 errcode = -ENOMEM;
     240             :                                 }
     241             : 
     242           0 :                                 if (!errcode) {
     243             :                                         int i;
     244             : 
     245           0 :                                         for (i = 0; i < *nwname; i++) {
     246           0 :                                                 errcode =
     247           0 :                                                     p9pdu_readf(pdu,
     248             :                                                                 proto_version,
     249             :                                                                 "s",
     250           0 :                                                                 &(*wnames)[i]);
     251           0 :                                                 if (errcode)
     252             :                                                         break;
     253             :                                         }
     254             :                                 }
     255             : 
     256           0 :                                 if (errcode) {
     257           0 :                                         if (*wnames) {
     258             :                                                 int i;
     259             : 
     260           0 :                                                 for (i = 0; i < *nwname; i++)
     261           0 :                                                         kfree((*wnames)[i]);
     262             :                                         }
     263           0 :                                         kfree(*wnames);
     264           0 :                                         *wnames = NULL;
     265             :                                 }
     266             :                         }
     267             :                         break;
     268           0 :                 case 'R':{
     269           0 :                                 uint16_t *nwqid = va_arg(ap, uint16_t *);
     270           0 :                                 struct p9_qid **wqids =
     271             :                                     va_arg(ap, struct p9_qid **);
     272             : 
     273           0 :                                 *wqids = NULL;
     274             : 
     275           0 :                                 errcode =
     276           0 :                                     p9pdu_readf(pdu, proto_version, "w", nwqid);
     277           0 :                                 if (!errcode) {
     278           0 :                                         *wqids =
     279           0 :                                             kmalloc_array(*nwqid,
     280             :                                                           sizeof(struct p9_qid),
     281             :                                                           GFP_NOFS);
     282           0 :                                         if (*wqids == NULL)
     283             :                                                 errcode = -ENOMEM;
     284             :                                 }
     285             : 
     286           0 :                                 if (!errcode) {
     287             :                                         int i;
     288             : 
     289           0 :                                         for (i = 0; i < *nwqid; i++) {
     290           0 :                                                 errcode =
     291           0 :                                                     p9pdu_readf(pdu,
     292             :                                                                 proto_version,
     293             :                                                                 "Q",
     294           0 :                                                                 &(*wqids)[i]);
     295           0 :                                                 if (errcode)
     296             :                                                         break;
     297             :                                         }
     298             :                                 }
     299             : 
     300           0 :                                 if (errcode) {
     301           0 :                                         kfree(*wqids);
     302           0 :                                         *wqids = NULL;
     303             :                                 }
     304             :                         }
     305             :                         break;
     306           0 :                 case 'A': {
     307           0 :                                 struct p9_stat_dotl *stbuf =
     308             :                                     va_arg(ap, struct p9_stat_dotl *);
     309             : 
     310           0 :                                 memset(stbuf, 0, sizeof(struct p9_stat_dotl));
     311           0 :                                 errcode =
     312           0 :                                     p9pdu_readf(pdu, proto_version,
     313             :                                         "qQdugqqqqqqqqqqqqqqq",
     314             :                                         &stbuf->st_result_mask,
     315             :                                         &stbuf->qid,
     316             :                                         &stbuf->st_mode,
     317             :                                         &stbuf->st_uid, &stbuf->st_gid,
     318             :                                         &stbuf->st_nlink,
     319             :                                         &stbuf->st_rdev, &stbuf->st_size,
     320             :                                         &stbuf->st_blksize, &stbuf->st_blocks,
     321             :                                         &stbuf->st_atime_sec,
     322             :                                         &stbuf->st_atime_nsec,
     323             :                                         &stbuf->st_mtime_sec,
     324             :                                         &stbuf->st_mtime_nsec,
     325             :                                         &stbuf->st_ctime_sec,
     326             :                                         &stbuf->st_ctime_nsec,
     327             :                                         &stbuf->st_btime_sec,
     328             :                                         &stbuf->st_btime_nsec,
     329             :                                         &stbuf->st_gen,
     330             :                                         &stbuf->st_data_version);
     331             :                         }
     332           0 :                         break;
     333           0 :                 case '?':
     334           0 :                         if ((proto_version != p9_proto_2000u) &&
     335             :                                 (proto_version != p9_proto_2000L))
     336             :                                 return 0;
     337             :                         break;
     338           0 :                 default:
     339           0 :                         BUG();
     340           0 :                         break;
     341             :                 }
     342             : 
     343           0 :                 if (errcode)
     344             :                         break;
     345             :         }
     346             : 
     347             :         return errcode;
     348             : }
     349             : 
     350             : int
     351           0 : p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
     352             :         va_list ap)
     353             : {
     354           0 :         const char *ptr;
     355           0 :         int errcode = 0;
     356             : 
     357           0 :         for (ptr = fmt; *ptr; ptr++) {
     358           0 :                 switch (*ptr) {
     359           0 :                 case 'b':{
     360           0 :                                 int8_t val = va_arg(ap, int);
     361           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     362           0 :                                         errcode = -EFAULT;
     363             :                         }
     364           0 :                         break;
     365           0 :                 case 'w':{
     366           0 :                                 __le16 val = cpu_to_le16(va_arg(ap, int));
     367           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     368           0 :                                         errcode = -EFAULT;
     369             :                         }
     370           0 :                         break;
     371           0 :                 case 'd':{
     372           0 :                                 __le32 val = cpu_to_le32(va_arg(ap, int32_t));
     373           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     374           0 :                                         errcode = -EFAULT;
     375             :                         }
     376           0 :                         break;
     377           0 :                 case 'q':{
     378           0 :                                 __le64 val = cpu_to_le64(va_arg(ap, int64_t));
     379           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     380           0 :                                         errcode = -EFAULT;
     381             :                         }
     382           0 :                         break;
     383           0 :                 case 's':{
     384           0 :                                 const char *sptr = va_arg(ap, const char *);
     385           0 :                                 uint16_t len = 0;
     386           0 :                                 if (sptr)
     387           0 :                                         len = min_t(size_t, strlen(sptr),
     388             :                                                                 USHRT_MAX);
     389             : 
     390           0 :                                 errcode = p9pdu_writef(pdu, proto_version,
     391             :                                                                 "w", len);
     392           0 :                                 if (!errcode && pdu_write(pdu, sptr, len))
     393             :                                         errcode = -EFAULT;
     394             :                         }
     395             :                         break;
     396           0 :                 case 'u': {
     397           0 :                                 kuid_t uid = va_arg(ap, kuid_t);
     398           0 :                                 __le32 val = cpu_to_le32(
     399             :                                                 from_kuid(&init_user_ns, uid));
     400           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     401           0 :                                         errcode = -EFAULT;
     402           0 :                         } break;
     403           0 :                 case 'g': {
     404           0 :                                 kgid_t gid = va_arg(ap, kgid_t);
     405           0 :                                 __le32 val = cpu_to_le32(
     406             :                                                 from_kgid(&init_user_ns, gid));
     407           0 :                                 if (pdu_write(pdu, &val, sizeof(val)))
     408           0 :                                         errcode = -EFAULT;
     409           0 :                         } break;
     410           0 :                 case 'Q':{
     411           0 :                                 const struct p9_qid *qid =
     412             :                                     va_arg(ap, const struct p9_qid *);
     413           0 :                                 errcode =
     414           0 :                                     p9pdu_writef(pdu, proto_version, "bdq",
     415           0 :                                                  qid->type, qid->version,
     416             :                                                  qid->path);
     417           0 :                         } break;
     418           0 :                 case 'S':{
     419           0 :                                 const struct p9_wstat *stbuf =
     420             :                                     va_arg(ap, const struct p9_wstat *);
     421           0 :                                 errcode =
     422           0 :                                     p9pdu_writef(pdu, proto_version,
     423             :                                                  "wwdQdddqssss?sugu",
     424           0 :                                                  stbuf->size, stbuf->type,
     425             :                                                  stbuf->dev, &stbuf->qid,
     426             :                                                  stbuf->mode, stbuf->atime,
     427             :                                                  stbuf->mtime, stbuf->length,
     428             :                                                  stbuf->name, stbuf->uid,
     429             :                                                  stbuf->gid, stbuf->muid,
     430             :                                                  stbuf->extension, stbuf->n_uid,
     431             :                                                  stbuf->n_gid, stbuf->n_muid);
     432           0 :                         } break;
     433           0 :                 case 'V':{
     434           0 :                                 uint32_t count = va_arg(ap, uint32_t);
     435           0 :                                 struct iov_iter *from =
     436             :                                                 va_arg(ap, struct iov_iter *);
     437           0 :                                 errcode = p9pdu_writef(pdu, proto_version, "d",
     438             :                                                                         count);
     439           0 :                                 if (!errcode && pdu_write_u(pdu, from, count))
     440             :                                         errcode = -EFAULT;
     441             :                         }
     442             :                         break;
     443           0 :                 case 'T':{
     444           0 :                                 uint16_t nwname = va_arg(ap, int);
     445           0 :                                 const char **wnames = va_arg(ap, const char **);
     446             : 
     447           0 :                                 errcode = p9pdu_writef(pdu, proto_version, "w",
     448             :                                                                         nwname);
     449           0 :                                 if (!errcode) {
     450             :                                         int i;
     451             : 
     452           0 :                                         for (i = 0; i < nwname; i++) {
     453           0 :                                                 errcode =
     454           0 :                                                     p9pdu_writef(pdu,
     455             :                                                                 proto_version,
     456             :                                                                  "s",
     457           0 :                                                                  wnames[i]);
     458           0 :                                                 if (errcode)
     459             :                                                         break;
     460             :                                         }
     461             :                                 }
     462             :                         }
     463             :                         break;
     464           0 :                 case 'R':{
     465           0 :                                 uint16_t nwqid = va_arg(ap, int);
     466           0 :                                 struct p9_qid *wqids =
     467             :                                     va_arg(ap, struct p9_qid *);
     468             : 
     469           0 :                                 errcode = p9pdu_writef(pdu, proto_version, "w",
     470             :                                                                         nwqid);
     471           0 :                                 if (!errcode) {
     472             :                                         int i;
     473             : 
     474           0 :                                         for (i = 0; i < nwqid; i++) {
     475           0 :                                                 errcode =
     476           0 :                                                     p9pdu_writef(pdu,
     477             :                                                                 proto_version,
     478             :                                                                  "Q",
     479           0 :                                                                  &wqids[i]);
     480           0 :                                                 if (errcode)
     481             :                                                         break;
     482             :                                         }
     483             :                                 }
     484             :                         }
     485             :                         break;
     486           0 :                 case 'I':{
     487           0 :                                 struct p9_iattr_dotl *p9attr = va_arg(ap,
     488             :                                                         struct p9_iattr_dotl *);
     489             : 
     490           0 :                                 errcode = p9pdu_writef(pdu, proto_version,
     491             :                                                         "ddugqqqqq",
     492             :                                                         p9attr->valid,
     493             :                                                         p9attr->mode,
     494             :                                                         p9attr->uid,
     495             :                                                         p9attr->gid,
     496             :                                                         p9attr->size,
     497             :                                                         p9attr->atime_sec,
     498             :                                                         p9attr->atime_nsec,
     499             :                                                         p9attr->mtime_sec,
     500             :                                                         p9attr->mtime_nsec);
     501             :                         }
     502           0 :                         break;
     503           0 :                 case '?':
     504           0 :                         if ((proto_version != p9_proto_2000u) &&
     505             :                                 (proto_version != p9_proto_2000L))
     506             :                                 return 0;
     507             :                         break;
     508           0 :                 default:
     509           0 :                         BUG();
     510           0 :                         break;
     511             :                 }
     512             : 
     513           0 :                 if (errcode)
     514             :                         break;
     515             :         }
     516             : 
     517             :         return errcode;
     518             : }
     519             : 
     520           0 : int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
     521             : {
     522           0 :         va_list ap;
     523           0 :         int ret;
     524             : 
     525           0 :         va_start(ap, fmt);
     526           0 :         ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
     527           0 :         va_end(ap);
     528             : 
     529           0 :         return ret;
     530             : }
     531             : 
     532             : static int
     533           0 : p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
     534             : {
     535           0 :         va_list ap;
     536           0 :         int ret;
     537             : 
     538           0 :         va_start(ap, fmt);
     539           0 :         ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
     540           0 :         va_end(ap);
     541             : 
     542           0 :         return ret;
     543             : }
     544             : 
     545           0 : int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
     546             : {
     547           0 :         struct p9_fcall fake_pdu;
     548           0 :         int ret;
     549             : 
     550           0 :         fake_pdu.size = len;
     551           0 :         fake_pdu.capacity = len;
     552           0 :         fake_pdu.sdata = buf;
     553           0 :         fake_pdu.offset = 0;
     554             : 
     555           0 :         ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
     556           0 :         if (ret) {
     557           0 :                 p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
     558           0 :                 trace_9p_protocol_dump(clnt, &fake_pdu);
     559           0 :                 return ret;
     560             :         }
     561             : 
     562           0 :         return fake_pdu.offset;
     563             : }
     564             : EXPORT_SYMBOL(p9stat_read);
     565             : 
     566           0 : int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
     567             : {
     568           0 :         pdu->id = type;
     569           0 :         return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
     570             : }
     571             : 
     572           0 : int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
     573             : {
     574           0 :         int size = pdu->size;
     575           0 :         int err;
     576             : 
     577           0 :         pdu->size = 0;
     578           0 :         err = p9pdu_writef(pdu, 0, "d", size);
     579           0 :         pdu->size = size;
     580             : 
     581           0 :         trace_9p_protocol_dump(clnt, pdu);
     582           0 :         p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
     583             :                  pdu->size, pdu->id, pdu->tag);
     584             : 
     585           0 :         return err;
     586             : }
     587             : 
     588           0 : void p9pdu_reset(struct p9_fcall *pdu)
     589             : {
     590           0 :         pdu->offset = 0;
     591           0 :         pdu->size = 0;
     592           0 : }
     593             : 
     594           0 : int p9dirent_read(struct p9_client *clnt, char *buf, int len,
     595             :                   struct p9_dirent *dirent)
     596             : {
     597           0 :         struct p9_fcall fake_pdu;
     598           0 :         int ret;
     599           0 :         char *nameptr;
     600             : 
     601           0 :         fake_pdu.size = len;
     602           0 :         fake_pdu.capacity = len;
     603           0 :         fake_pdu.sdata = buf;
     604           0 :         fake_pdu.offset = 0;
     605             : 
     606           0 :         ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
     607             :                           &dirent->d_off, &dirent->d_type, &nameptr);
     608           0 :         if (ret) {
     609           0 :                 p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
     610           0 :                 trace_9p_protocol_dump(clnt, &fake_pdu);
     611           0 :                 return ret;
     612             :         }
     613             : 
     614           0 :         ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
     615           0 :         if (ret < 0) {
     616           0 :                 p9_debug(P9_DEBUG_ERROR,
     617             :                          "On the wire dirent name too long: %s\n",
     618             :                          nameptr);
     619           0 :                 kfree(nameptr);
     620           0 :                 return ret;
     621             :         }
     622           0 :         kfree(nameptr);
     623             : 
     624           0 :         return fake_pdu.offset;
     625             : }
     626             : EXPORT_SYMBOL(p9dirent_read);

Generated by: LCOV version 1.14