1 /* 2 * Copyright (c) 2024, Google Inc. All rights reserved. 3 * Author: codycswong@google.com (Cody Wong) 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files 7 * (the "Software"), to deal in the Software without restriction, 8 * including without limitation the rights to use, copy, modify, merge, 9 * publish, distribute, sublicense, and/or sell copies of the Software, 10 * and to permit persons to whom the Software is furnished to do so, 11 * subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 #include <dev/virtio/9p.h> 25 #include <lib/fs.h> 26 #include <lk/list.h> 27 #include <kernel/mutex.h> 28 29 typedef struct v9fs_fid { 30 uint32_t fid; 31 uint32_t iounit; 32 virtio_9p_qid_t qid; 33 } v9fs_fid_t; 34 35 typedef struct v9fs { 36 struct virtio_device *dev; 37 bdev_t *bdev; 38 39 uint32_t unused_fid; 40 v9fs_fid_t root; 41 mutex_t lock; 42 43 struct list_node files; 44 struct list_node dirs; 45 } v9fs_t; 46 47 #define V9FS_FILE_PAGE_BUFFER_SIZE (1 << 12) 48 #define V9FS_FILE_LOCK_TIMEOUT 3000 49 50 typedef struct v9fs_file { 51 v9fs_t *v9fs; 52 v9fs_fid_t fid; 53 54 struct list_node node; 55 mutex_t lock; 56 57 struct fs_page_buffer { 58 size_t size; 59 off_t index; 60 bool need_update; 61 bool dirty; 62 uint8_t data[V9FS_FILE_PAGE_BUFFER_SIZE]; 63 } pg_buf; 64 } v9fs_file_t; 65 66 typedef struct v9fs_dir { 67 v9fs_t *v9fs; 68 v9fs_fid_t fid; 69 uint64_t offset; 70 71 uint32_t head; 72 uint32_t tail; 73 uint8_t data[PAGE_SIZE]; 74 75 struct list_node node; 76 } v9fs_dir_t; 77 78 status_t v9fs_mount(bdev_t *dev, fscookie **cookie); 79 status_t v9fs_unmount(fscookie *cookie); 80 status_t v9fs_open_file(fscookie *cookie, const char *path, 81 filecookie **fcookie); 82 status_t v9fs_create_file(fscookie *cookie, const char *path, 83 filecookie **fcookie, uint64_t len); 84 ssize_t v9fs_read_file(filecookie *fcookie, void *buf, off_t offset, 85 size_t len); 86 ssize_t v9fs_write_file(filecookie *fcookie, const void *buf, off_t offset, 87 size_t len); 88 status_t v9fs_close_file(filecookie *fcookie); 89 status_t v9fs_stat_file(filecookie *fcookie, struct file_stat *stat); 90 status_t v9fs_open_dir(fscookie *cookie, const char *path, dircookie **dcookie); 91 status_t v9fs_mkdir(fscookie *cookie, const char *path); 92 status_t v9fs_read_dir(dircookie *dcookie, struct dirent *ent); 93 status_t v9fs_close_dir(dircookie *dcookie); 94 95 status_t path_to_wname(char *path, uint16_t *nwname, const char *wname[P9_MAXWELEM]) __NONNULL((1)) __NONNULL((2)); 96 uint32_t get_unused_fid(v9fs_t *v9fs); 97 void put_fid(v9fs_t *v9fs, uint32_t fid); 98