embox

Форк
0
/
initfs_inode_ops.c 
120 строк · 2.3 Кб
1
/**
2
 * @
3
 *
4
 * @date Dec 23, 2019
5
 * @author Anton Bondarev
6
 */
7

8
#include <util/log.h>
9

10
#include <cpio.h>
11
#include <errno.h>
12
#include <stddef.h>
13
#include <string.h>
14
#include <assert.h>
15

16
#include <fs/dir_context.h>
17

18
#include <fs/inode.h>
19

20
#include "initfs.h"
21

22
extern int initfs_fillname(struct inode *inode, char *buf);
23

24
static int initfs_alloc_inode_priv(struct inode *node) {
25
	struct initfs_file_info *fi;
26

27
	if (inode_priv(node)) {
28
		return 0;
29
	}
30

31
	fi = initfs_alloc_inode();
32
	if (!fi) {
33
		return -ENOMEM;
34
	}
35
	memset(fi, 0, sizeof(*fi));
36

37
	inode_priv_set(node, fi);
38

39
	return 0;
40
}
41

42
struct inode *initfs_lookup(struct inode *node, char const *name, struct inode const *dir) {
43
	extern char _initfs_start;
44
	char *cpio = &_initfs_start;
45
	struct cpio_entry entry;
46
	struct initfs_file_info *fi = inode_priv(dir);
47

48
	while ((cpio = cpio_parse_entry(cpio, &entry))) {
49
		if (fi->path && memcmp(fi->path, entry.name, fi->path_len)) {
50
			continue;
51
		}
52
		if (!strcmp(name,
53
		             entry.name + fi->path_len + (*(entry.name + fi->path_len) == '/' ? 1 : 0)) &&
54
			strrchr(entry.name + fi->path_len + 1, '/') == NULL) {
55

56
			if (!S_ISDIR(entry.mode) && !S_ISREG(entry.mode)) {
57
				log_error("Unknown inode type in cpio\n");
58
				break;
59
			}
60

61
			if (0 > initfs_alloc_inode_priv(node)) {
62
				return NULL;
63
			}
64

65
			if (0 > initfs_fill_inode(node, cpio, &entry)) {
66
				initfs_destroy_inode(node);
67
				return NULL;
68
			}
69

70
			return node;
71
		}
72
	}
73

74
	return NULL;
75
}
76

77
int initfs_iterate(struct inode *next, char *name, struct inode *parent, struct dir_ctx *ctx) {
78
	struct cpio_entry entry;
79
	extern char _initfs_start;
80
	struct initfs_file_info *di = inode_priv(parent);
81
	char *cpio = ctx->fs_ctx;
82
	char *prev;
83

84
	assert(di);
85

86
	if (!cpio) {
87
		cpio = &_initfs_start;
88
	}
89

90
	while ((prev = cpio, cpio = cpio_parse_entry(cpio, &entry))) {
91
		if (di->path && memcmp(di->path, entry.name, di->path_len)) {
92
			continue;
93
		}
94
		if (entry.name[di->path_len] != '\0' &&
95
			strrchr(entry.name + di->path_len + 1, '/') == NULL) {
96

97
			if (!S_ISDIR(entry.mode) && !S_ISREG(entry.mode)) {
98
				log_error("Unknown inode type in cpio\n");
99
				break;
100
			}
101

102
			if (0 > initfs_alloc_inode_priv(next)) {
103
				return -1;
104
			}
105

106
			if (0 > initfs_fill_inode(next, prev, &entry)) {
107
				initfs_destroy_inode(next);
108
				return -1;
109
			}
110

111
			initfs_fillname(next, name);
112
			ctx->fs_ctx = cpio;
113

114
			return 0;
115
		}
116
	}
117

118
	/* End of directory */
119
	return -1;
120
}
121

122

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

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

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

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