Path: blob/master/tools/testing/selftests/filesystems/fuse/fuse_mnt.c
29271 views
// SPDX-License-Identifier: GPL-2.01/*2* fusectl test file-system3* Creates a simple FUSE filesystem with a single read-write file (/test)4*/56#define FUSE_USE_VERSION 2678#include <fuse.h>9#include <stdio.h>10#include <string.h>11#include <errno.h>12#include <fcntl.h>13#include <stdlib.h>14#include <unistd.h>1516#define MAX(a, b) ((a) > (b) ? (a) : (b))1718static char *content;19static size_t content_size = 0;20static const char test_path[] = "/test";2122static int test_getattr(const char *path, struct stat *st)23{24memset(st, 0, sizeof(*st));2526if (!strcmp(path, "/")) {27st->st_mode = S_IFDIR | 0755;28st->st_nlink = 2;29return 0;30}3132if (!strcmp(path, test_path)) {33st->st_mode = S_IFREG | 0664;34st->st_nlink = 1;35st->st_size = content_size;36return 0;37}3839return -ENOENT;40}4142static int test_readdir(const char *path, void *buf, fuse_fill_dir_t filler,43off_t offset, struct fuse_file_info *fi)44{45if (strcmp(path, "/"))46return -ENOENT;4748filler(buf, ".", NULL, 0);49filler(buf, "..", NULL, 0);50filler(buf, test_path + 1, NULL, 0);5152return 0;53}5455static int test_open(const char *path, struct fuse_file_info *fi)56{57if (strcmp(path, test_path))58return -ENOENT;5960return 0;61}6263static int test_read(const char *path, char *buf, size_t size, off_t offset,64struct fuse_file_info *fi)65{66if (strcmp(path, test_path) != 0)67return -ENOENT;6869if (!content || content_size == 0)70return 0;7172if (offset >= content_size)73return 0;7475if (offset + size > content_size)76size = content_size - offset;7778memcpy(buf, content + offset, size);7980return size;81}8283static int test_write(const char *path, const char *buf, size_t size,84off_t offset, struct fuse_file_info *fi)85{86size_t new_size;8788if (strcmp(path, test_path) != 0)89return -ENOENT;9091if(offset > content_size)92return -EINVAL;9394new_size = MAX(offset + size, content_size);9596if (new_size > content_size)97content = realloc(content, new_size);9899content_size = new_size;100101if (!content)102return -ENOMEM;103104memcpy(content + offset, buf, size);105106return size;107}108109static int test_truncate(const char *path, off_t size)110{111if (strcmp(path, test_path) != 0)112return -ENOENT;113114if (size == 0) {115free(content);116content = NULL;117content_size = 0;118return 0;119}120121content = realloc(content, size);122123if (!content)124return -ENOMEM;125126if (size > content_size)127memset(content + content_size, 0, size - content_size);128129content_size = size;130return 0;131}132133static struct fuse_operations memfd_ops = {134.getattr = test_getattr,135.readdir = test_readdir,136.open = test_open,137.read = test_read,138.write = test_write,139.truncate = test_truncate,140};141142int main(int argc, char *argv[])143{144return fuse_main(argc, argv, &memfd_ops, NULL);145}146147148