diff --git a/vmdk/sparse.c b/vmdk/sparse.c index b36731f..f2aefe0 100644 --- a/vmdk/sparse.c +++ b/vmdk/sparse.c @@ -810,8 +810,8 @@ SparsePread(DiskInfo *self, break; } readLen = grainSize - readSkip; - if (len < readLen) - readLen = len; + if (len < readLen) + readLen = len; sect = __le32_to_cpu(sdi->gtInfo.gt[grainNr]); if (sect == 0) { diff --git a/vmdk/vmdk-fuse.c b/vmdk/vmdk-fuse.c index e7ea6a6..707acd7 100644 --- a/vmdk/vmdk-fuse.c +++ b/vmdk/vmdk-fuse.c @@ -1,6 +1,7 @@ /* FUSE: Filesystem in Userspace Copyright (C) 2001-2007 Miklos Szeredi + Copyright (C) 2014 Broadcom This program can be distributed under the terms of the GNU GPLv2. See the file COPYING. @@ -9,16 +10,7 @@ /** @file * * This "filesystem" provides only a single file. The mountpoint - * needs to be a file rather than a directory. All writes to the - * file will be discarded, and reading the file always returns - * \0. - * - * Compile with: - * - * gcc -Wall null.c `pkg-config fuse3 --cflags --libs` -o null - * - * ## Source code ## - * \include passthrough_fh.c + * needs to be a file rather than a directory. */ @@ -55,25 +47,25 @@ struct vmdk_data { }; static int vmdk_getattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi) + struct fuse_file_info *fi) { (void) fi; struct stat st; struct vmdk_data *data = (struct vmdk_data *)fuse_get_context()->private_data; char *vmdk_path = data->options.vmdk_path; - if(strcmp(path, "/") != 0) - return -ENOENT; + if(strcmp(path, "/") != 0) + return -ENOENT; stat(vmdk_path, &st); - stbuf->st_mode = st.st_mode; - stbuf->st_nlink = 1; - stbuf->st_uid = getuid(); - stbuf->st_gid = getgid(); - stbuf->st_size = data->capacity; - stbuf->st_blocks = 0; - stbuf->st_atime = st.st_atime; + stbuf->st_mode = st.st_mode; + stbuf->st_nlink = 1; + stbuf->st_uid = getuid(); + stbuf->st_gid = getgid(); + stbuf->st_size = data->capacity; + stbuf->st_blocks = 0; + stbuf->st_atime = st.st_atime; stbuf->st_mtime = st.st_mtime; stbuf->st_ctime = st.st_ctime; @@ -81,63 +73,88 @@ static int vmdk_getattr(const char *path, struct stat *stbuf, } static int vmdk_truncate(const char *path, off_t size, - struct fuse_file_info *fi) + struct fuse_file_info *fi) { - (void) size; - (void) fi; + (void) size; + (void) fi; - if(strcmp(path, "/") != 0) - return -ENOENT; + if(strcmp(path, "/") != 0) + return -ENOENT; - return 0; + return -EROFS; } static int vmdk_open(const char *path, struct fuse_file_info *fi) { - (void) fi; + (void) fi; + + if(strcmp(path, "/") != 0) + return -ENOENT; - if(strcmp(path, "/") != 0) - return -ENOENT; + struct vmdk_data *data = (struct vmdk_data *)fuse_get_context()->private_data; + DiskInfo *di = Sparse_Open(data->options.vmdk_path); + if (di == NULL) { + fprintf(stderr, "could not read %s\n", data->options.vmdk_path); + return -EIO; + } + + fi->fh = (uint64_t)di; return 0; } +static int vmdk_release(const char *path, struct fuse_file_info *fi) +{ + if(strcmp(path, "/") != 0) + return -ENOENT; + + DiskInfo *di = (DiskInfo *)(fi->fh); + if (di == NULL) + return -EIO; + + di->vmt->close(di); + + return 0; +} + static int vmdk_read(const char *path, char *buf, size_t size, - off_t offset, struct fuse_file_info *fi) + off_t offset, struct fuse_file_info *fi) { - (void) buf; - (void) offset; - (void) fi; + if(strcmp(path, "/") != 0) + return -ENOENT; - if(strcmp(path, "/") != 0) - return -ENOENT; + DiskInfo *di = (DiskInfo *)(fi->fh); + if (di == NULL) + return -EIO; - if (offset >= (1ULL << 32)) - return 0; + if (di->vmt->pread(di, (void *)buf, size, offset) != (ssize_t)size) { + return -EIO; + } - memset(buf, 0, size); - return size; + return size; } static int vmdk_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - (void) buf; - (void) offset; - (void) fi; + (void) buf; + (void) offset; + (void) fi; + (void) size; - if(strcmp(path, "/") != 0) - return -ENOENT; + if(strcmp(path, "/") != 0) + return -ENOENT; - return size; + return -EROFS; } static const struct fuse_operations vmdk_oper = { - .getattr = vmdk_getattr, - .truncate = vmdk_truncate, - .open = vmdk_open, - .read = vmdk_read, - .write = vmdk_write, + .getattr = vmdk_getattr, + .truncate = vmdk_truncate, + .open = vmdk_open, + .release = vmdk_release, + .read = vmdk_read, + .write = vmdk_write, }; int vmdk_init(struct vmdk_data *data) @@ -158,57 +175,41 @@ int vmdk_init(struct vmdk_data *data) int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - struct fuse_cmdline_opts opts; struct stat stbuf; struct vmdk_data data = {0}; + int argc_saved; + char **argv_saved; if (fuse_opt_parse(&args, &data.options, option_spec, NULL) == -1) return 1; if (!data.options.vmdk_path) { - fprintf(stderr, "missing vmdk file parameter (file=)\n"); - return 1; + fprintf(stderr, "missing vmdk file parameter (file=)\n"); + return 1; } else { char *tmp = data.options.vmdk_path; data.options.vmdk_path = realpath(data.options.vmdk_path, NULL); free(tmp); } - if (stat(data.options.vmdk_path, &stbuf) == -1) { - fprintf(stderr ,"failed to access vmdk file %s: %s\n", - data.options.vmdk_path, strerror(errno)); - free(data.options.vmdk_path); - return 1; - } - if (!S_ISREG(stbuf.st_mode)) { - fprintf(stderr, "vmdk file %s is not a regular file\n", data.options.vmdk_path); - return 1; - } - - /* - if (fuse_parse_cmdline(&args, &opts) != 0) - return 1; - - if (!opts.mountpoint) { - fprintf(stderr, "missing mountpoint parameter\n"); - return 1; - } - if (stat(opts.mountpoint, &stbuf) == -1) { - fprintf(stderr ,"failed to access mountpoint %s: %s\n", - opts.mountpoint, strerror(errno)); - free(opts.mountpoint); - return 1; - } - if (!S_ISREG(stbuf.st_mode)) { - fprintf(stderr, "mountpoint %s is not a regular file\n", opts.mountpoint); - return 1; - } - */ + if (stat(data.options.vmdk_path, &stbuf) == -1) { + fprintf(stderr ,"failed to access vmdk file %s: %s\n", + data.options.vmdk_path, strerror(errno)); + free(data.options.vmdk_path); + return 1; + } + if (!S_ISREG(stbuf.st_mode)) { + fprintf(stderr, "vmdk file %s is not a regular file\n", data.options.vmdk_path); + return 1; + } + + argc_saved = args.argc; + argv_saved = args.argv; if (vmdk_init(&data) != 0) { return 1; } printf("before fuse_main\n"); - return fuse_main(args.argc, args.argv, &vmdk_oper, (void *)&data); + return fuse_main(argc_saved, argv_saved, &vmdk_oper, (void *)&data); }