186e42d74SVenkateswararao Jujjuri (JV) 286e42d74SVenkateswararao Jujjuri (JV) /* 386e42d74SVenkateswararao Jujjuri (JV) * Virtio 9p backend 486e42d74SVenkateswararao Jujjuri (JV) * 586e42d74SVenkateswararao Jujjuri (JV) * Copyright IBM, Corp. 2011 686e42d74SVenkateswararao Jujjuri (JV) * 786e42d74SVenkateswararao Jujjuri (JV) * Authors: 886e42d74SVenkateswararao Jujjuri (JV) * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 986e42d74SVenkateswararao Jujjuri (JV) * 1086e42d74SVenkateswararao Jujjuri (JV) * This work is licensed under the terms of the GNU GPL, version 2. See 1186e42d74SVenkateswararao Jujjuri (JV) * the COPYING file in the top-level directory. 1286e42d74SVenkateswararao Jujjuri (JV) * 1386e42d74SVenkateswararao Jujjuri (JV) */ 1486e42d74SVenkateswararao Jujjuri (JV) 1586e42d74SVenkateswararao Jujjuri (JV) #include "fsdev/qemu-fsdev.h" 1686e42d74SVenkateswararao Jujjuri (JV) #include "qemu-thread.h" 1786e42d74SVenkateswararao Jujjuri (JV) #include "qemu-coroutine.h" 1886e42d74SVenkateswararao Jujjuri (JV) #include "virtio-9p-coth.h" 1986e42d74SVenkateswararao Jujjuri (JV) 20bccacf6cSAneesh Kumar K.V int v9fs_co_readlink(V9fsPDU *pdu, V9fsPath *path, V9fsString *buf) 2186e42d74SVenkateswararao Jujjuri (JV) { 2286e42d74SVenkateswararao Jujjuri (JV) int err; 2386e42d74SVenkateswararao Jujjuri (JV) ssize_t len; 24bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 2586e42d74SVenkateswararao Jujjuri (JV) 26bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 27bccacf6cSAneesh Kumar K.V return -EINTR; 28bccacf6cSAneesh Kumar K.V } 297267c094SAnthony Liguori buf->data = g_malloc(PATH_MAX); 30532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 3186e42d74SVenkateswararao Jujjuri (JV) v9fs_co_run_in_worker( 3286e42d74SVenkateswararao Jujjuri (JV) { 332289be19SAneesh Kumar K.V len = s->ops->readlink(&s->ctx, path, 3486e42d74SVenkateswararao Jujjuri (JV) buf->data, PATH_MAX - 1); 3586e42d74SVenkateswararao Jujjuri (JV) if (len > -1) { 3686e42d74SVenkateswararao Jujjuri (JV) buf->size = len; 3786e42d74SVenkateswararao Jujjuri (JV) buf->data[len] = 0; 3886e42d74SVenkateswararao Jujjuri (JV) err = 0; 3986e42d74SVenkateswararao Jujjuri (JV) } else { 4086e42d74SVenkateswararao Jujjuri (JV) err = -errno; 4186e42d74SVenkateswararao Jujjuri (JV) } 4286e42d74SVenkateswararao Jujjuri (JV) }); 43532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 4486e42d74SVenkateswararao Jujjuri (JV) if (err) { 457267c094SAnthony Liguori g_free(buf->data); 4686e42d74SVenkateswararao Jujjuri (JV) buf->data = NULL; 4786e42d74SVenkateswararao Jujjuri (JV) buf->size = 0; 4886e42d74SVenkateswararao Jujjuri (JV) } 4986e42d74SVenkateswararao Jujjuri (JV) return err; 5086e42d74SVenkateswararao Jujjuri (JV) } 5194840ff9SAneesh Kumar K.V 52bccacf6cSAneesh Kumar K.V int v9fs_co_statfs(V9fsPDU *pdu, V9fsPath *path, struct statfs *stbuf) 5394840ff9SAneesh Kumar K.V { 5494840ff9SAneesh Kumar K.V int err; 55bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 5694840ff9SAneesh Kumar K.V 57bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 58bccacf6cSAneesh Kumar K.V return -EINTR; 59bccacf6cSAneesh Kumar K.V } 60532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 6194840ff9SAneesh Kumar K.V v9fs_co_run_in_worker( 6294840ff9SAneesh Kumar K.V { 632289be19SAneesh Kumar K.V err = s->ops->statfs(&s->ctx, path, stbuf); 6494840ff9SAneesh Kumar K.V if (err < 0) { 6594840ff9SAneesh Kumar K.V err = -errno; 6694840ff9SAneesh Kumar K.V } 6794840ff9SAneesh Kumar K.V }); 68532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 6994840ff9SAneesh Kumar K.V return err; 7094840ff9SAneesh Kumar K.V } 714011ead2SAneesh Kumar K.V 72bccacf6cSAneesh Kumar K.V int v9fs_co_chmod(V9fsPDU *pdu, V9fsPath *path, mode_t mode) 734011ead2SAneesh Kumar K.V { 744011ead2SAneesh Kumar K.V int err; 754011ead2SAneesh Kumar K.V FsCred cred; 76bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 774011ead2SAneesh Kumar K.V 78bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 79bccacf6cSAneesh Kumar K.V return -EINTR; 80bccacf6cSAneesh Kumar K.V } 814011ead2SAneesh Kumar K.V cred_init(&cred); 824011ead2SAneesh Kumar K.V cred.fc_mode = mode; 83532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 844011ead2SAneesh Kumar K.V v9fs_co_run_in_worker( 854011ead2SAneesh Kumar K.V { 862289be19SAneesh Kumar K.V err = s->ops->chmod(&s->ctx, path, &cred); 874011ead2SAneesh Kumar K.V if (err < 0) { 884011ead2SAneesh Kumar K.V err = -errno; 894011ead2SAneesh Kumar K.V } 904011ead2SAneesh Kumar K.V }); 91532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 924011ead2SAneesh Kumar K.V return err; 934011ead2SAneesh Kumar K.V } 944011ead2SAneesh Kumar K.V 95bccacf6cSAneesh Kumar K.V int v9fs_co_utimensat(V9fsPDU *pdu, V9fsPath *path, 964011ead2SAneesh Kumar K.V struct timespec times[2]) 974011ead2SAneesh Kumar K.V { 984011ead2SAneesh Kumar K.V int err; 99bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 1004011ead2SAneesh Kumar K.V 101bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 102bccacf6cSAneesh Kumar K.V return -EINTR; 103bccacf6cSAneesh Kumar K.V } 104532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 1054011ead2SAneesh Kumar K.V v9fs_co_run_in_worker( 1064011ead2SAneesh Kumar K.V { 1072289be19SAneesh Kumar K.V err = s->ops->utimensat(&s->ctx, path, times); 1084011ead2SAneesh Kumar K.V if (err < 0) { 1094011ead2SAneesh Kumar K.V err = -errno; 1104011ead2SAneesh Kumar K.V } 1114011ead2SAneesh Kumar K.V }); 112532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 1134011ead2SAneesh Kumar K.V return err; 1144011ead2SAneesh Kumar K.V } 1154011ead2SAneesh Kumar K.V 116bccacf6cSAneesh Kumar K.V int v9fs_co_chown(V9fsPDU *pdu, V9fsPath *path, uid_t uid, gid_t gid) 1174011ead2SAneesh Kumar K.V { 1184011ead2SAneesh Kumar K.V int err; 1194011ead2SAneesh Kumar K.V FsCred cred; 120bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 1214011ead2SAneesh Kumar K.V 122bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 123bccacf6cSAneesh Kumar K.V return -EINTR; 124bccacf6cSAneesh Kumar K.V } 1254011ead2SAneesh Kumar K.V cred_init(&cred); 1264011ead2SAneesh Kumar K.V cred.fc_uid = uid; 1274011ead2SAneesh Kumar K.V cred.fc_gid = gid; 128532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 1294011ead2SAneesh Kumar K.V v9fs_co_run_in_worker( 1304011ead2SAneesh Kumar K.V { 1312289be19SAneesh Kumar K.V err = s->ops->chown(&s->ctx, path, &cred); 1324011ead2SAneesh Kumar K.V if (err < 0) { 1334011ead2SAneesh Kumar K.V err = -errno; 1344011ead2SAneesh Kumar K.V } 1354011ead2SAneesh Kumar K.V }); 136532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 1374011ead2SAneesh Kumar K.V return err; 1384011ead2SAneesh Kumar K.V } 1394011ead2SAneesh Kumar K.V 140bccacf6cSAneesh Kumar K.V int v9fs_co_truncate(V9fsPDU *pdu, V9fsPath *path, off_t size) 1414011ead2SAneesh Kumar K.V { 1424011ead2SAneesh Kumar K.V int err; 143bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 1444011ead2SAneesh Kumar K.V 145bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 146bccacf6cSAneesh Kumar K.V return -EINTR; 147bccacf6cSAneesh Kumar K.V } 148532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 1494011ead2SAneesh Kumar K.V v9fs_co_run_in_worker( 1504011ead2SAneesh Kumar K.V { 1512289be19SAneesh Kumar K.V err = s->ops->truncate(&s->ctx, path, size); 1524011ead2SAneesh Kumar K.V if (err < 0) { 1534011ead2SAneesh Kumar K.V err = -errno; 1544011ead2SAneesh Kumar K.V } 1554011ead2SAneesh Kumar K.V }); 156532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 1574011ead2SAneesh Kumar K.V return err; 1584011ead2SAneesh Kumar K.V } 15900ace8c5SAneesh Kumar K.V 160bccacf6cSAneesh Kumar K.V int v9fs_co_mknod(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, uid_t uid, 16102cb7f3aSAneesh Kumar K.V gid_t gid, dev_t dev, mode_t mode, struct stat *stbuf) 16200ace8c5SAneesh Kumar K.V { 16300ace8c5SAneesh Kumar K.V int err; 1642289be19SAneesh Kumar K.V V9fsPath path; 16500ace8c5SAneesh Kumar K.V FsCred cred; 166bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 16700ace8c5SAneesh Kumar K.V 168bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 169bccacf6cSAneesh Kumar K.V return -EINTR; 170bccacf6cSAneesh Kumar K.V } 17100ace8c5SAneesh Kumar K.V cred_init(&cred); 17200ace8c5SAneesh Kumar K.V cred.fc_uid = uid; 17300ace8c5SAneesh Kumar K.V cred.fc_gid = gid; 17400ace8c5SAneesh Kumar K.V cred.fc_mode = mode; 17500ace8c5SAneesh Kumar K.V cred.fc_rdev = dev; 176532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 17700ace8c5SAneesh Kumar K.V v9fs_co_run_in_worker( 17800ace8c5SAneesh Kumar K.V { 1792289be19SAneesh Kumar K.V err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred); 18002cb7f3aSAneesh Kumar K.V if (err < 0) { 18102cb7f3aSAneesh Kumar K.V err = -errno; 18202cb7f3aSAneesh Kumar K.V } else { 1832289be19SAneesh Kumar K.V v9fs_path_init(&path); 1842289be19SAneesh Kumar K.V err = v9fs_name_to_path(s, &fidp->path, name->data, &path); 1852289be19SAneesh Kumar K.V if (!err) { 1862289be19SAneesh Kumar K.V err = s->ops->lstat(&s->ctx, &path, stbuf); 18700ace8c5SAneesh Kumar K.V if (err < 0) { 18800ace8c5SAneesh Kumar K.V err = -errno; 18900ace8c5SAneesh Kumar K.V } 19002cb7f3aSAneesh Kumar K.V } 1912289be19SAneesh Kumar K.V v9fs_path_free(&path); 1922289be19SAneesh Kumar K.V } 19300ace8c5SAneesh Kumar K.V }); 194532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 19500ace8c5SAneesh Kumar K.V return err; 19600ace8c5SAneesh Kumar K.V } 197b4b1537bSVenkateswararao Jujjuri 1982289be19SAneesh Kumar K.V /* Only works with path name based fid */ 199bccacf6cSAneesh Kumar K.V int v9fs_co_remove(V9fsPDU *pdu, V9fsPath *path) 200b4b1537bSVenkateswararao Jujjuri { 201b4b1537bSVenkateswararao Jujjuri int err; 202bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 203b4b1537bSVenkateswararao Jujjuri 204bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 205bccacf6cSAneesh Kumar K.V return -EINTR; 206bccacf6cSAneesh Kumar K.V } 207532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 208b4b1537bSVenkateswararao Jujjuri v9fs_co_run_in_worker( 209b4b1537bSVenkateswararao Jujjuri { 210b4b1537bSVenkateswararao Jujjuri err = s->ops->remove(&s->ctx, path->data); 211b4b1537bSVenkateswararao Jujjuri if (err < 0) { 212b4b1537bSVenkateswararao Jujjuri err = -errno; 213b4b1537bSVenkateswararao Jujjuri } 214b4b1537bSVenkateswararao Jujjuri }); 215532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 216b4b1537bSVenkateswararao Jujjuri return err; 217b4b1537bSVenkateswararao Jujjuri } 2182a487e05SAneesh Kumar K.V 219bccacf6cSAneesh Kumar K.V int v9fs_co_unlinkat(V9fsPDU *pdu, V9fsPath *path, V9fsString *name, int flags) 2202289be19SAneesh Kumar K.V { 2212289be19SAneesh Kumar K.V int err; 222bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 2232289be19SAneesh Kumar K.V 224bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 225bccacf6cSAneesh Kumar K.V return -EINTR; 226bccacf6cSAneesh Kumar K.V } 227532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 2282289be19SAneesh Kumar K.V v9fs_co_run_in_worker( 2292289be19SAneesh Kumar K.V { 2302289be19SAneesh Kumar K.V err = s->ops->unlinkat(&s->ctx, path, name->data, flags); 2312289be19SAneesh Kumar K.V if (err < 0) { 2322289be19SAneesh Kumar K.V err = -errno; 2332289be19SAneesh Kumar K.V } 2342289be19SAneesh Kumar K.V }); 235532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 2362289be19SAneesh Kumar K.V return err; 2372289be19SAneesh Kumar K.V } 2382289be19SAneesh Kumar K.V 2392289be19SAneesh Kumar K.V /* Only work with path name based fid */ 240bccacf6cSAneesh Kumar K.V int v9fs_co_rename(V9fsPDU *pdu, V9fsPath *oldpath, V9fsPath *newpath) 2412a487e05SAneesh Kumar K.V { 2422a487e05SAneesh Kumar K.V int err; 243bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 2442a487e05SAneesh Kumar K.V 245bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 246bccacf6cSAneesh Kumar K.V return -EINTR; 247bccacf6cSAneesh Kumar K.V } 2482a487e05SAneesh Kumar K.V v9fs_co_run_in_worker( 2492a487e05SAneesh Kumar K.V { 2502a487e05SAneesh Kumar K.V err = s->ops->rename(&s->ctx, oldpath->data, newpath->data); 2512a487e05SAneesh Kumar K.V if (err < 0) { 2522a487e05SAneesh Kumar K.V err = -errno; 2532a487e05SAneesh Kumar K.V } 2542a487e05SAneesh Kumar K.V }); 2552a487e05SAneesh Kumar K.V return err; 2562a487e05SAneesh Kumar K.V } 25702ac7a34SVenkateswararao Jujjuri 258bccacf6cSAneesh Kumar K.V int v9fs_co_renameat(V9fsPDU *pdu, V9fsPath *olddirpath, V9fsString *oldname, 2592289be19SAneesh Kumar K.V V9fsPath *newdirpath, V9fsString *newname) 2602289be19SAneesh Kumar K.V { 2612289be19SAneesh Kumar K.V int err; 262bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 2632289be19SAneesh Kumar K.V 264bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 265bccacf6cSAneesh Kumar K.V return -EINTR; 266bccacf6cSAneesh Kumar K.V } 2672289be19SAneesh Kumar K.V v9fs_co_run_in_worker( 2682289be19SAneesh Kumar K.V { 2692289be19SAneesh Kumar K.V err = s->ops->renameat(&s->ctx, olddirpath, oldname->data, 2702289be19SAneesh Kumar K.V newdirpath, newname->data); 2712289be19SAneesh Kumar K.V if (err < 0) { 2722289be19SAneesh Kumar K.V err = -errno; 2732289be19SAneesh Kumar K.V } 2742289be19SAneesh Kumar K.V }); 2752289be19SAneesh Kumar K.V return err; 2762289be19SAneesh Kumar K.V } 2772289be19SAneesh Kumar K.V 278bccacf6cSAneesh Kumar K.V int v9fs_co_symlink(V9fsPDU *pdu, V9fsFidState *dfidp, V9fsString *name, 27902cb7f3aSAneesh Kumar K.V const char *oldpath, gid_t gid, struct stat *stbuf) 28002ac7a34SVenkateswararao Jujjuri { 28102ac7a34SVenkateswararao Jujjuri int err; 28202ac7a34SVenkateswararao Jujjuri FsCred cred; 2832289be19SAneesh Kumar K.V V9fsPath path; 284bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 28502cb7f3aSAneesh Kumar K.V 286bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 287bccacf6cSAneesh Kumar K.V return -EINTR; 288bccacf6cSAneesh Kumar K.V } 28902ac7a34SVenkateswararao Jujjuri cred_init(&cred); 29002cb7f3aSAneesh Kumar K.V cred.fc_uid = dfidp->uid; 29102ac7a34SVenkateswararao Jujjuri cred.fc_gid = gid; 29202ac7a34SVenkateswararao Jujjuri cred.fc_mode = 0777; 293532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 29402ac7a34SVenkateswararao Jujjuri v9fs_co_run_in_worker( 29502ac7a34SVenkateswararao Jujjuri { 2962289be19SAneesh Kumar K.V err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path, 2972289be19SAneesh Kumar K.V name->data, &cred); 29802cb7f3aSAneesh Kumar K.V if (err < 0) { 29902cb7f3aSAneesh Kumar K.V err = -errno; 30002cb7f3aSAneesh Kumar K.V } else { 3012289be19SAneesh Kumar K.V v9fs_path_init(&path); 3022289be19SAneesh Kumar K.V err = v9fs_name_to_path(s, &dfidp->path, name->data, &path); 3032289be19SAneesh Kumar K.V if (!err) { 3042289be19SAneesh Kumar K.V err = s->ops->lstat(&s->ctx, &path, stbuf); 30502ac7a34SVenkateswararao Jujjuri if (err < 0) { 30602ac7a34SVenkateswararao Jujjuri err = -errno; 30702ac7a34SVenkateswararao Jujjuri } 30802cb7f3aSAneesh Kumar K.V } 3092289be19SAneesh Kumar K.V v9fs_path_free(&path); 3102289be19SAneesh Kumar K.V } 31102ac7a34SVenkateswararao Jujjuri }); 312532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 3132289be19SAneesh Kumar K.V return err; 3142289be19SAneesh Kumar K.V } 3152289be19SAneesh Kumar K.V 3162289be19SAneesh Kumar K.V /* 3172289be19SAneesh Kumar K.V * For path name based fid we don't block. So we can 3182289be19SAneesh Kumar K.V * directly call the fs driver ops. 3192289be19SAneesh Kumar K.V */ 320bccacf6cSAneesh Kumar K.V int v9fs_co_name_to_path(V9fsPDU *pdu, V9fsPath *dirpath, 3212289be19SAneesh Kumar K.V const char *name, V9fsPath *path) 3222289be19SAneesh Kumar K.V { 3232289be19SAneesh Kumar K.V int err; 324bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 325532decb7SAneesh Kumar K.V 326*c98f1d4aSAneesh Kumar K.V if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 3272289be19SAneesh Kumar K.V err = s->ops->name_to_path(&s->ctx, dirpath, name, path); 3282289be19SAneesh Kumar K.V if (err < 0) { 3292289be19SAneesh Kumar K.V err = -errno; 3302289be19SAneesh Kumar K.V } 331532decb7SAneesh Kumar K.V } else { 332bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 333bccacf6cSAneesh Kumar K.V return -EINTR; 334bccacf6cSAneesh Kumar K.V } 335532decb7SAneesh Kumar K.V v9fs_co_run_in_worker( 336532decb7SAneesh Kumar K.V { 337532decb7SAneesh Kumar K.V err = s->ops->name_to_path(&s->ctx, dirpath, name, path); 338532decb7SAneesh Kumar K.V if (err < 0) { 339532decb7SAneesh Kumar K.V err = -errno; 340532decb7SAneesh Kumar K.V } 341532decb7SAneesh Kumar K.V }); 342532decb7SAneesh Kumar K.V } 34302ac7a34SVenkateswararao Jujjuri return err; 34402ac7a34SVenkateswararao Jujjuri } 345