1dcb9dbe3SAneesh Kumar K.V /* 2af8b38b0SGreg Kurz * 9p backend 3dcb9dbe3SAneesh Kumar K.V * 4dcb9dbe3SAneesh Kumar K.V * Copyright IBM, Corp. 2011 5dcb9dbe3SAneesh Kumar K.V * 6dcb9dbe3SAneesh Kumar K.V * Authors: 7dcb9dbe3SAneesh Kumar K.V * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 8dcb9dbe3SAneesh Kumar K.V * 9dcb9dbe3SAneesh Kumar K.V * This work is licensed under the terms of the GNU GPL, version 2. See 10dcb9dbe3SAneesh Kumar K.V * the COPYING file in the top-level directory. 11dcb9dbe3SAneesh Kumar K.V * 12dcb9dbe3SAneesh Kumar K.V */ 13dcb9dbe3SAneesh Kumar K.V 14fbc04127SPeter Maydell #include "qemu/osdep.h" 15dcb9dbe3SAneesh Kumar K.V #include "fsdev/qemu-fsdev.h" 161de7afc9SPaolo Bonzini #include "qemu/thread.h" 1710817bf0SDaniel P. Berrange #include "qemu/coroutine.h" 18db725815SMarkus Armbruster #include "qemu/main-loop.h" 19fe52840cSWei Liu #include "coth.h" 20dcb9dbe3SAneesh Kumar K.V 21*dd8151f4SChristian Schoenebeck /* 22*dd8151f4SChristian Schoenebeck * Intended to be called from bottom-half (e.g. background I/O thread) 23*dd8151f4SChristian Schoenebeck * context. 24*dd8151f4SChristian Schoenebeck */ 25*dd8151f4SChristian Schoenebeck static int do_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent) 26dcb9dbe3SAneesh Kumar K.V { 27*dd8151f4SChristian Schoenebeck int err = 0; 28bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 29635324e8SGreg Kurz struct dirent *entry; 30635324e8SGreg Kurz 31dcb9dbe3SAneesh Kumar K.V errno = 0; 32635324e8SGreg Kurz entry = s->ops->readdir(&s->ctx, &fidp->fs); 33635324e8SGreg Kurz if (!entry && errno) { 34*dd8151f4SChristian Schoenebeck *dent = NULL; 35dcb9dbe3SAneesh Kumar K.V err = -errno; 36dcb9dbe3SAneesh Kumar K.V } else { 37635324e8SGreg Kurz *dent = entry; 38dcb9dbe3SAneesh Kumar K.V } 39*dd8151f4SChristian Schoenebeck return err; 40*dd8151f4SChristian Schoenebeck } 41*dd8151f4SChristian Schoenebeck 42*dd8151f4SChristian Schoenebeck int coroutine_fn v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, 43*dd8151f4SChristian Schoenebeck struct dirent **dent) 44*dd8151f4SChristian Schoenebeck { 45*dd8151f4SChristian Schoenebeck int err; 46*dd8151f4SChristian Schoenebeck 47*dd8151f4SChristian Schoenebeck if (v9fs_request_cancelled(pdu)) { 48*dd8151f4SChristian Schoenebeck return -EINTR; 49*dd8151f4SChristian Schoenebeck } 50*dd8151f4SChristian Schoenebeck v9fs_co_run_in_worker({ 51*dd8151f4SChristian Schoenebeck err = do_readdir(pdu, fidp, dent); 52dcb9dbe3SAneesh Kumar K.V }); 53dcb9dbe3SAneesh Kumar K.V return err; 54dcb9dbe3SAneesh Kumar K.V } 55dcb9dbe3SAneesh Kumar K.V 56bccacf6cSAneesh Kumar K.V off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) 57dcb9dbe3SAneesh Kumar K.V { 58dcb9dbe3SAneesh Kumar K.V off_t err; 59bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 60dcb9dbe3SAneesh Kumar K.V 61bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 62bccacf6cSAneesh Kumar K.V return -EINTR; 63bccacf6cSAneesh Kumar K.V } 64dcb9dbe3SAneesh Kumar K.V v9fs_co_run_in_worker( 65dcb9dbe3SAneesh Kumar K.V { 66cc720ddbSAneesh Kumar K.V err = s->ops->telldir(&s->ctx, &fidp->fs); 67dcb9dbe3SAneesh Kumar K.V if (err < 0) { 68dcb9dbe3SAneesh Kumar K.V err = -errno; 69dcb9dbe3SAneesh Kumar K.V } 70dcb9dbe3SAneesh Kumar K.V }); 71dcb9dbe3SAneesh Kumar K.V return err; 72dcb9dbe3SAneesh Kumar K.V } 73dcb9dbe3SAneesh Kumar K.V 745bdade66SGreg Kurz void coroutine_fn v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, 755bdade66SGreg Kurz off_t offset) 76dcb9dbe3SAneesh Kumar K.V { 77bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 78bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 79bccacf6cSAneesh Kumar K.V return; 80bccacf6cSAneesh Kumar K.V } 81dcb9dbe3SAneesh Kumar K.V v9fs_co_run_in_worker( 82dcb9dbe3SAneesh Kumar K.V { 83cc720ddbSAneesh Kumar K.V s->ops->seekdir(&s->ctx, &fidp->fs, offset); 84dcb9dbe3SAneesh Kumar K.V }); 85dcb9dbe3SAneesh Kumar K.V } 86dcb9dbe3SAneesh Kumar K.V 875bdade66SGreg Kurz void coroutine_fn v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp) 88dcb9dbe3SAneesh Kumar K.V { 89bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 90bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 91bccacf6cSAneesh Kumar K.V return; 92bccacf6cSAneesh Kumar K.V } 93dcb9dbe3SAneesh Kumar K.V v9fs_co_run_in_worker( 94dcb9dbe3SAneesh Kumar K.V { 95cc720ddbSAneesh Kumar K.V s->ops->rewinddir(&s->ctx, &fidp->fs); 96dcb9dbe3SAneesh Kumar K.V }); 97dcb9dbe3SAneesh Kumar K.V } 98d0884642SVenkateswararao Jujjuri 995bdade66SGreg Kurz int coroutine_fn v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, 1005bdade66SGreg Kurz V9fsString *name, mode_t mode, uid_t uid, 1015bdade66SGreg Kurz gid_t gid, struct stat *stbuf) 102d0884642SVenkateswararao Jujjuri { 103d0884642SVenkateswararao Jujjuri int err; 104d0884642SVenkateswararao Jujjuri FsCred cred; 1052289be19SAneesh Kumar K.V V9fsPath path; 106bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 107d0884642SVenkateswararao Jujjuri 108bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 1093a93113aSDong Xu Wang return -EINTR; 110bccacf6cSAneesh Kumar K.V } 111d0884642SVenkateswararao Jujjuri cred_init(&cred); 112d0884642SVenkateswararao Jujjuri cred.fc_mode = mode; 113d0884642SVenkateswararao Jujjuri cred.fc_uid = uid; 114d0884642SVenkateswararao Jujjuri cred.fc_gid = gid; 115532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 116d0884642SVenkateswararao Jujjuri v9fs_co_run_in_worker( 117d0884642SVenkateswararao Jujjuri { 1182289be19SAneesh Kumar K.V err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred); 11902cb7f3aSAneesh Kumar K.V if (err < 0) { 12002cb7f3aSAneesh Kumar K.V err = -errno; 12102cb7f3aSAneesh Kumar K.V } else { 1222289be19SAneesh Kumar K.V v9fs_path_init(&path); 1232289be19SAneesh Kumar K.V err = v9fs_name_to_path(s, &fidp->path, name->data, &path); 1242289be19SAneesh Kumar K.V if (!err) { 1252289be19SAneesh Kumar K.V err = s->ops->lstat(&s->ctx, &path, stbuf); 126d0884642SVenkateswararao Jujjuri if (err < 0) { 127d0884642SVenkateswararao Jujjuri err = -errno; 128d0884642SVenkateswararao Jujjuri } 12902cb7f3aSAneesh Kumar K.V } 1302289be19SAneesh Kumar K.V v9fs_path_free(&path); 1312289be19SAneesh Kumar K.V } 132d0884642SVenkateswararao Jujjuri }); 133532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 134d0884642SVenkateswararao Jujjuri return err; 135d0884642SVenkateswararao Jujjuri } 136f6b7f0abSAneesh Kumar K.V 1375bdade66SGreg Kurz int coroutine_fn v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) 138f6b7f0abSAneesh Kumar K.V { 139f6b7f0abSAneesh Kumar K.V int err; 140bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 141f6b7f0abSAneesh Kumar K.V 142bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 1433a93113aSDong Xu Wang return -EINTR; 144bccacf6cSAneesh Kumar K.V } 145532decb7SAneesh Kumar K.V v9fs_path_read_lock(s); 146f6b7f0abSAneesh Kumar K.V v9fs_co_run_in_worker( 147f6b7f0abSAneesh Kumar K.V { 148cc720ddbSAneesh Kumar K.V err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs); 149cc720ddbSAneesh Kumar K.V if (err < 0) { 150f6b7f0abSAneesh Kumar K.V err = -errno; 151f6b7f0abSAneesh Kumar K.V } else { 152f6b7f0abSAneesh Kumar K.V err = 0; 153f6b7f0abSAneesh Kumar K.V } 154f6b7f0abSAneesh Kumar K.V }); 155532decb7SAneesh Kumar K.V v9fs_path_unlock(s); 15695f65511SAneesh Kumar K.V if (!err) { 15795f65511SAneesh Kumar K.V total_open_fd++; 15895f65511SAneesh Kumar K.V if (total_open_fd > open_fd_hw) { 159bccacf6cSAneesh Kumar K.V v9fs_reclaim_fd(pdu); 16095f65511SAneesh Kumar K.V } 16195f65511SAneesh Kumar K.V } 162f6b7f0abSAneesh Kumar K.V return err; 163f6b7f0abSAneesh Kumar K.V } 164bed4352cSAneesh Kumar K.V 1655bdade66SGreg Kurz int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs) 166bed4352cSAneesh Kumar K.V { 167bed4352cSAneesh Kumar K.V int err; 168bccacf6cSAneesh Kumar K.V V9fsState *s = pdu->s; 169bed4352cSAneesh Kumar K.V 170bccacf6cSAneesh Kumar K.V if (v9fs_request_cancelled(pdu)) { 1713a93113aSDong Xu Wang return -EINTR; 172bccacf6cSAneesh Kumar K.V } 173bed4352cSAneesh Kumar K.V v9fs_co_run_in_worker( 174bed4352cSAneesh Kumar K.V { 175cc720ddbSAneesh Kumar K.V err = s->ops->closedir(&s->ctx, fs); 176bed4352cSAneesh Kumar K.V if (err < 0) { 177bed4352cSAneesh Kumar K.V err = -errno; 178bed4352cSAneesh Kumar K.V } 179bed4352cSAneesh Kumar K.V }); 18095f65511SAneesh Kumar K.V if (!err) { 18195f65511SAneesh Kumar K.V total_open_fd--; 18295f65511SAneesh Kumar K.V } 183bed4352cSAneesh Kumar K.V return err; 184bed4352cSAneesh Kumar K.V } 185