1 /* Part of libvboxfs - (c) 2012, D.C. van Moolenbroek */ 2 3 #include "inc.h" 4 5 /* 6 * We perform all file I/O using a local, intermediate buffer. While in theory 7 * it would be possible to perform direct DMA from/to the user process, this 8 * does not work in practice: on short reads, VirtualBox copies back the entire 9 * provided buffer rather than only the part actually filled, resulting in the 10 * unused part of the buffer being clobbered. Marking the buffer as bi- 11 * directional would solve this, except it would also eliminate all the 12 * zero-copy benefits for reads; in addition, it is prevented by the protection 13 * set on the given grant. 14 */ 15 16 #define VBOXFS_MAX_FILEIO 65536 /* maximum I/O chunk size */ 17 18 static char iobuf[VBOXFS_MAX_FILEIO]; 19 20 /* 21 * Open a file. 22 */ 23 int 24 vboxfs_open(const char *path, int flags, int mode, sffs_file_t *handle) 25 { 26 vboxfs_handle_t *handlep; 27 int r; 28 29 handlep = (vboxfs_handle_t *) malloc(sizeof(*handlep)); 30 31 if ((r = vboxfs_open_file(path, flags, mode, handlep, NULL)) != OK) { 32 free(handlep); 33 34 return r; 35 } 36 37 *handle = (sffs_file_t) handlep; 38 39 return OK; 40 } 41 42 /* 43 * Read or write a chunk from or to a file. 44 */ 45 static ssize_t 46 read_write(vboxfs_handle_t handle, char *buf, size_t size, u64_t pos, 47 int write) 48 { 49 vbox_param_t param[5]; 50 int r, dir, call; 51 52 dir = write ? VBOX_DIR_OUT : VBOX_DIR_IN; 53 call = write ? VBOXFS_CALL_WRITE : VBOXFS_CALL_READ; 54 55 vbox_set_u32(¶m[0], vboxfs_root); 56 vbox_set_u64(¶m[1], handle); 57 vbox_set_u64(¶m[2], pos); 58 vbox_set_u32(¶m[3], size); 59 vbox_set_ptr(¶m[4], buf, size, dir); 60 61 if ((r = vbox_call(vboxfs_conn, call, param, 5, NULL)) != OK) 62 return r; 63 64 return vbox_get_u32(¶m[3]); 65 } 66 67 /* 68 * Read from a file. 69 */ 70 ssize_t 71 vboxfs_read(sffs_file_t handle, char *buf, size_t size, u64_t pos) 72 { 73 vboxfs_handle_t *handlep; 74 75 handlep = (vboxfs_handle_t *) handle; 76 77 return read_write(*handlep, buf, size, pos, FALSE /*write*/); 78 } 79 80 /* 81 * Write to a file. 82 */ 83 ssize_t 84 vboxfs_write(sffs_file_t handle, char *buf, size_t len, u64_t pos) 85 { 86 vboxfs_handle_t *handlep; 87 88 handlep = (vboxfs_handle_t *) handle; 89 90 return read_write(*handlep, buf, len, pos, TRUE /*write*/); 91 } 92 93 /* 94 * Close a file handle. 95 */ 96 int 97 vboxfs_close(sffs_file_t handle) 98 { 99 vboxfs_handle_t *handlep; 100 101 handlep = (vboxfs_handle_t *) handle; 102 103 vboxfs_close_file(*handlep); 104 105 free(handlep); 106 107 return OK; 108 } 109 110 /* 111 * Return an internal buffer address and size for I/O operations. 112 */ 113 size_t 114 vboxfs_buffer(char **ptr) 115 { 116 117 *ptr = iobuf; 118 return sizeof(iobuf); 119 } 120