Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 146 lines 2.7 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fusectl test file-system 4 * Creates a simple FUSE filesystem with a single read-write file (/test) 5 */ 6 7#define FUSE_USE_VERSION 26 8 9#include <fuse.h> 10#include <stdio.h> 11#include <string.h> 12#include <errno.h> 13#include <fcntl.h> 14#include <stdlib.h> 15#include <unistd.h> 16 17#define MAX(a, b) ((a) > (b) ? (a) : (b)) 18 19static char *content; 20static size_t content_size = 0; 21static const char test_path[] = "/test"; 22 23static int test_getattr(const char *path, struct stat *st) 24{ 25 memset(st, 0, sizeof(*st)); 26 27 if (!strcmp(path, "/")) { 28 st->st_mode = S_IFDIR | 0755; 29 st->st_nlink = 2; 30 return 0; 31 } 32 33 if (!strcmp(path, test_path)) { 34 st->st_mode = S_IFREG | 0664; 35 st->st_nlink = 1; 36 st->st_size = content_size; 37 return 0; 38 } 39 40 return -ENOENT; 41} 42 43static int test_readdir(const char *path, void *buf, fuse_fill_dir_t filler, 44 off_t offset, struct fuse_file_info *fi) 45{ 46 if (strcmp(path, "/")) 47 return -ENOENT; 48 49 filler(buf, ".", NULL, 0); 50 filler(buf, "..", NULL, 0); 51 filler(buf, test_path + 1, NULL, 0); 52 53 return 0; 54} 55 56static int test_open(const char *path, struct fuse_file_info *fi) 57{ 58 if (strcmp(path, test_path)) 59 return -ENOENT; 60 61 return 0; 62} 63 64static int test_read(const char *path, char *buf, size_t size, off_t offset, 65 struct fuse_file_info *fi) 66{ 67 if (strcmp(path, test_path) != 0) 68 return -ENOENT; 69 70 if (!content || content_size == 0) 71 return 0; 72 73 if (offset >= content_size) 74 return 0; 75 76 if (offset + size > content_size) 77 size = content_size - offset; 78 79 memcpy(buf, content + offset, size); 80 81 return size; 82} 83 84static int test_write(const char *path, const char *buf, size_t size, 85 off_t offset, struct fuse_file_info *fi) 86{ 87 size_t new_size; 88 89 if (strcmp(path, test_path) != 0) 90 return -ENOENT; 91 92 if(offset > content_size) 93 return -EINVAL; 94 95 new_size = MAX(offset + size, content_size); 96 97 if (new_size > content_size) 98 content = realloc(content, new_size); 99 100 content_size = new_size; 101 102 if (!content) 103 return -ENOMEM; 104 105 memcpy(content + offset, buf, size); 106 107 return size; 108} 109 110static int test_truncate(const char *path, off_t size) 111{ 112 if (strcmp(path, test_path) != 0) 113 return -ENOENT; 114 115 if (size == 0) { 116 free(content); 117 content = NULL; 118 content_size = 0; 119 return 0; 120 } 121 122 content = realloc(content, size); 123 124 if (!content) 125 return -ENOMEM; 126 127 if (size > content_size) 128 memset(content + content_size, 0, size - content_size); 129 130 content_size = size; 131 return 0; 132} 133 134static struct fuse_operations memfd_ops = { 135 .getattr = test_getattr, 136 .readdir = test_readdir, 137 .open = test_open, 138 .read = test_read, 139 .write = test_write, 140 .truncate = test_truncate, 141}; 142 143int main(int argc, char *argv[]) 144{ 145 return fuse_main(argc, argv, &memfd_ops, NULL); 146}