qemu: virtio-9p: Implement TMKDIR

Synopsis

    size[4] Tmkdir tag[2] fid[4] name[s] mode[4] gid[4]

    size[4] Rmkdir tag[2] qid[13]

Description

    mkdir asks the file server to create a directory with given name,
    mode and gid. The qid for the new directory is returned with
    the mkdir reply message.

Note: 72 is selected as the opcode for TMKDIR from the reserved list.

Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
[jvrao@linux.vnet.ibm.com: Fix perm handling when creating directory]

Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
This commit is contained in:
M. Mohan Kumar 2010-06-22 12:25:22 +05:30 committed by Aneesh Kumar K.V
parent 5268cecc6d
commit b67592ea56
3 changed files with 91 additions and 5 deletions

View File

@ -367,6 +367,17 @@ void pprint_pdu(V9fsPDU *pdu)
pprint_data(pdu, 1, &offset, ", data"); pprint_data(pdu, 1, &offset, ", data");
#endif #endif
break; break;
case P9_TMKDIR:
fprintf(llogfile, "TMKDIR: (");
pprint_int32(pdu, 0, &offset, "fid");
pprint_str(pdu, 0, &offset, "name");
pprint_int32(pdu, 0, &offset, "mode");
pprint_int32(pdu, 0, &offset, "gid");
break;
case P9_RMKDIR:
fprintf(llogfile, "RMKDIR: (");
pprint_qid(pdu, 0, &offset, "qid");
break;
case P9_TVERSION: case P9_TVERSION:
fprintf(llogfile, "TVERSION: ("); fprintf(llogfile, "TVERSION: (");
pprint_int32(pdu, 0, &offset, "msize"); pprint_int32(pdu, 0, &offset, "msize");

View File

@ -172,15 +172,17 @@ static int v9fs_do_mknod(V9fsState *s, char *name,
return s->ops->mknod(&s->ctx, name, &cred); return s->ops->mknod(&s->ctx, name, &cred);
} }
static int v9fs_do_mkdir(V9fsState *s, V9fsCreateState *vs) static int v9fs_do_mkdir(V9fsState *s, char *name, mode_t mode,
uid_t uid, gid_t gid)
{ {
FsCred cred; FsCred cred;
cred_init(&cred); cred_init(&cred);
cred.fc_uid = vs->fidp->uid; cred.fc_uid = uid;
cred.fc_mode = vs->perm & 0777; cred.fc_gid = gid;
cred.fc_mode = mode;
return s->ops->mkdir(&s->ctx, vs->fullname.data, &cred); return s->ops->mkdir(&s->ctx, name, &cred);
} }
static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf) static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
@ -2294,7 +2296,8 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
} }
if (vs->perm & P9_STAT_MODE_DIR) { if (vs->perm & P9_STAT_MODE_DIR) {
err = v9fs_do_mkdir(s, vs); err = v9fs_do_mkdir(s, vs->fullname.data, vs->perm & 0777,
vs->fidp->uid, -1);
v9fs_create_post_mkdir(s, vs, err); v9fs_create_post_mkdir(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_SYMLINK) { } else if (vs->perm & P9_STAT_MODE_SYMLINK) {
err = v9fs_do_symlink(s, vs->fidp, vs->extension.data, err = v9fs_do_symlink(s, vs->fidp, vs->extension.data,
@ -2924,6 +2927,75 @@ out:
qemu_free(vs); qemu_free(vs);
} }
static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
{
if (err == -1) {
err = -errno;
goto out;
}
stat_to_qid(&vs->stbuf, &vs->qid);
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid);
err = vs->offset;
out:
complete_pdu(s, vs->pdu, err);
v9fs_string_free(&vs->fullname);
v9fs_string_free(&vs->name);
qemu_free(vs);
}
static void v9fs_mkdir_post_mkdir(V9fsState *s, V9fsMkState *vs, int err)
{
if (err == -1) {
err = -errno;
goto out;
}
err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
v9fs_mkdir_post_lstat(s, vs, err);
return;
out:
complete_pdu(s, vs->pdu, err);
v9fs_string_free(&vs->fullname);
v9fs_string_free(&vs->name);
qemu_free(vs);
}
static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsMkState *vs;
int err = 0;
V9fsFidState *fidp;
gid_t gid;
int mode;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
v9fs_string_init(&vs->fullname);
pdu_unmarshal(vs->pdu, vs->offset, "dsdd", &fid, &vs->name, &mode,
&gid);
fidp = lookup_fid(s, fid);
if (fidp == NULL) {
err = -ENOENT;
goto out;
}
v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data);
err = v9fs_do_mkdir(s, vs->fullname.data, mode, fidp->uid, gid);
v9fs_mkdir_post_mkdir(s, vs, err);
return;
out:
complete_pdu(s, vs->pdu, err);
v9fs_string_free(&vs->fullname);
v9fs_string_free(&vs->name);
qemu_free(vs);
}
typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu); typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
static pdu_handler_t *pdu_handlers[] = { static pdu_handler_t *pdu_handlers[] = {
@ -2932,6 +3004,7 @@ static pdu_handler_t *pdu_handlers[] = {
[P9_TGETATTR] = v9fs_getattr, [P9_TGETATTR] = v9fs_getattr,
[P9_TSETATTR] = v9fs_setattr, [P9_TSETATTR] = v9fs_setattr,
[P9_TMKNOD] = v9fs_mknod, [P9_TMKNOD] = v9fs_mknod,
[P9_TMKDIR] = v9fs_mkdir,
[P9_TVERSION] = v9fs_version, [P9_TVERSION] = v9fs_version,
[P9_TATTACH] = v9fs_attach, [P9_TATTACH] = v9fs_attach,
[P9_TSTAT] = v9fs_stat, [P9_TSTAT] = v9fs_stat,

View File

@ -29,6 +29,8 @@ enum {
P9_RREADDIR, P9_RREADDIR,
P9_TLINK = 70, P9_TLINK = 70,
P9_RLINK, P9_RLINK,
P9_TMKDIR = 72,
P9_RMKDIR,
P9_TVERSION = 100, P9_TVERSION = 100,
P9_RVERSION, P9_RVERSION,
P9_TAUTH = 102, P9_TAUTH = 102,