qemu-virtio-9p: Implement TREADLINK operation for 9p2000.L

Synopsis

        size[4] TReadlink tag[2] fid[4]
        size[4] RReadlink tag[2] target[s]

Description
        Readlink is used to return the contents of the symoblic link
        referred by fid. Contents of symboic link is returned as a
        response.

        target[s] - Contents of the symbolic link referred by fid.

Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
master
M. Mohan Kumar 2010-09-14 15:08:25 +05:30 committed by Anthony Liguori
parent b41e95d348
commit df0973a465
3 changed files with 60 additions and 0 deletions

View File

@ -502,6 +502,14 @@ void pprint_pdu(V9fsPDU *pdu)
fprintf(llogfile, "RMKNOD: )");
pprint_qid(pdu, 0, &offset, "qid");
break;
case P9_TREADLINK:
fprintf(llogfile, "TREADLINK: (");
pprint_int32(pdu, 0, &offset, "fid");
break;
case P9_RREADLINK:
fprintf(llogfile, "RREADLINK: (");
pprint_str(pdu, 0, &offset, "target");
break;
case P9_TREAD:
fprintf(llogfile, "TREAD: (");
pprint_int32(pdu, 0, &offset, "fid");

View File

@ -3520,6 +3520,49 @@ out:
qemu_free(vs);
}
static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs,
int err)
{
if (err < 0) {
err = -errno;
goto out;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "s", &vs->target);
err = vs->offset;
out:
complete_pdu(s, vs->pdu, err);
v9fs_string_free(&vs->target);
qemu_free(vs);
}
static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsReadLinkState *vs;
int err = 0;
V9fsFidState *fidp;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
fidp = lookup_fid(s, fid);
if (fidp == NULL) {
err = -ENOENT;
goto out;
}
v9fs_string_init(&vs->target);
err = v9fs_do_readlink(s, &fidp->path, &vs->target);
v9fs_readlink_post_readlink(s, vs, err);
return;
out:
complete_pdu(s, vs->pdu, err);
qemu_free(vs);
}
typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
static pdu_handler_t *pdu_handlers[] = {
@ -3533,6 +3576,7 @@ static pdu_handler_t *pdu_handlers[] = {
[P9_TRENAME] = v9fs_rename,
[P9_TLOCK] = v9fs_lock,
[P9_TGETLOCK] = v9fs_getlock,
[P9_TREADLINK] = v9fs_readlink,
[P9_TMKDIR] = v9fs_mkdir,
[P9_TVERSION] = v9fs_version,
[P9_TLOPEN] = v9fs_open,

View File

@ -27,6 +27,8 @@ enum {
P9_RMKNOD,
P9_TRENAME = 20,
P9_RRENAME,
P9_TREADLINK = 22,
P9_RREADLINK,
P9_TGETATTR = 24,
P9_RGETATTR,
P9_TSETATTR = 26,
@ -486,6 +488,12 @@ typedef struct V9fsGetlockState
V9fsGetlock *glock;
} V9fsGetlockState;
typedef struct V9fsReadLinkState
{
V9fsPDU *pdu;
size_t offset;
V9fsString target;
} V9fsReadLinkState;
extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
size_t offset, size_t size, int pack);