1 #include "kvm/virtio-pci-dev.h"
2 #include "kvm/ioport.h"
4 #include "kvm/threadpool.h"
6 #include "kvm/virtio-9p.h"
7 #include "kvm/guest_compat.h"
8 #include "kvm/builtin-setup.h"
19 #include <linux/virtio_ring.h>
20 #include <linux/virtio_9p.h>
21 #include <net/9p/9p.h>
23 static LIST_HEAD(devs);
24 static int compat_id = -1;
26 static int insert_new_fid(struct p9_dev *dev, struct p9_fid *fid);
27 static struct p9_fid *find_or_create_fid(struct p9_dev *dev, u32 fid)
29 struct rb_node *node = dev->fids.rb_node;
30 struct p9_fid *pfid = NULL;
33 struct p9_fid *cur = rb_entry(node, struct p9_fid, node);
37 } else if (fid > cur->fid) {
38 node = node->rb_right;
44 pfid = calloc(sizeof(*pfid), 1);
49 strcpy(pfid->abs_path, dev->root_dir);
50 pfid->path = pfid->abs_path + strlen(dev->root_dir);
52 insert_new_fid(dev, pfid);
57 static int insert_new_fid(struct p9_dev *dev, struct p9_fid *fid)
59 struct rb_node **node = &(dev->fids.rb_node), *parent = NULL;
62 int result = fid->fid - rb_entry(*node, struct p9_fid, node)->fid;
66 node = &((*node)->rb_left);
68 node = &((*node)->rb_right);
73 rb_link_node(&fid->node, parent, node);
74 rb_insert_color(&fid->node, &dev->fids);
78 static struct p9_fid *get_fid(struct p9_dev *p9dev, int fid)
82 new = find_or_create_fid(p9dev, fid);
87 /* Warning: Immediately use value returned from this function */
88 static const char *rel_to_abs(struct p9_dev *p9dev,
89 const char *path, char *abs_path)
91 sprintf(abs_path, "%s/%s", p9dev->root_dir, path);
96 static void stat2qid(struct stat *st, struct p9_qid *qid)
98 *qid = (struct p9_qid) {
100 .version = st->st_mtime,
103 if (S_ISDIR(st->st_mode))
104 qid->type |= P9_QTDIR;
107 static void close_fid(struct p9_dev *p9dev, u32 fid)
109 struct p9_fid *pfid = get_fid(p9dev, fid);
117 rb_erase(&pfid->node, &p9dev->fids);
121 static void virtio_p9_set_reply_header(struct p9_pdu *pdu, u32 size)
126 pdu->read_offset = sizeof(u32);
127 virtio_p9_pdu_readf(pdu, "bw", &cmd, &tag);
128 pdu->write_offset = 0;
129 /* cmd + 1 is the reply message */
130 virtio_p9_pdu_writef(pdu, "dbw", size, cmd + 1, tag);
133 static u16 virtio_p9_update_iov_cnt(struct iovec iov[], u32 count, int iov_cnt)
137 for (i = 0; (i < iov_cnt) && (total < count); i++) {
138 if (total + iov[i].iov_len > count) {
139 /* we don't need this iov fully */
140 iov[i].iov_len -= ((total + iov[i].iov_len) - count);
144 total += iov[i].iov_len;
149 static void virtio_p9_error_reply(struct p9_dev *p9dev,
150 struct p9_pdu *pdu, int err, u32 *outlen)
154 pdu->write_offset = VIRTIO_9P_HDR_LEN;
155 virtio_p9_pdu_writef(pdu, "d", err);
156 *outlen = pdu->write_offset;
158 /* read the tag from input */
159 pdu->read_offset = sizeof(u32) + sizeof(u8);
160 virtio_p9_pdu_readf(pdu, "w", &tag);
162 /* Update the header */
163 pdu->write_offset = 0;
164 virtio_p9_pdu_writef(pdu, "dbw", *outlen, P9_RLERROR, tag);
167 static void virtio_p9_version(struct p9_dev *p9dev,
168 struct p9_pdu *pdu, u32 *outlen)
172 virtio_p9_pdu_readf(pdu, "ds", &msize, &version);
174 * reply with the same msize the client sent us
175 * Error out if the request is not for 9P2000.L
177 if (!strcmp(version, VIRTIO_9P_VERSION_DOTL))
178 virtio_p9_pdu_writef(pdu, "ds", msize, version);
180 virtio_p9_pdu_writef(pdu, "ds", msize, "unknown");
182 *outlen = pdu->write_offset;
183 virtio_p9_set_reply_header(pdu, *outlen);
188 static void virtio_p9_clunk(struct p9_dev *p9dev,
189 struct p9_pdu *pdu, u32 *outlen)
193 virtio_p9_pdu_readf(pdu, "d", &fid);
194 close_fid(p9dev, fid);
196 *outlen = pdu->write_offset;
197 virtio_p9_set_reply_header(pdu, *outlen);
202 * FIXME!! Need to map to protocol independent value. Upstream
203 * 9p also have the same BUG
205 static int virtio_p9_openflags(int flags)
207 flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT | O_DIRECT);
212 static bool is_dir(struct p9_fid *fid)
216 stat(fid->abs_path, &st);
218 return S_ISDIR(st.st_mode);
221 static void virtio_p9_open(struct p9_dev *p9dev,
222 struct p9_pdu *pdu, u32 *outlen)
227 struct p9_fid *new_fid;
230 virtio_p9_pdu_readf(pdu, "dd", &fid, &flags);
231 new_fid = get_fid(p9dev, fid);
233 if (lstat(new_fid->abs_path, &st) < 0)
238 if (is_dir(new_fid)) {
239 new_fid->dir = opendir(new_fid->abs_path);
243 new_fid->fd = open(new_fid->abs_path,
244 virtio_p9_openflags(flags));
248 /* FIXME!! need ot send proper iounit */
249 virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
251 *outlen = pdu->write_offset;
252 virtio_p9_set_reply_header(pdu, *outlen);
255 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
259 static void virtio_p9_create(struct p9_dev *p9dev,
260 struct p9_pdu *pdu, u32 *outlen)
267 char full_path[PATH_MAX];
268 u32 dfid_val, flags, mode, gid;
270 virtio_p9_pdu_readf(pdu, "dsddd", &dfid_val,
271 &name, &flags, &mode, &gid);
272 dfid = get_fid(p9dev, dfid_val);
274 flags = virtio_p9_openflags(flags);
276 sprintf(full_path, "%s/%s", dfid->abs_path, name);
277 fd = open(full_path, flags | O_CREAT, mode);
282 if (lstat(full_path, &st) < 0)
285 ret = chmod(full_path, mode & 0777);
289 sprintf(dfid->path, "%s/%s", dfid->path, name);
291 virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
292 *outlen = pdu->write_offset;
293 virtio_p9_set_reply_header(pdu, *outlen);
298 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
302 static void virtio_p9_mkdir(struct p9_dev *p9dev,
303 struct p9_pdu *pdu, u32 *outlen)
310 char full_path[PATH_MAX];
311 u32 dfid_val, mode, gid;
313 virtio_p9_pdu_readf(pdu, "dsdd", &dfid_val,
315 dfid = get_fid(p9dev, dfid_val);
317 sprintf(full_path, "%s/%s", dfid->abs_path, name);
318 ret = mkdir(full_path, mode);
322 if (lstat(full_path, &st) < 0)
325 ret = chmod(full_path, mode & 0777);
330 virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
331 *outlen = pdu->write_offset;
332 virtio_p9_set_reply_header(pdu, *outlen);
337 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
341 static void virtio_p9_walk(struct p9_dev *p9dev,
342 struct p9_pdu *pdu, u32 *outlen)
348 struct p9_fid *new_fid, *old_fid;
349 u32 fid_val, newfid_val;
352 virtio_p9_pdu_readf(pdu, "ddw", &fid_val, &newfid_val, &nwname);
353 new_fid = get_fid(p9dev, newfid_val);
357 struct p9_fid *fid = get_fid(p9dev, fid_val);
359 strcpy(new_fid->path, fid->path);
360 /* skip the space for count */
361 pdu->write_offset += sizeof(u16);
362 for (i = 0; i < nwname; i++) {
364 char tmp[PATH_MAX] = {0};
365 char full_path[PATH_MAX];
368 virtio_p9_pdu_readf(pdu, "s", &str);
370 /* Format the new path we're 'walk'ing into */
371 sprintf(tmp, "%s/%s", new_fid->path, str);
375 if (lstat(rel_to_abs(p9dev, tmp, full_path), &st) < 0)
378 stat2qid(&st, &wqid);
379 strcpy(new_fid->path, tmp);
380 new_fid->uid = fid->uid;
382 virtio_p9_pdu_writef(pdu, "Q", &wqid);
386 * update write_offset so our outlen get correct value
388 pdu->write_offset += sizeof(u16);
389 old_fid = get_fid(p9dev, fid_val);
390 strcpy(new_fid->path, old_fid->path);
391 new_fid->uid = old_fid->uid;
393 *outlen = pdu->write_offset;
394 pdu->write_offset = VIRTIO_9P_HDR_LEN;
395 virtio_p9_pdu_writef(pdu, "d", nwqid);
396 virtio_p9_set_reply_header(pdu, *outlen);
399 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
403 static void virtio_p9_attach(struct p9_dev *p9dev,
404 struct p9_pdu *pdu, u32 *outlen)
411 u32 fid_val, afid, uid;
413 virtio_p9_pdu_readf(pdu, "ddssd", &fid_val, &afid,
414 &uname, &aname, &uid);
419 if (lstat(p9dev->root_dir, &st) < 0)
424 fid = get_fid(p9dev, fid_val);
426 strcpy(fid->path, "/");
428 virtio_p9_pdu_writef(pdu, "Q", &qid);
429 *outlen = pdu->write_offset;
430 virtio_p9_set_reply_header(pdu, *outlen);
433 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
437 static void virtio_p9_fill_stat(struct p9_dev *p9dev,
438 struct stat *st, struct p9_stat_dotl *statl)
440 memset(statl, 0, sizeof(*statl));
441 statl->st_mode = st->st_mode;
442 statl->st_nlink = st->st_nlink;
443 statl->st_uid = st->st_uid;
444 statl->st_gid = st->st_gid;
445 statl->st_rdev = st->st_rdev;
446 statl->st_size = st->st_size;
447 statl->st_blksize = st->st_blksize;
448 statl->st_blocks = st->st_blocks;
449 statl->st_atime_sec = st->st_atime;
450 statl->st_atime_nsec = st->st_atim.tv_nsec;
451 statl->st_mtime_sec = st->st_mtime;
452 statl->st_mtime_nsec = st->st_mtim.tv_nsec;
453 statl->st_ctime_sec = st->st_ctime;
454 statl->st_ctime_nsec = st->st_ctim.tv_nsec;
455 /* Currently we only support BASIC fields in stat */
456 statl->st_result_mask = P9_STATS_BASIC;
457 stat2qid(st, &statl->qid);
460 static void virtio_p9_read(struct p9_dev *p9dev,
461 struct p9_pdu *pdu, u32 *outlen)
473 virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
474 fid = get_fid(p9dev, fid_val);
476 iov_base = pdu->in_iov[0].iov_base;
477 iov_len = pdu->in_iov[0].iov_len;
478 iov_cnt = pdu->in_iov_cnt;
479 pdu->in_iov[0].iov_base += VIRTIO_9P_HDR_LEN + sizeof(u32);
480 pdu->in_iov[0].iov_len -= VIRTIO_9P_HDR_LEN + sizeof(u32);
481 pdu->in_iov_cnt = virtio_p9_update_iov_cnt(pdu->in_iov,
484 rcount = preadv(fid->fd, pdu->in_iov,
485 pdu->in_iov_cnt, offset);
489 * Update the iov_base back, so that rest of
490 * pdu_writef works correctly.
492 pdu->in_iov[0].iov_base = iov_base;
493 pdu->in_iov[0].iov_len = iov_len;
494 pdu->in_iov_cnt = iov_cnt;
496 pdu->write_offset = VIRTIO_9P_HDR_LEN;
497 virtio_p9_pdu_writef(pdu, "d", rcount);
498 *outlen = pdu->write_offset + rcount;
499 virtio_p9_set_reply_header(pdu, *outlen);
503 static int virtio_p9_dentry_size(struct dirent *dent)
506 * Size of each dirent:
507 * qid(13) + offset(8) + type(1) + name_len(2) + name
509 return 24 + strlen(dent->d_name);
512 static void virtio_p9_readdir(struct p9_dev *p9dev,
513 struct p9_pdu *pdu, u32 *outlen)
520 char full_path[PATH_MAX];
521 u64 offset, old_offset;
524 virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
525 fid = get_fid(p9dev, fid_val);
532 /* Move the offset specified */
533 seekdir(fid->dir, offset);
536 /* If reading a dir, fill the buffer with p9_stat entries */
537 dent = readdir(fid->dir);
539 /* Skip the space for writing count */
540 pdu->write_offset += sizeof(u32);
545 if ((rcount + virtio_p9_dentry_size(dent)) > count) {
546 /* seek to the previous offset and return */
547 seekdir(fid->dir, old_offset);
550 old_offset = dent->d_off;
551 lstat(rel_to_abs(p9dev, dent->d_name, full_path), &st);
553 read = pdu->write_offset;
554 virtio_p9_pdu_writef(pdu, "Qqbs", &qid, dent->d_off,
555 dent->d_type, dent->d_name);
556 rcount += pdu->write_offset - read;
557 dent = readdir(fid->dir);
560 pdu->write_offset = VIRTIO_9P_HDR_LEN;
561 virtio_p9_pdu_writef(pdu, "d", rcount);
562 *outlen = pdu->write_offset + rcount;
563 virtio_p9_set_reply_header(pdu, *outlen);
566 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
571 static void virtio_p9_getattr(struct p9_dev *p9dev,
572 struct p9_pdu *pdu, u32 *outlen)
578 struct p9_stat_dotl statl;
580 virtio_p9_pdu_readf(pdu, "dq", &fid_val, &request_mask);
581 fid = get_fid(p9dev, fid_val);
582 if (lstat(fid->abs_path, &st) < 0)
585 virtio_p9_fill_stat(p9dev, &st, &statl);
586 virtio_p9_pdu_writef(pdu, "A", &statl);
587 *outlen = pdu->write_offset;
588 virtio_p9_set_reply_header(pdu, *outlen);
591 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
595 /* FIXME!! from linux/fs.h */
597 * Attribute flags. These should be or-ed together to figure out what
600 #define ATTR_MODE (1 << 0)
601 #define ATTR_UID (1 << 1)
602 #define ATTR_GID (1 << 2)
603 #define ATTR_SIZE (1 << 3)
604 #define ATTR_ATIME (1 << 4)
605 #define ATTR_MTIME (1 << 5)
606 #define ATTR_CTIME (1 << 6)
607 #define ATTR_ATIME_SET (1 << 7)
608 #define ATTR_MTIME_SET (1 << 8)
609 #define ATTR_FORCE (1 << 9) /* Not a change, but a change it */
610 #define ATTR_ATTR_FLAG (1 << 10)
611 #define ATTR_KILL_SUID (1 << 11)
612 #define ATTR_KILL_SGID (1 << 12)
613 #define ATTR_FILE (1 << 13)
614 #define ATTR_KILL_PRIV (1 << 14)
615 #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
616 #define ATTR_TIMES_SET (1 << 16)
618 #define ATTR_MASK 127
620 static void virtio_p9_setattr(struct p9_dev *p9dev,
621 struct p9_pdu *pdu, u32 *outlen)
626 struct p9_iattr_dotl p9attr;
628 virtio_p9_pdu_readf(pdu, "dI", &fid_val, &p9attr);
629 fid = get_fid(p9dev, fid_val);
631 if (p9attr.valid & ATTR_MODE) {
632 ret = chmod(fid->abs_path, p9attr.mode);
636 if (p9attr.valid & (ATTR_ATIME | ATTR_MTIME)) {
637 struct timespec times[2];
638 if (p9attr.valid & ATTR_ATIME) {
639 if (p9attr.valid & ATTR_ATIME_SET) {
640 times[0].tv_sec = p9attr.atime_sec;
641 times[0].tv_nsec = p9attr.atime_nsec;
643 times[0].tv_nsec = UTIME_NOW;
646 times[0].tv_nsec = UTIME_OMIT;
648 if (p9attr.valid & ATTR_MTIME) {
649 if (p9attr.valid & ATTR_MTIME_SET) {
650 times[1].tv_sec = p9attr.mtime_sec;
651 times[1].tv_nsec = p9attr.mtime_nsec;
653 times[1].tv_nsec = UTIME_NOW;
656 times[1].tv_nsec = UTIME_OMIT;
658 ret = utimensat(-1, fid->abs_path, times, AT_SYMLINK_NOFOLLOW);
663 * If the only valid entry in iattr is ctime we can call
664 * chown(-1,-1) to update the ctime of the file
666 if ((p9attr.valid & (ATTR_UID | ATTR_GID)) ||
667 ((p9attr.valid & ATTR_CTIME)
668 && !((p9attr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
669 if (!(p9attr.valid & ATTR_UID))
672 if (!(p9attr.valid & ATTR_GID))
675 ret = lchown(fid->abs_path, p9attr.uid, p9attr.gid);
679 if (p9attr.valid & (ATTR_SIZE)) {
680 ret = truncate(fid->abs_path, p9attr.size);
684 *outlen = VIRTIO_9P_HDR_LEN;
685 virtio_p9_set_reply_header(pdu, *outlen);
688 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
692 static void virtio_p9_write(struct p9_dev *p9dev,
693 struct p9_pdu *pdu, u32 *outlen)
704 /* u32 fid + u64 offset + u32 count */
705 int twrite_size = sizeof(u32) + sizeof(u64) + sizeof(u32);
707 virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
708 fid = get_fid(p9dev, fid_val);
710 iov_base = pdu->out_iov[0].iov_base;
711 iov_len = pdu->out_iov[0].iov_len;
712 iov_cnt = pdu->out_iov_cnt;
714 /* Adjust the iovec to skip the header and meta data */
715 pdu->out_iov[0].iov_base += (sizeof(struct p9_msg) + twrite_size);
716 pdu->out_iov[0].iov_len -= (sizeof(struct p9_msg) + twrite_size);
717 pdu->out_iov_cnt = virtio_p9_update_iov_cnt(pdu->out_iov, count,
719 res = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, offset);
721 * Update the iov_base back, so that rest of
722 * pdu_readf works correctly.
724 pdu->out_iov[0].iov_base = iov_base;
725 pdu->out_iov[0].iov_len = iov_len;
726 pdu->out_iov_cnt = iov_cnt;
730 virtio_p9_pdu_writef(pdu, "d", res);
731 *outlen = pdu->write_offset;
732 virtio_p9_set_reply_header(pdu, *outlen);
735 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
739 static void virtio_p9_remove(struct p9_dev *p9dev,
740 struct p9_pdu *pdu, u32 *outlen)
746 virtio_p9_pdu_readf(pdu, "d", &fid_val);
747 fid = get_fid(p9dev, fid_val);
749 ret = remove(fid->abs_path);
752 *outlen = pdu->write_offset;
753 virtio_p9_set_reply_header(pdu, *outlen);
757 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
761 static void virtio_p9_rename(struct p9_dev *p9dev,
762 struct p9_pdu *pdu, u32 *outlen)
765 u32 fid_val, new_fid_val;
766 struct p9_fid *fid, *new_fid;
767 char full_path[PATH_MAX], *new_name;
769 virtio_p9_pdu_readf(pdu, "dds", &fid_val, &new_fid_val, &new_name);
770 fid = get_fid(p9dev, fid_val);
771 new_fid = get_fid(p9dev, new_fid_val);
773 sprintf(full_path, "%s/%s", new_fid->abs_path, new_name);
774 ret = rename(fid->abs_path, full_path);
777 *outlen = pdu->write_offset;
778 virtio_p9_set_reply_header(pdu, *outlen);
782 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
786 static void virtio_p9_readlink(struct p9_dev *p9dev,
787 struct p9_pdu *pdu, u32 *outlen)
792 char target_path[PATH_MAX];
794 virtio_p9_pdu_readf(pdu, "d", &fid_val);
795 fid = get_fid(p9dev, fid_val);
797 memset(target_path, 0, PATH_MAX);
798 ret = readlink(fid->abs_path, target_path, PATH_MAX - 1);
802 virtio_p9_pdu_writef(pdu, "s", target_path);
803 *outlen = pdu->write_offset;
804 virtio_p9_set_reply_header(pdu, *outlen);
807 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
811 static void virtio_p9_statfs(struct p9_dev *p9dev,
812 struct p9_pdu *pdu, u32 *outlen)
818 struct statfs stat_buf;
820 virtio_p9_pdu_readf(pdu, "d", &fid_val);
821 fid = get_fid(p9dev, fid_val);
823 ret = statfs(fid->abs_path, &stat_buf);
826 /* FIXME!! f_blocks needs update based on client msize */
827 fsid = (unsigned int) stat_buf.f_fsid.__val[0] |
828 (unsigned long long)stat_buf.f_fsid.__val[1] << 32;
829 virtio_p9_pdu_writef(pdu, "ddqqqqqqd", stat_buf.f_type,
830 stat_buf.f_bsize, stat_buf.f_blocks,
831 stat_buf.f_bfree, stat_buf.f_bavail,
832 stat_buf.f_files, stat_buf.f_ffree,
833 fsid, stat_buf.f_namelen);
834 *outlen = pdu->write_offset;
835 virtio_p9_set_reply_header(pdu, *outlen);
838 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
842 static void virtio_p9_mknod(struct p9_dev *p9dev,
843 struct p9_pdu *pdu, u32 *outlen)
850 char full_path[PATH_MAX];
851 u32 fid_val, mode, major, minor, gid;
853 virtio_p9_pdu_readf(pdu, "dsdddd", &fid_val, &name, &mode,
854 &major, &minor, &gid);
856 dfid = get_fid(p9dev, fid_val);
857 sprintf(full_path, "%s/%s", dfid->abs_path, name);
858 ret = mknod(full_path, mode, makedev(major, minor));
862 if (lstat(full_path, &st) < 0)
865 ret = chmod(full_path, mode & 0777);
870 virtio_p9_pdu_writef(pdu, "Q", &qid);
872 *outlen = pdu->write_offset;
873 virtio_p9_set_reply_header(pdu, *outlen);
877 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
881 static void virtio_p9_fsync(struct p9_dev *p9dev,
882 struct p9_pdu *pdu, u32 *outlen)
886 u32 fid_val, datasync;
888 virtio_p9_pdu_readf(pdu, "dd", &fid_val, &datasync);
889 fid = get_fid(p9dev, fid_val);
892 ret = fdatasync(fid->fd);
894 ret = fsync(fid->fd);
897 *outlen = pdu->write_offset;
898 virtio_p9_set_reply_header(pdu, *outlen);
901 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
905 static void virtio_p9_symlink(struct p9_dev *p9dev,
906 struct p9_pdu *pdu, u32 *outlen)
913 char new_name[PATH_MAX];
914 char *old_path, *name;
916 virtio_p9_pdu_readf(pdu, "dssd", &fid_val, &name, &old_path, &gid);
918 dfid = get_fid(p9dev, fid_val);
919 sprintf(new_name, "%s/%s", dfid->abs_path, name);
920 ret = symlink(old_path, new_name);
924 if (lstat(new_name, &st) < 0)
928 virtio_p9_pdu_writef(pdu, "Q", &qid);
931 *outlen = pdu->write_offset;
932 virtio_p9_set_reply_header(pdu, *outlen);
937 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
941 static void virtio_p9_link(struct p9_dev *p9dev,
942 struct p9_pdu *pdu, u32 *outlen)
946 u32 fid_val, dfid_val;
947 struct p9_fid *dfid, *fid;
948 char full_path[PATH_MAX];
950 virtio_p9_pdu_readf(pdu, "dds", &dfid_val, &fid_val, &name);
952 dfid = get_fid(p9dev, dfid_val);
953 fid = get_fid(p9dev, fid_val);
954 sprintf(full_path, "%s/%s", dfid->abs_path, name);
955 ret = link(fid->abs_path, full_path);
959 *outlen = pdu->write_offset;
960 virtio_p9_set_reply_header(pdu, *outlen);
964 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
969 static void virtio_p9_lock(struct p9_dev *p9dev,
970 struct p9_pdu *pdu, u32 *outlen)
974 struct p9_flock flock;
976 virtio_p9_pdu_readf(pdu, "dbdqqds", &fid_val, &flock.type,
977 &flock.flags, &flock.start, &flock.length,
978 &flock.proc_id, &flock.client_id);
980 /* Just return success */
981 ret = P9_LOCK_SUCCESS;
982 virtio_p9_pdu_writef(pdu, "d", ret);
983 *outlen = pdu->write_offset;
984 virtio_p9_set_reply_header(pdu, *outlen);
985 free(flock.client_id);
989 static void virtio_p9_getlock(struct p9_dev *p9dev,
990 struct p9_pdu *pdu, u32 *outlen)
993 struct p9_getlock glock;
994 virtio_p9_pdu_readf(pdu, "dbqqds", &fid_val, &glock.type,
995 &glock.start, &glock.length, &glock.proc_id,
998 /* Just return success */
999 glock.type = F_UNLCK;
1000 virtio_p9_pdu_writef(pdu, "bqqds", glock.type,
1001 glock.start, glock.length, glock.proc_id,
1003 *outlen = pdu->write_offset;
1004 virtio_p9_set_reply_header(pdu, *outlen);
1005 free(glock.client_id);
1009 static int virtio_p9_ancestor(char *path, char *ancestor)
1011 int size = strlen(ancestor);
1012 if (!strncmp(path, ancestor, size)) {
1014 * Now check whether ancestor is a full name or
1015 * or directory component and not just part
1018 if (path[size] == '\0' || path[size] == '/')
1024 static void virtio_p9_fix_path(char *fid_path, char *old_name, char *new_name)
1026 char tmp_name[PATH_MAX];
1027 size_t rp_sz = strlen(old_name);
1029 if (rp_sz == strlen(fid_path)) {
1030 /* replace the full name */
1031 strcpy(fid_path, new_name);
1034 /* save the trailing path details */
1035 strcpy(tmp_name, fid_path + rp_sz);
1036 sprintf(fid_path, "%s%s", new_name, tmp_name);
1040 static void rename_fids(struct p9_dev *p9dev, char *old_name, char *new_name)
1042 struct rb_node *node = rb_first(&p9dev->fids);
1045 struct p9_fid *fid = rb_entry(node, struct p9_fid, node);
1047 if (fid->fid != P9_NOFID && virtio_p9_ancestor(fid->path, old_name)) {
1048 virtio_p9_fix_path(fid->path, old_name, new_name);
1050 node = rb_next(node);
1054 static void virtio_p9_renameat(struct p9_dev *p9dev,
1055 struct p9_pdu *pdu, u32 *outlen)
1058 char *old_name, *new_name;
1059 u32 old_dfid_val, new_dfid_val;
1060 struct p9_fid *old_dfid, *new_dfid;
1061 char old_full_path[PATH_MAX], new_full_path[PATH_MAX];
1064 virtio_p9_pdu_readf(pdu, "dsds", &old_dfid_val, &old_name,
1065 &new_dfid_val, &new_name);
1067 old_dfid = get_fid(p9dev, old_dfid_val);
1068 new_dfid = get_fid(p9dev, new_dfid_val);
1070 sprintf(old_full_path, "%s/%s", old_dfid->abs_path, old_name);
1071 sprintf(new_full_path, "%s/%s", new_dfid->abs_path, new_name);
1072 ret = rename(old_full_path, new_full_path);
1076 * Now fix path in other fids, if the renamed path is part of
1079 rename_fids(p9dev, old_name, new_name);
1082 *outlen = pdu->write_offset;
1083 virtio_p9_set_reply_header(pdu, *outlen);
1088 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
1092 static void virtio_p9_unlinkat(struct p9_dev *p9dev,
1093 struct p9_pdu *pdu, u32 *outlen)
1099 char full_path[PATH_MAX];
1101 virtio_p9_pdu_readf(pdu, "dsd", &fid_val, &name, &flags);
1102 fid = get_fid(p9dev, fid_val);
1104 sprintf(full_path, "%s/%s", fid->abs_path, name);
1105 ret = remove(full_path);
1109 *outlen = pdu->write_offset;
1110 virtio_p9_set_reply_header(pdu, *outlen);
1114 virtio_p9_error_reply(p9dev, pdu, errno, outlen);
1118 static void virtio_p9_flush(struct p9_dev *p9dev,
1119 struct p9_pdu *pdu, u32 *outlen)
1123 virtio_p9_pdu_readf(pdu, "ww", &tag, &oldtag);
1124 virtio_p9_pdu_writef(pdu, "w", tag);
1125 *outlen = pdu->write_offset;
1126 virtio_p9_set_reply_header(pdu, *outlen);
1131 static void virtio_p9_eopnotsupp(struct p9_dev *p9dev,
1132 struct p9_pdu *pdu, u32 *outlen)
1134 return virtio_p9_error_reply(p9dev, pdu, EOPNOTSUPP, outlen);
1137 typedef void p9_handler(struct p9_dev *p9dev,
1138 struct p9_pdu *pdu, u32 *outlen);
1140 /* FIXME should be removed when merging with latest linus tree */
1141 #define P9_TRENAMEAT 74
1142 #define P9_TUNLINKAT 76
1144 static p9_handler *virtio_9p_dotl_handler [] = {
1145 [P9_TREADDIR] = virtio_p9_readdir,
1146 [P9_TSTATFS] = virtio_p9_statfs,
1147 [P9_TGETATTR] = virtio_p9_getattr,
1148 [P9_TSETATTR] = virtio_p9_setattr,
1149 [P9_TXATTRWALK] = virtio_p9_eopnotsupp,
1150 [P9_TXATTRCREATE] = virtio_p9_eopnotsupp,
1151 [P9_TMKNOD] = virtio_p9_mknod,
1152 [P9_TLOCK] = virtio_p9_lock,
1153 [P9_TGETLOCK] = virtio_p9_getlock,
1154 [P9_TRENAMEAT] = virtio_p9_renameat,
1155 [P9_TREADLINK] = virtio_p9_readlink,
1156 [P9_TUNLINKAT] = virtio_p9_unlinkat,
1157 [P9_TMKDIR] = virtio_p9_mkdir,
1158 [P9_TVERSION] = virtio_p9_version,
1159 [P9_TLOPEN] = virtio_p9_open,
1160 [P9_TATTACH] = virtio_p9_attach,
1161 [P9_TWALK] = virtio_p9_walk,
1162 [P9_TCLUNK] = virtio_p9_clunk,
1163 [P9_TFSYNC] = virtio_p9_fsync,
1164 [P9_TREAD] = virtio_p9_read,
1165 [P9_TFLUSH] = virtio_p9_flush,
1166 [P9_TLINK] = virtio_p9_link,
1167 [P9_TSYMLINK] = virtio_p9_symlink,
1168 [P9_TLCREATE] = virtio_p9_create,
1169 [P9_TWRITE] = virtio_p9_write,
1170 [P9_TREMOVE] = virtio_p9_remove,
1171 [P9_TRENAME] = virtio_p9_rename,
1174 static struct p9_pdu *virtio_p9_pdu_init(struct kvm *kvm, struct virt_queue *vq)
1176 struct p9_pdu *pdu = calloc(1, sizeof(*pdu));
1180 /* skip the pdu header p9_msg */
1181 pdu->read_offset = VIRTIO_9P_HDR_LEN;
1182 pdu->write_offset = VIRTIO_9P_HDR_LEN;
1183 pdu->queue_head = virt_queue__get_inout_iov(kvm, vq, pdu->in_iov,
1184 pdu->out_iov, &pdu->in_iov_cnt, &pdu->out_iov_cnt);
1188 static u8 virtio_p9_get_cmd(struct p9_pdu *pdu)
1192 * we can peek directly into pdu for a u8
1193 * value. The host endianess won't be an issue
1195 msg = pdu->out_iov[0].iov_base;
1199 static bool virtio_p9_do_io_request(struct kvm *kvm, struct p9_dev_job *job)
1203 p9_handler *handler;
1204 struct p9_dev *p9dev;
1205 struct virt_queue *vq;
1206 struct p9_pdu *p9pdu;
1211 p9pdu = virtio_p9_pdu_init(kvm, vq);
1212 cmd = virtio_p9_get_cmd(p9pdu);
1214 if ((cmd >= ARRAY_SIZE(virtio_9p_dotl_handler)) ||
1215 !virtio_9p_dotl_handler[cmd])
1216 handler = virtio_p9_eopnotsupp;
1218 handler = virtio_9p_dotl_handler[cmd];
1220 handler(p9dev, p9pdu, &len);
1221 virt_queue__set_used_elem(vq, p9pdu->queue_head, len);
1226 static void virtio_p9_do_io(struct kvm *kvm, void *param)
1228 struct p9_dev_job *job = (struct p9_dev_job *)param;
1229 struct p9_dev *p9dev = job->p9dev;
1230 struct virt_queue *vq = job->vq;
1232 while (virt_queue__available(vq)) {
1233 virtio_p9_do_io_request(kvm, job);
1234 p9dev->vdev.ops->signal_vq(kvm, &p9dev->vdev, vq - p9dev->vqs);
1238 static u8 *get_config(struct kvm *kvm, void *dev)
1240 struct p9_dev *p9dev = dev;
1242 return ((u8 *)(p9dev->config));
1245 static u32 get_host_features(struct kvm *kvm, void *dev)
1247 return 1 << VIRTIO_9P_MOUNT_TAG;
1250 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
1252 struct p9_dev *p9dev = dev;
1254 p9dev->features = features;
1257 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
1259 struct p9_dev *p9dev = dev;
1260 struct p9_dev_job *job;
1261 struct virt_queue *queue;
1264 compat__remove_message(compat_id);
1266 queue = &p9dev->vqs[vq];
1268 p = guest_pfn_to_host(kvm, queue->pfn);
1269 job = &p9dev->jobs[vq];
1271 vring_init(&queue->vring, VIRTQUEUE_NUM, p, VIRTIO_PCI_VRING_ALIGN);
1273 *job = (struct p9_dev_job) {
1277 thread_pool__init_job(&job->job_id, kvm, virtio_p9_do_io, job);
1282 static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
1284 struct p9_dev *p9dev = dev;
1286 thread_pool__do_job(&p9dev->jobs[vq].job_id);
1291 static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
1293 struct p9_dev *p9dev = dev;
1295 return p9dev->vqs[vq].pfn;
1298 static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
1300 return VIRTQUEUE_NUM;
1303 struct virtio_ops p9_dev_virtio_ops = (struct virtio_ops) {
1304 .get_config = get_config,
1305 .get_host_features = get_host_features,
1306 .set_guest_features = set_guest_features,
1308 .notify_vq = notify_vq,
1309 .get_pfn_vq = get_pfn_vq,
1310 .get_size_vq = get_size_vq,
1313 int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, int unset)
1317 struct kvm *kvm = opt->ptr;
1320 * 9p dir can be of the form dirname,tag_name or
1321 * just dirname. In the later case we use the
1324 tag_name = strstr(arg, ",");
1329 if (realpath(arg, tmp)) {
1330 if (virtio_9p__register(kvm, tmp, tag_name) < 0)
1331 die("Unable to initialize virtio 9p");
1333 die("Failed resolving 9p path");
1337 int virtio_9p_img_name_parser(const struct option *opt, const char *arg, int unset)
1339 char path[PATH_MAX];
1341 struct kvm *kvm = opt->ptr;
1343 if (stat(arg, &st) == 0 &&
1344 S_ISDIR(st.st_mode)) {
1347 if (kvm->cfg.using_rootfs)
1348 die("Please use only one rootfs directory atmost");
1350 if (realpath(arg, tmp) == 0 ||
1351 virtio_9p__register(kvm, tmp, "/dev/root") < 0)
1352 die("Unable to initialize virtio 9p");
1353 kvm->cfg.using_rootfs = 1;
1357 snprintf(path, PATH_MAX, "%s%s", kvm__get_dir(), arg);
1359 if (stat(path, &st) == 0 &&
1360 S_ISDIR(st.st_mode)) {
1363 if (kvm->cfg.using_rootfs)
1364 die("Please use only one rootfs directory atmost");
1366 if (realpath(path, tmp) == 0 ||
1367 virtio_9p__register(kvm, tmp, "/dev/root") < 0)
1368 die("Unable to initialize virtio 9p");
1369 if (virtio_9p__register(kvm, "/", "hostfs") < 0)
1370 die("Unable to initialize virtio 9p");
1371 kvm_setup_resolv(arg);
1372 kvm->cfg.using_rootfs = kvm->cfg.custom_rootfs = 1;
1373 kvm->cfg.custom_rootfs_name = arg;
1380 int virtio_9p__init(struct kvm *kvm)
1382 struct p9_dev *p9dev;
1384 list_for_each_entry(p9dev, &devs, list) {
1385 virtio_init(kvm, p9dev, &p9dev->vdev, &p9_dev_virtio_ops,
1386 VIRTIO_PCI, PCI_DEVICE_ID_VIRTIO_9P, VIRTIO_ID_9P, PCI_CLASS_9P);
1391 virtio_dev_init(virtio_9p__init);
1393 int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name)
1395 struct p9_dev *p9dev;
1398 p9dev = calloc(1, sizeof(*p9dev));
1403 tag_name = VIRTIO_9P_DEFAULT_TAG;
1405 p9dev->config = calloc(1, sizeof(*p9dev->config) + strlen(tag_name) + 1);
1406 if (p9dev->config == NULL) {
1411 strcpy(p9dev->root_dir, root);
1412 p9dev->config->tag_len = strlen(tag_name);
1413 if (p9dev->config->tag_len > MAX_TAG_LEN) {
1415 goto free_p9dev_config;
1418 memcpy(&p9dev->config->tag, tag_name, strlen(tag_name));
1420 list_add(&p9dev->list, &devs);
1422 if (compat_id == -1)
1423 compat_id = virtio_compat_add_message("virtio-9p", "CONFIG_NET_9P_VIRTIO");
1428 free(p9dev->config);