Revision b67592ea hw/virtio-9p.c

b/hw/virtio-9p.c
172 172
    return s->ops->mknod(&s->ctx, name, &cred);
173 173
}
174 174

  
175
static int v9fs_do_mkdir(V9fsState *s, V9fsCreateState *vs)
175
static int v9fs_do_mkdir(V9fsState *s, char *name, mode_t mode,
176
                uid_t uid, gid_t gid)
176 177
{
177 178
    FsCred cred;
178 179

  
179 180
    cred_init(&cred);
180
    cred.fc_uid = vs->fidp->uid;
181
    cred.fc_mode = vs->perm & 0777;
181
    cred.fc_uid = uid;
182
    cred.fc_gid = gid;
183
    cred.fc_mode = mode;
182 184

  
183
    return s->ops->mkdir(&s->ctx, vs->fullname.data, &cred);
185
    return s->ops->mkdir(&s->ctx, name, &cred);
184 186
}
185 187

  
186 188
static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
......
2294 2296
    }
2295 2297

  
2296 2298
    if (vs->perm & P9_STAT_MODE_DIR) {
2297
        err = v9fs_do_mkdir(s, vs);
2299
        err = v9fs_do_mkdir(s, vs->fullname.data, vs->perm & 0777,
2300
                vs->fidp->uid, -1);
2298 2301
        v9fs_create_post_mkdir(s, vs, err);
2299 2302
    } else if (vs->perm & P9_STAT_MODE_SYMLINK) {
2300 2303
        err = v9fs_do_symlink(s, vs->fidp, vs->extension.data,
......
2924 2927
    qemu_free(vs);
2925 2928
}
2926 2929

  
2930
static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
2931
{
2932
    if (err == -1) {
2933
        err = -errno;
2934
        goto out;
2935
    }
2936

  
2937
    stat_to_qid(&vs->stbuf, &vs->qid);
2938
    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid);
2939
    err = vs->offset;
2940
out:
2941
    complete_pdu(s, vs->pdu, err);
2942
    v9fs_string_free(&vs->fullname);
2943
    v9fs_string_free(&vs->name);
2944
    qemu_free(vs);
2945
}
2946

  
2947
static void v9fs_mkdir_post_mkdir(V9fsState *s, V9fsMkState *vs, int err)
2948
{
2949
    if (err == -1) {
2950
        err = -errno;
2951
        goto out;
2952
    }
2953

  
2954
    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
2955
    v9fs_mkdir_post_lstat(s, vs, err);
2956
    return;
2957
out:
2958
    complete_pdu(s, vs->pdu, err);
2959
    v9fs_string_free(&vs->fullname);
2960
    v9fs_string_free(&vs->name);
2961
    qemu_free(vs);
2962
}
2963

  
2964
static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
2965
{
2966
    int32_t fid;
2967
    V9fsMkState *vs;
2968
    int err = 0;
2969
    V9fsFidState *fidp;
2970
    gid_t gid;
2971
    int mode;
2972

  
2973
    vs = qemu_malloc(sizeof(*vs));
2974
    vs->pdu = pdu;
2975
    vs->offset = 7;
2976

  
2977
    v9fs_string_init(&vs->fullname);
2978
    pdu_unmarshal(vs->pdu, vs->offset, "dsdd", &fid, &vs->name, &mode,
2979
        &gid);
2980

  
2981
    fidp = lookup_fid(s, fid);
2982
    if (fidp == NULL) {
2983
        err = -ENOENT;
2984
        goto out;
2985
    }
2986

  
2987
    v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data);
2988
    err = v9fs_do_mkdir(s, vs->fullname.data, mode, fidp->uid, gid);
2989
    v9fs_mkdir_post_mkdir(s, vs, err);
2990
    return;
2991

  
2992
out:
2993
    complete_pdu(s, vs->pdu, err);
2994
    v9fs_string_free(&vs->fullname);
2995
    v9fs_string_free(&vs->name);
2996
    qemu_free(vs);
2997
}
2998

  
2927 2999
typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
2928 3000

  
2929 3001
static pdu_handler_t *pdu_handlers[] = {
......
2932 3004
    [P9_TGETATTR] = v9fs_getattr,
2933 3005
    [P9_TSETATTR] = v9fs_setattr,
2934 3006
    [P9_TMKNOD] = v9fs_mknod,
3007
    [P9_TMKDIR] = v9fs_mkdir,
2935 3008
    [P9_TVERSION] = v9fs_version,
2936 3009
    [P9_TATTACH] = v9fs_attach,
2937 3010
    [P9_TSTAT] = v9fs_stat,

Also available in: Unified diff