|
|
1.1 ! root 1: ! 2: /* ! 3: * Virtio 9p backend ! 4: * ! 5: * Copyright IBM, Corp. 2011 ! 6: * ! 7: * Authors: ! 8: * Aneesh Kumar K.V <[email protected]> ! 9: * ! 10: * This work is licensed under the terms of the GNU GPL, version 2. See ! 11: * the COPYING file in the top-level directory. ! 12: * ! 13: */ ! 14: ! 15: #include "fsdev/qemu-fsdev.h" ! 16: #include "qemu-thread.h" ! 17: #include "qemu-coroutine.h" ! 18: #include "virtio-9p-coth.h" ! 19: ! 20: int v9fs_co_readlink(V9fsPDU *pdu, V9fsPath *path, V9fsString *buf) ! 21: { ! 22: int err; ! 23: ssize_t len; ! 24: V9fsState *s = pdu->s; ! 25: ! 26: if (v9fs_request_cancelled(pdu)) { ! 27: return -EINTR; ! 28: } ! 29: buf->data = g_malloc(PATH_MAX); ! 30: v9fs_path_read_lock(s); ! 31: v9fs_co_run_in_worker( ! 32: { ! 33: len = s->ops->readlink(&s->ctx, path, ! 34: buf->data, PATH_MAX - 1); ! 35: if (len > -1) { ! 36: buf->size = len; ! 37: buf->data[len] = 0; ! 38: err = 0; ! 39: } else { ! 40: err = -errno; ! 41: } ! 42: }); ! 43: v9fs_path_unlock(s); ! 44: if (err) { ! 45: g_free(buf->data); ! 46: buf->data = NULL; ! 47: buf->size = 0; ! 48: } ! 49: return err; ! 50: } ! 51: ! 52: int v9fs_co_statfs(V9fsPDU *pdu, V9fsPath *path, struct statfs *stbuf) ! 53: { ! 54: int err; ! 55: V9fsState *s = pdu->s; ! 56: ! 57: if (v9fs_request_cancelled(pdu)) { ! 58: return -EINTR; ! 59: } ! 60: v9fs_path_read_lock(s); ! 61: v9fs_co_run_in_worker( ! 62: { ! 63: err = s->ops->statfs(&s->ctx, path, stbuf); ! 64: if (err < 0) { ! 65: err = -errno; ! 66: } ! 67: }); ! 68: v9fs_path_unlock(s); ! 69: return err; ! 70: } ! 71: ! 72: int v9fs_co_chmod(V9fsPDU *pdu, V9fsPath *path, mode_t mode) ! 73: { ! 74: int err; ! 75: FsCred cred; ! 76: V9fsState *s = pdu->s; ! 77: ! 78: if (v9fs_request_cancelled(pdu)) { ! 79: return -EINTR; ! 80: } ! 81: cred_init(&cred); ! 82: cred.fc_mode = mode; ! 83: v9fs_path_read_lock(s); ! 84: v9fs_co_run_in_worker( ! 85: { ! 86: err = s->ops->chmod(&s->ctx, path, &cred); ! 87: if (err < 0) { ! 88: err = -errno; ! 89: } ! 90: }); ! 91: v9fs_path_unlock(s); ! 92: return err; ! 93: } ! 94: ! 95: int v9fs_co_utimensat(V9fsPDU *pdu, V9fsPath *path, ! 96: struct timespec times[2]) ! 97: { ! 98: int err; ! 99: V9fsState *s = pdu->s; ! 100: ! 101: if (v9fs_request_cancelled(pdu)) { ! 102: return -EINTR; ! 103: } ! 104: v9fs_path_read_lock(s); ! 105: v9fs_co_run_in_worker( ! 106: { ! 107: err = s->ops->utimensat(&s->ctx, path, times); ! 108: if (err < 0) { ! 109: err = -errno; ! 110: } ! 111: }); ! 112: v9fs_path_unlock(s); ! 113: return err; ! 114: } ! 115: ! 116: int v9fs_co_chown(V9fsPDU *pdu, V9fsPath *path, uid_t uid, gid_t gid) ! 117: { ! 118: int err; ! 119: FsCred cred; ! 120: V9fsState *s = pdu->s; ! 121: ! 122: if (v9fs_request_cancelled(pdu)) { ! 123: return -EINTR; ! 124: } ! 125: cred_init(&cred); ! 126: cred.fc_uid = uid; ! 127: cred.fc_gid = gid; ! 128: v9fs_path_read_lock(s); ! 129: v9fs_co_run_in_worker( ! 130: { ! 131: err = s->ops->chown(&s->ctx, path, &cred); ! 132: if (err < 0) { ! 133: err = -errno; ! 134: } ! 135: }); ! 136: v9fs_path_unlock(s); ! 137: return err; ! 138: } ! 139: ! 140: int v9fs_co_truncate(V9fsPDU *pdu, V9fsPath *path, off_t size) ! 141: { ! 142: int err; ! 143: V9fsState *s = pdu->s; ! 144: ! 145: if (v9fs_request_cancelled(pdu)) { ! 146: return -EINTR; ! 147: } ! 148: v9fs_path_read_lock(s); ! 149: v9fs_co_run_in_worker( ! 150: { ! 151: err = s->ops->truncate(&s->ctx, path, size); ! 152: if (err < 0) { ! 153: err = -errno; ! 154: } ! 155: }); ! 156: v9fs_path_unlock(s); ! 157: return err; ! 158: } ! 159: ! 160: int v9fs_co_mknod(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, uid_t uid, ! 161: gid_t gid, dev_t dev, mode_t mode, struct stat *stbuf) ! 162: { ! 163: int err; ! 164: V9fsPath path; ! 165: FsCred cred; ! 166: V9fsState *s = pdu->s; ! 167: ! 168: if (v9fs_request_cancelled(pdu)) { ! 169: return -EINTR; ! 170: } ! 171: cred_init(&cred); ! 172: cred.fc_uid = uid; ! 173: cred.fc_gid = gid; ! 174: cred.fc_mode = mode; ! 175: cred.fc_rdev = dev; ! 176: v9fs_path_read_lock(s); ! 177: v9fs_co_run_in_worker( ! 178: { ! 179: err = s->ops->mknod(&s->ctx, &fidp->path, name->data, &cred); ! 180: if (err < 0) { ! 181: err = -errno; ! 182: } else { ! 183: v9fs_path_init(&path); ! 184: err = v9fs_name_to_path(s, &fidp->path, name->data, &path); ! 185: if (!err) { ! 186: err = s->ops->lstat(&s->ctx, &path, stbuf); ! 187: if (err < 0) { ! 188: err = -errno; ! 189: } ! 190: } ! 191: v9fs_path_free(&path); ! 192: } ! 193: }); ! 194: v9fs_path_unlock(s); ! 195: return err; ! 196: } ! 197: ! 198: /* Only works with path name based fid */ ! 199: int v9fs_co_remove(V9fsPDU *pdu, V9fsPath *path) ! 200: { ! 201: int err; ! 202: V9fsState *s = pdu->s; ! 203: ! 204: if (v9fs_request_cancelled(pdu)) { ! 205: return -EINTR; ! 206: } ! 207: v9fs_path_read_lock(s); ! 208: v9fs_co_run_in_worker( ! 209: { ! 210: err = s->ops->remove(&s->ctx, path->data); ! 211: if (err < 0) { ! 212: err = -errno; ! 213: } ! 214: }); ! 215: v9fs_path_unlock(s); ! 216: return err; ! 217: } ! 218: ! 219: int v9fs_co_unlinkat(V9fsPDU *pdu, V9fsPath *path, V9fsString *name, int flags) ! 220: { ! 221: int err; ! 222: V9fsState *s = pdu->s; ! 223: ! 224: if (v9fs_request_cancelled(pdu)) { ! 225: return -EINTR; ! 226: } ! 227: v9fs_path_read_lock(s); ! 228: v9fs_co_run_in_worker( ! 229: { ! 230: err = s->ops->unlinkat(&s->ctx, path, name->data, flags); ! 231: if (err < 0) { ! 232: err = -errno; ! 233: } ! 234: }); ! 235: v9fs_path_unlock(s); ! 236: return err; ! 237: } ! 238: ! 239: /* Only work with path name based fid */ ! 240: int v9fs_co_rename(V9fsPDU *pdu, V9fsPath *oldpath, V9fsPath *newpath) ! 241: { ! 242: int err; ! 243: V9fsState *s = pdu->s; ! 244: ! 245: if (v9fs_request_cancelled(pdu)) { ! 246: return -EINTR; ! 247: } ! 248: v9fs_co_run_in_worker( ! 249: { ! 250: err = s->ops->rename(&s->ctx, oldpath->data, newpath->data); ! 251: if (err < 0) { ! 252: err = -errno; ! 253: } ! 254: }); ! 255: return err; ! 256: } ! 257: ! 258: int v9fs_co_renameat(V9fsPDU *pdu, V9fsPath *olddirpath, V9fsString *oldname, ! 259: V9fsPath *newdirpath, V9fsString *newname) ! 260: { ! 261: int err; ! 262: V9fsState *s = pdu->s; ! 263: ! 264: if (v9fs_request_cancelled(pdu)) { ! 265: return -EINTR; ! 266: } ! 267: v9fs_co_run_in_worker( ! 268: { ! 269: err = s->ops->renameat(&s->ctx, olddirpath, oldname->data, ! 270: newdirpath, newname->data); ! 271: if (err < 0) { ! 272: err = -errno; ! 273: } ! 274: }); ! 275: return err; ! 276: } ! 277: ! 278: int v9fs_co_symlink(V9fsPDU *pdu, V9fsFidState *dfidp, V9fsString *name, ! 279: const char *oldpath, gid_t gid, struct stat *stbuf) ! 280: { ! 281: int err; ! 282: FsCred cred; ! 283: V9fsPath path; ! 284: V9fsState *s = pdu->s; ! 285: ! 286: if (v9fs_request_cancelled(pdu)) { ! 287: return -EINTR; ! 288: } ! 289: cred_init(&cred); ! 290: cred.fc_uid = dfidp->uid; ! 291: cred.fc_gid = gid; ! 292: cred.fc_mode = 0777; ! 293: v9fs_path_read_lock(s); ! 294: v9fs_co_run_in_worker( ! 295: { ! 296: err = s->ops->symlink(&s->ctx, oldpath, &dfidp->path, ! 297: name->data, &cred); ! 298: if (err < 0) { ! 299: err = -errno; ! 300: } else { ! 301: v9fs_path_init(&path); ! 302: err = v9fs_name_to_path(s, &dfidp->path, name->data, &path); ! 303: if (!err) { ! 304: err = s->ops->lstat(&s->ctx, &path, stbuf); ! 305: if (err < 0) { ! 306: err = -errno; ! 307: } ! 308: } ! 309: v9fs_path_free(&path); ! 310: } ! 311: }); ! 312: v9fs_path_unlock(s); ! 313: return err; ! 314: } ! 315: ! 316: /* ! 317: * For path name based fid we don't block. So we can ! 318: * directly call the fs driver ops. ! 319: */ ! 320: int v9fs_co_name_to_path(V9fsPDU *pdu, V9fsPath *dirpath, ! 321: const char *name, V9fsPath *path) ! 322: { ! 323: int err; ! 324: V9fsState *s = pdu->s; ! 325: ! 326: if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { ! 327: err = s->ops->name_to_path(&s->ctx, dirpath, name, path); ! 328: if (err < 0) { ! 329: err = -errno; ! 330: } ! 331: } else { ! 332: if (v9fs_request_cancelled(pdu)) { ! 333: return -EINTR; ! 334: } ! 335: v9fs_co_run_in_worker( ! 336: { ! 337: err = s->ops->name_to_path(&s->ctx, dirpath, name, path); ! 338: if (err < 0) { ! 339: err = -errno; ! 340: } ! 341: }); ! 342: } ! 343: return err; ! 344: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.