embox

Форк
0
/
initfs_fops.c 
156 строк · 3.1 Кб
1
/**
2
 * @
3
 *
4
 * @date Dec 23, 2019
5
 * @author Anton Bondarev
6
 */
7
#include <cpio.h>
8
#include <errno.h>
9
#include <stddef.h>
10
#include <string.h>
11
#include <stdint.h>
12
#include <sys/types.h>
13

14
#include <fs/dir_context.h>
15
#include <fs/file_desc.h>
16
#include <fs/inode.h>
17
#include <fs/super_block.h>
18

19
#include "initfs.h"
20

21
int initfs_create(struct inode *i_new, struct inode *i_dir, int mode) {
22
	return -EACCES;
23
}
24

25
static size_t initfs_read(struct file_desc *desc, void *buf, size_t size) {
26
	struct initfs_file_info *fi;
27
	off_t pos;
28

29
	pos = file_get_pos(desc);
30
	fi = file_get_inode_data(desc);
31

32
	if (pos + size > file_get_size(desc)) {
33
		size = file_get_size(desc) - pos;
34
	}
35

36
	memcpy(buf, (char *) (uintptr_t) (fi->start_pos + pos), size);
37

38
	return size;
39
}
40

41
static int initfs_ioctl(struct file_desc *desc, int request, void *data) {
42
	char **p_addr;
43
	struct initfs_file_info *fi;
44

45
	fi = file_get_inode_data(desc);
46

47
	p_addr = data;
48

49
	*p_addr = (char*) (uintptr_t) fi->start_pos;
50

51
	return 0;
52
}
53

54
static size_t initfs_write(struct file_desc *desc, void *buf, size_t size) {
55
	return -EACCES;
56
}
57

58
struct file_operations initfs_fops = {
59
	.read  = initfs_read,
60
	.write = initfs_write,
61
	.ioctl = initfs_ioctl,
62
};
63

64
/**
65
* @brief Initialize initfs inode
66
*
67
* @param node  Structure to be initialized
68
* @param entry Information about file in cpio archieve
69
*
70
* @return Negative error code
71
*/
72
int initfs_fill_inode(struct inode *node, char *cpio,
73
		struct cpio_entry *entry) {
74
	struct initfs_file_info *fi;
75

76
	fi = inode_priv(node);
77
	assert(fi);
78

79
	inode_size_set(node, entry->size);
80
	inode_mtime_set(node, entry->mtime);
81
	node->i_mode = entry->mode & (S_IFMT | S_IRWXA);
82

83
	fi->start_pos = (uintptr_t) entry->data;
84
	fi->entry     = (void *) cpio;
85

86
	if (S_ISDIR(entry->mode)) {
87
		fi->path      = entry->name;
88
		fi->path_len  = strlen(entry->name);
89
	}
90

91
	return 0;
92
}
93

94
int initfs_fillname(struct inode *inode, char *buf) {
95
	struct cpio_entry entry;
96
	struct initfs_file_info *fi = inode_priv(inode);
97
	size_t name_len = 0;
98
	char *name;
99

100
	if (NULL == cpio_parse_entry((char *) fi->entry, &entry)) {
101
		return -1;
102
	}
103

104
	/* CPIO entry contains full path, so we need to throw away
105
	 * everything before the last '/' symbol */
106
	name = strrchr(entry.name, '/');
107
	if (name) {
108
		name++;
109
	} else {
110
		name = entry.name;
111
	}
112

113
	name_len = entry.name_len - (name - entry.name);
114

115
	memcpy(buf, name, name_len);
116
	buf[name_len] = '\0';
117

118
	return 0;
119
}
120

121
int initfs_destroy_inode(struct inode *inode) {
122
	if (inode_priv(inode) != NULL) {
123
		initfs_free_inode(inode_priv(inode));
124
	}
125

126
	return 0;
127
}
128

129
extern struct super_block_operations initfs_sbops;
130
extern struct inode_operations initfs_iops;
131

132
int initfs_fill_sb(struct super_block *sb, const char *source) {
133
	extern char _initfs_start, _initfs_end;
134
	struct initfs_file_info *fi;
135

136
	if (&_initfs_start == &_initfs_end) {
137
		return -1;
138
	}
139

140
	fi = initfs_alloc_inode();
141
	if (fi == NULL) {
142
		return -ENOMEM;
143
	}
144

145
	sb->sb_iops = &initfs_iops;
146
	sb->sb_fops = &initfs_fops;
147
	sb->sb_ops  = &initfs_sbops;
148
	sb->bdev    = NULL;
149

150
	memset(fi, 0, sizeof(struct initfs_file_info));
151
	inode_priv_set(sb->sb_root, fi);
152

153
	sb->sb_root->i_ops = &initfs_iops;
154

155
	return 0;
156
}
157

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.