-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b7a9ead
commit 30d0f97
Showing
2 changed files
with
87 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
FUSE: Filesystem in Userspace | ||
Copyright (C) 2001-2007 Miklos Szeredi <[email protected]> | ||
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,89 +47,114 @@ 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; | ||
|
||
return 0; | ||
} | ||
|
||
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); | ||
} |