From: Sooyoung Ha Date: Wed, 2 Nov 2016 08:33:34 +0000 (+0900) Subject: 9pfs: enable 9pfs on Windows and Macos X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~6^2~13^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1da4aeb2eb54d8fb84f94a6e608c1c65360afdba;p=sdk%2Femulator%2Fqemu.git 9pfs: enable 9pfs on Windows and Macos I modify the maru defined codes of 9pfs for applying qemu 2.7 upgrade. Change-Id: I83abb46d97f07443f1337659f12da8afa1d8eb15 Signed-off-by: Sooyoung Ha --- diff --git a/hw/9pfs/9p-local-maru.c b/hw/9pfs/9p-local-maru.c index d2f49311e5..7605f1dd13 100644 --- a/hw/9pfs/9p-local-maru.c +++ b/hw/9pfs/9p-local-maru.c @@ -1,11 +1,12 @@ /* * Virtio 9p backend for Maru - * Based on hw/9pfs/virtio-9p-local.c: + * Based on hw/9pfs/9p-local.c: * - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: * Sooyoung Ha + * SeokYeon Hwang * YeongKyoon Lee * * This program is free software; you can redistribute it and/or @@ -29,9 +30,9 @@ #include "qemu/osdep.h" #include "9p.h" -#include "fsdev/qemu-fsdev.h" /* local_ops */ #ifndef CONFIG_WIN32 #include "9p-xattr.h" +#include "fsdev/qemu-fsdev.h" /* local_ops */ #include #include #include @@ -571,12 +572,12 @@ static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs) struct dirent *entry; again: -#ifndef CONFIG_WIN32 entry = readdir(fs->dir.stream); if (!entry) { return NULL; } +#ifndef CONFIG_WIN32 if (ctx->export_flags & V9FS_SM_MAPPED) { entry->d_type = DT_UNKNOWN; } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { @@ -587,13 +588,8 @@ again: entry->d_type = DT_UNKNOWN; } #else - int ret = errno; - *result = readdir(fs->dir.stream); - ret = (ret == errno ? 0 : errno); - entry = *result; if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { - if (!ret && *result != NULL && - !strcmp(entry->d_name, VIRTFS_META_DIR)) { + if (!strcmp(entry->d_name, VIRTFS_META_DIR)) { /* skp the meta data directory */ goto again; } diff --git a/hw/9pfs/9p-maru.c b/hw/9pfs/9p-maru.c index dcc0f2b927..ebe4987d73 100644 --- a/hw/9pfs/9p-maru.c +++ b/hw/9pfs/9p-maru.c @@ -1,11 +1,12 @@ /* * Virtio 9p backend for Maru - * Based on hw/9pfs/virtio-9p.c: + * Based on hw/9pfs/9p.c: * - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: * Sooyoung Ha + * SeokYeon Hwang * YeongKyoon Lee * * This program is free software; you can redistribute it and/or @@ -29,7 +30,6 @@ #include "qemu/osdep.h" #include "hw/virtio/virtio.h" -#include "hw/i386/pc.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/iov.h" @@ -348,6 +348,9 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid) f->next = s->fid_list; s->fid_list = f; + v9fs_readdir_init(&f->fs.dir); + v9fs_readdir_init(&f->fs_reclaim.dir); + return f; } @@ -1107,6 +1110,7 @@ static void v9fs_attach(void *opaque) goto out; } err += offset; + memcpy(&s->root_qid, &qid, sizeof(qid)); trace_v9fs_attach_return(pdu->tag, pdu->id, qid.type, qid.version, qid.path); /* @@ -1366,6 +1370,23 @@ static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids) return offset; } +static bool name_is_illegal(const char *name) +{ +#ifndef CONFIG_WIN32 + return !*name || strchr(name, '/') != NULL; +#else + return !*name || strchr(name, '\\') != NULL; +#endif +} + +static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2) +{ + return + qid1->type != qid2->type || + qid1->version != qid2->version || + qid1->path != qid2->path; +} + static void v9fs_walk(void *opaque) { TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__); @@ -1382,6 +1403,7 @@ static void v9fs_walk(void *opaque) V9fsFidState *newfidp = NULL; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; + V9fsQID qid; err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames); if (err < 0) { @@ -1402,6 +1424,10 @@ static void v9fs_walk(void *opaque) ERR("[%d][ >> %s]\n", __LINE__, __func__); goto out_nofid; } + if (name_is_illegal(wnames[i].data)) { + err = -ENOENT; + goto out_nofid; + } offset += err; } } else if (nwnames > P9_MAXWELEM) { @@ -1415,6 +1441,12 @@ static void v9fs_walk(void *opaque) err = -ENOENT; goto out_nofid; } + + err = fid_to_qid(pdu, fidp, &qid); + if (err < 0) { + goto out; + } + v9fs_path_init(&dpath); v9fs_path_init(&path); /* @@ -1424,17 +1456,23 @@ static void v9fs_walk(void *opaque) v9fs_path_copy(&dpath, &fidp->path); v9fs_path_copy(&path, &fidp->path); for (name_idx = 0; name_idx < nwnames; name_idx++) { - err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path); - if (err < 0) { - ERR("[%d][ >> %s]\n", __LINE__, __func__); - goto out; - } - err = v9fs_co_lstat(pdu, &path, &stbuf); - if (err < 0) { - goto out; + if (not_same_qid(&pdu->s->root_qid, &qid) || + strcmp("..", wnames[name_idx].data)) { + err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, + &path); + if (err < 0) { + ERR("[%d][ >> %s]\n", __LINE__, __func__); + goto out; + } + + err = v9fs_co_lstat(pdu, &path, &stbuf); + if (err < 0) { + goto out; + } + stat_to_qid(&stbuf, &qid); + v9fs_path_copy(&dpath, &path); } - stat_to_qid(&stbuf, &qids[name_idx]); - v9fs_path_copy(&dpath, &path); + memcpy(&qids[name_idx], &qid, sizeof(qid)); } if (fid == newfid) { BUG_ON(fidp->fid_type != P9_FID_NONE); @@ -1612,6 +1650,16 @@ static void v9fs_lcreate(void *opaque) } trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + fidp = get_fid(pdu, dfid); if (fidp == NULL) { ERR("[%d][ >> %s]\n", __LINE__, __func__); @@ -1773,8 +1821,6 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, return saved_dir_pos; } - dent = g_malloc(sizeof(struct dirent)); - while (1) { v9fs_path_init(&path); @@ -1788,17 +1834,17 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path); if (err < 0) { ERR("[%d][ >> %s]\n", __LINE__, __func__); - goto out; + break; } err = v9fs_co_lstat(pdu, &path, &stbuf); if (err < 0) { ERR("[%d][ >> %s]\n", __LINE__, __func__); - goto out; + break; } err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat); if (err < 0) { ERR("[%d][ >> %s]\n", __LINE__, __func__); - goto out; + break; } /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */ len = pdu_marshal(pdu, 11 + count, "S", &v9stat); @@ -1810,7 +1856,6 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_stat_free(&v9stat); v9fs_path_free(&path); - g_free(dent); return count; } count += len; @@ -1822,8 +1867,6 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, saved_dir_pos = v9fs_co_telldir(pdu, fidp); #endif } -out: - g_free(dent); v9fs_readdir_unlock(&fidp->fs.dir); @@ -1986,8 +2029,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, return saved_dir_pos; } - dent = g_malloc(sizeof(struct dirent)); - while (1) { v9fs_readdir_lock(&fidp->fs.dir); @@ -1999,10 +2040,11 @@ static int v9fs_do_readdir(V9fsPDU *pdu, v9fs_string_init(&name); v9fs_string_sprintf(&name, "%s", dent->d_name); if ((count + v9fs_readdir_data_size(&name)) > max_count) { + v9fs_readdir_unlock(&fidp->fs.dir); + /* Ran out of buffer. Set dir back to old position and return */ v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); - g_free(dent); return count; } /* @@ -2039,7 +2081,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, if (len < 0) { v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); - g_free(dent); return len; } count += len; @@ -2050,7 +2091,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, saved_dir_pos = d_offset; #endif } - g_free(dent); v9fs_readdir_unlock(&fidp->fs.dir); @@ -2286,6 +2326,16 @@ static void v9fs_create(void *opaque) } trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + fidp = get_fid(pdu, fid); if (fidp == NULL) { ERR("[%d][ >> %s]\n", __LINE__, __func__); @@ -2473,6 +2523,16 @@ static void v9fs_symlink(void *opaque) } trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + dfidp = get_fid(pdu, dfid); if (dfidp == NULL) { err = -EINVAL; @@ -2553,6 +2613,16 @@ static void v9fs_link(void *opaque) } trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + dfidp = get_fid(pdu, dfid); if (dfidp == NULL) { err = -ENOENT; @@ -2637,6 +2707,22 @@ static void v9fs_unlinkat(void *opaque) if (err < 0) { goto out_nofid; } + + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data)) { + err = -EINVAL; + goto out_nofid; + } + + if (!strcmp("..", name.data)) { + err = -ENOTEMPTY; + goto out_nofid; + } + dfidp = get_fid(pdu, dfid); if (dfidp == NULL) { err = -EINVAL; @@ -2744,6 +2830,17 @@ static void v9fs_rename(void *opaque) if (err < 0) { goto out_nofid; } + + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EISDIR; + goto out_nofid; + } + fidp = get_fid(pdu, fid); if (fidp == NULL) { err = -ENOENT; @@ -2858,6 +2955,17 @@ static void v9fs_renameat(void *opaque) goto out_err; } + if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) { + err = -ENOENT; + goto out_err; + } + + if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) || + !strcmp(".", new_name.data) || !strcmp("..", new_name.data)) { + err = -EISDIR; + goto out_err; + } + v9fs_path_write_lock(s); err = v9fs_complete_renameat(pdu, olddirfid, &old_name, newdirfid, &new_name); @@ -3085,6 +3193,16 @@ static void v9fs_mknod(void *opaque) } trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + fidp = get_fid(pdu, fid); if (fidp == NULL) { err = -ENOENT; @@ -3243,6 +3361,16 @@ static void v9fs_mkdir(void *opaque) } trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid); + if (name_is_illegal(name.data)) { + err = -ENOENT; + goto out_nofid; + } + + if (!strcmp(".", name.data) || !strcmp("..", name.data)) { + err = -EEXIST; + goto out_nofid; + } + fidp = get_fid(pdu, fid); if (fidp == NULL) { err = -ENOENT;