-
Notifications
You must be signed in to change notification settings - Fork 2
/
ext2_fuse.c
112 lines (87 loc) · 2.58 KB
/
ext2_fuse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "ext2_fuse.h"
#include "ext2_helpers.h"
#include "ext2_common.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
static inline struct ext2_fuse_context* ext2_get_context()
{
return (struct ext2_fuse_context*)fuse_get_context()->private_data;
}
static inline struct ext2_description* ext2_get_description()
{
return &ext2_get_context()->d;
}
int ext2_fuse_getattr(const char* path, struct stat* stbuf, struct fuse_file_info* file_info)
{
printf("getattr, path:%s\n", path);
const struct ext2_description* d = ext2_get_description();
const int i = ext2_get_inode(d, path);
if(i != 0)
{
struct ext2_inode inode;
ext2_read_inode(d, i, &inode);
stbuf->st_ino = i;
stbuf->st_size = inode.i_size;
stbuf->st_mode = inode.i_mode;
stbuf->st_nlink = inode.i_links_count;
stbuf->st_uid = inode.i_uid;
stbuf->st_gid = inode.i_gid;
stbuf->st_blksize = d->block_size;
return 0;
}
else
return -ENOENT;
}
int ext2_fuse_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* file_info, enum fuse_readdir_flags flags)
{
printf("readdir, path:%s\n", path);
const struct ext2_description* d = ext2_get_description();
const int i = ext2_get_inode(d, path);
if(i!= 0)
{
struct ext2_inode inode;
ext2_read_inode(d, i, &inode);
if((inode.i_mode & EXT2_FT_MASK) == EXT2_FT_DIR)
{
const size_t data_size = ext2_get_data_size(d, &inode);
uint8_t* blocks = calloc(data_size, 1);
ext2_read_blocks(d, &inode, blocks);
struct ext2_dir_entry* de_root = ext2_get_dir_entries(d, blocks);
for(struct ext2_dir_entry* de = de_root; de != NULL; de = de->next)
filler(buf, de->name, NULL, 0, 0);
free(blocks);
ext2_free_dir_entries(de_root);
}
else
return 0;
}
else
return -ENOENT;
return 0;
}
int ext2_fuse_open(const char* path, struct fuse_file_info* file_info)
{
printf("open, path:%s\n", path);
return 0;
}
int ext2_fuse_read(const char* path, char* buffer, size_t read_size, off_t offset, struct fuse_file_info* file_info)
{
printf("read, path:%s\n", path);
const struct ext2_description* d = ext2_get_description();
const int i = ext2_get_inode(d, path);
if(i!= 0)
{
struct ext2_inode inode;
ext2_read_inode(d, i, &inode);
const size_t data_size = ext2_get_data_size(d, &inode);
uint8_t* blocks = calloc(data_size, 1);
ext2_read_blocks(d, &inode, blocks);
const size_t size_to_read = inode.i_size > offset + read_size ? read_size : inode.i_size - offset;
memmove(buffer + offset, blocks + offset, size_to_read);
free(blocks);
return size_to_read;
}
else
return -ENOENT;
}