On Sun, 30 May 2010 09:40:38 -0700, "Venkateswararao Jujjuri (JV)" <jv...@linux.vnet.ibm.com> wrote: > Create a link. > > SYNOPSIS > > size[4] Tlink tag[2] dfid[4] oldpath[s] newpath[s] > > size[4] Rlink tag[2] > > DESCRIPTION > > Create a link 'newpath' in directory pointed by dfid linking to oldpath. > > Signed-off-by: Venkateswararao Jujjuri <jv...@linux.vnet.ibm.com> > --- > hw/file-op-9p.h | 2 +- > hw/virtio-9p-debug.c | 9 +++++++++ > hw/virtio-9p-local.c | 2 +- > hw/virtio-9p.c | 40 ++++++++++++++++++++++++++++++++-------- > hw/virtio-9p.h | 2 ++ > 5 files changed, 45 insertions(+), 10 deletions(-) > > diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h > index b3a320c..6744d69 100644 > --- a/hw/file-op-9p.h > +++ b/hw/file-op-9p.h > @@ -55,7 +55,7 @@ typedef struct FileOperations > int (*utime)(FsContext *, const char *, const struct utimbuf *); > int (*remove)(FsContext *, const char *); > int (*symlink)(FsContext *, const char *, const char *, FsCred *); > - int (*link)(FsContext *, const char *, const char *, FsCred *); > + int (*link)(FsContext *, const char *, const char *); > int (*setuid)(FsContext *, uid_t); > int (*close)(FsContext *, int); > int (*closedir)(FsContext *, DIR *); > diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c > index a82b771..a870b97 100644 > --- a/hw/virtio-9p-debug.c > +++ b/hw/virtio-9p-debug.c > @@ -463,6 +463,15 @@ void pprint_pdu(V9fsPDU *pdu) > case P9_RCLUNK: > fprintf(llogfile, "RCLUNK: ("); > break; > + case P9_TLINK: > + fprintf(llogfile, "TLINK: ("); > + pprint_int32(pdu, 0, &offset, "fid"); > + pprint_str(pdu, 0, &offset, ", name"); > + pprint_str(pdu, 0, &offset, ", linkname"); > + break; > + case P9_RLINK: > + fprintf(llogfile, "RLINK: ("); > + break; > case P9_TREMOVE: > fprintf(llogfile, "TREMOVE: ("); > pprint_int32(pdu, 0, &offset, "fid"); > diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c > index c5678ae..fa8d05c 100644 > --- a/hw/virtio-9p-local.c > +++ b/hw/virtio-9p-local.c > @@ -375,7 +375,7 @@ err_end: > } > > static int local_link(FsContext *fs_ctx, const char *oldpath, > - const char *newpath, FsCred *credp) > + const char *newpath) > { > char *tmp = qemu_strdup(rpath(fs_ctx, oldpath)); > int err;
I guess it would be good to make sure local_link use linkat with flags = 0 to ensure that we won't follow symlinks. But that can be seperate patch. > diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c > index 097dce8..d36d206 100644 > --- a/hw/virtio-9p.c > +++ b/hw/virtio-9p.c > @@ -212,14 +212,9 @@ static int v9fs_do_symlink(V9fsState *s, V9fsCreateState > *vs) > &cred); > } > > -static int v9fs_do_link(V9fsState *s, V9fsFidState *nfidp, V9fsCreateState > *vs) > +static int v9fs_do_link(V9fsState *s, char *oldpath, char *fullname) > { > - FsCred cred; > - cred_init(&cred); > - cred.fc_uid = nfidp->uid; > - cred.fc_mode = vs->perm & 0777; > - > - return s->ops->link(&s->ctx, nfidp->path.data, vs->fullname.data, &cred); > + return s->ops->link(&s->ctx, oldpath, fullname); > } > > static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size) > @@ -1919,7 +1914,7 @@ static void v9fs_create_post_lstat(V9fsState *s, > V9fsCreateState *vs, int err) > err = -errno; > v9fs_post_create(s, vs, err); > } > - err = v9fs_do_link(s, nfidp, vs); > + err = v9fs_do_link(s, nfidp->path.data, vs->fullname.data); > v9fs_create_post_perms(s, vs, err); > } else if (vs->perm & P9_STAT_MODE_DEVICE) { > char ctype; > @@ -1999,6 +1994,34 @@ out: > qemu_free(vs); > } > > +static void v9fs_link(V9fsState *s, V9fsPDU *pdu) > +{ > + int32_t dfid; > + V9fsFidState *dfidp; > + V9fsString name, fullname, oldname; > + size_t offset = 7; > + int err = 0; > + > + v9fs_string_init(&fullname); > + > + pdu_unmarshal(pdu, offset, "dss", &dfid, &oldname, &name); > + > + dfidp = lookup_fid(s, dfid); > + if (dfidp == NULL) { > + err = -errno; > + goto out; > + } > + > + v9fs_string_sprintf(&fullname, "%s/%s", dfidp->path.data, name.data); > + err = v9fs_do_link(s, oldname.data, fullname.data); > + v9fs_string_free(&fullname); > + > +out: > + v9fs_string_free(&name); > + v9fs_string_free(&oldname); > + complete_pdu(s, pdu, err); > +} > + > static void v9fs_flush(V9fsState *s, V9fsPDU *pdu) > { > /* A nop call with no return */ > @@ -2354,6 +2377,7 @@ static pdu_handler_t *pdu_handlers[] = { > [P9_TAUTH] = v9fs_auth, > #endif > [P9_TFLUSH] = v9fs_flush, > + [P9_TLINK] = v9fs_link, > [P9_TCREATE] = v9fs_create, > [P9_TWRITE] = v9fs_write, > [P9_TWSTAT] = v9fs_wstat, > diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h > index 9773659..6b3d4a4 100644 > --- a/hw/virtio-9p.h > +++ b/hw/virtio-9p.h > @@ -17,6 +17,8 @@ enum { > P9_RSTATFS, > P9_TREADDIR = 40, > P9_RREADDIR, > + P9_TLINK = 70, > + P9_RLINK, > P9_TVERSION = 100, > P9_RVERSION, > P9_TAUTH = 102, > -- > 1.6.5.2 -aneesh