embox

Форк
0
/
inode.c 
267 строк · 5.6 Кб
1
/**
2
 * @brief
3
 *
4
 * @date 02.01.24
5
 * @author Aleksey Zhmulin
6
 */
7

8
#include <assert.h>
9
#include <fcntl.h>
10
#include <stdbool.h>
11
#include <string.h>
12
#include <sys/stat.h>
13
#include <sys/types.h>
14
#include <time.h>
15
#include <unistd.h>
16

17
#include <kernel/spinlock.h>
18
#include <kernel/thread/sync/mutex.h>
19
#include <lib/libds/dlist.h>
20
#include <util/err.h>
21
#include <vfs/core.h>
22

23
struct idesc;
24
struct block_dev;
25

26
static struct mutex inode_mutex = MUTEX_INIT(inode_mutex);
27

28
void vfs_inode_ops_lock(void) {
29
	mutex_lock(&inode_mutex);
30
}
31

32
void vfs_inode_ops_unlock(void) {
33
	mutex_unlock(&inode_mutex);
34
}
35

36
void vfs_inode_get_root(struct inode *inode) {
37
	assert(inode);
38

39
	inode->ino = VFS_MPT_INO;
40
	inode->sb = vfs_get_rootfs();
41
}
42

43
bool vfs_inode_is_root(const struct inode *inode) {
44
	struct inode root;
45

46
	assert(inode);
47
	assert(inode->sb);
48

49
	vfs_inode_get_root(&root);
50

51
	return (inode->ino == root.ino) && (inode->sb == root.sb);
52
}
53

54
bool vfs_inode_is_bad(const struct inode *inode) {
55
	assert(inode);
56
	assert(inode->sb);
57

58
	return inode->ino == VFS_BAD_INO;
59
}
60

61
bool vfs_inode_is_mount_point(const struct inode *inode) {
62
	assert(inode);
63
	assert(inode->sb);
64

65
	return inode->ino == VFS_MPT_INO;
66
}
67

68
bool vfs_inode_is_normal(const struct inode *inode) {
69
	assert(inode);
70
	assert(inode->sb);
71

72
	return (inode->ino != VFS_BAD_INO) && (inode->ino != VFS_MPT_INO);
73
}
74

75
bool vfs_inode_is_modified(const struct inode *inode, struct timespec *old) {
76
	struct timespec mtime;
77

78
	assert(!vfs_inode_is_bad(inode));
79

80
	vfs_inode_get_mtime(inode, &mtime);
81

82
	return (mtime.tv_sec != old->tv_sec) || (mtime.tv_nsec != old->tv_nsec);
83
}
84

85
bool vfs_inode_is_directory(const struct inode *inode) {
86
	assert(!vfs_inode_is_bad(inode));
87

88
	return vfs_inode_is_mount_point(inode)
89
	       || S_ISDIR(vfs_inode_get_mode(inode));
90
}
91

92
void vfs_inode_init(const struct inode *inode, mode_t mode) {
93
	struct inode_info info;
94

95
	clock_gettime(CLOCK_REALTIME, &info.mtime);
96
	info.owner = getuid();
97
	info.group = getgid();
98
	info.mode = mode;
99

100
	vfs_inode_save_info(inode, &info);
101
}
102

103
void vfs_inode_load_info(const struct inode *inode, struct inode_info *info) {
104
	assert(!vfs_inode_is_bad(inode));
105

106
	if (vfs_inode_is_mount_point(inode)) {
107
		memcpy(info, &inode->sb->info, sizeof(struct inode_info));
108
	}
109
	else {
110
		inode->sb->drv->ops.load_info(inode, info);
111
	}
112
}
113

114
void vfs_inode_save_info(const struct inode *inode,
115
    const struct inode_info *info) {
116
	assert(!vfs_inode_is_bad(inode));
117

118
	if (vfs_inode_is_mount_point(inode)) {
119
		memcpy(&inode->sb->info, info, sizeof(struct inode_info));
120
	}
121
	else {
122
		inode->sb->drv->ops.save_info(inode, info);
123
	}
124
}
125

126
void vfs_inode_get_mtime(const struct inode *inode, struct timespec *mtime) {
127
	struct inode_info info;
128

129
	vfs_inode_load_info(inode, &info);
130
	memcpy(mtime, &info.mtime, sizeof(struct timespec));
131
}
132

133
void vfs_inode_update_mtime(const struct inode *inode) {
134
	struct inode_info info;
135
	struct timespec mtime;
136

137
	clock_gettime(CLOCK_REALTIME, &mtime);
138

139
	vfs_inode_load_info(inode, &info);
140
	memcpy(&info.mtime, &mtime, sizeof(struct timespec));
141
	vfs_inode_save_info(inode, &info);
142
}
143

144
mode_t vfs_inode_get_mode(const struct inode *inode) {
145
	struct inode_info info;
146

147
	vfs_inode_load_info(inode, &info);
148

149
	return info.mode;
150
}
151

152
void vfs_inode_set_mode(const struct inode *inode, mode_t mode) {
153
	struct inode_info info;
154

155
	vfs_inode_load_info(inode, &info);
156
	info.mode &= ~S_IRWXA;
157
	info.mode |= mode & S_IRWXA;
158
	vfs_inode_save_info(inode, &info);
159
}
160

161
uid_t vfs_inode_get_owner(const struct inode *inode) {
162
	struct inode_info info;
163

164
	vfs_inode_load_info(inode, &info);
165

166
	return info.owner;
167
}
168

169
void vfs_inode_set_owner(const struct inode *inode, uid_t owner) {
170
	struct inode_info info;
171

172
	vfs_inode_load_info(inode, &info);
173
	info.owner = owner;
174
	vfs_inode_save_info(inode, &info);
175
}
176

177
gid_t vfs_inode_get_group(const struct inode *inode) {
178
	struct inode_info info;
179

180
	vfs_inode_load_info(inode, &info);
181

182
	return info.owner;
183
}
184

185
void vfs_inode_set_group(const struct inode *inode, gid_t group) {
186
	struct inode_info info;
187

188
	vfs_inode_load_info(inode, &info);
189
	info.group = group;
190
	vfs_inode_save_info(inode, &info);
191
}
192

193
void vfs_inode_lock(const struct inode *inode) {
194
	bool normal;
195

196
	assert(!vfs_inode_is_bad(inode));
197
	assert(inode->sb->usage_count >= 0);
198

199
	normal = vfs_inode_is_normal(inode);
200

201
	spin_lock_ipl_disable(&inode->sb->lock);
202
	{
203
		inode->sb->usage_count++;
204
		if (normal && inode->sb->drv->ops.lock) {
205
			inode->sb->drv->ops.lock(inode);
206
		}
207
	}
208
	spin_unlock_ipl_enable(&inode->sb->lock);
209
}
210

211
void vfs_inode_unlock(const struct inode *inode) {
212
	bool normal;
213

214
	assert(!vfs_inode_is_bad(inode));
215
	assert(inode->sb->usage_count > 0);
216

217
	normal = vfs_inode_is_normal(inode);
218

219
	spin_lock_ipl_disable(&inode->sb->lock);
220
	{
221
		inode->sb->usage_count--;
222
		if (normal && inode->sb->drv->ops.unlock) {
223
			inode->sb->drv->ops.unlock(inode);
224
		}
225
	}
226
	spin_unlock_ipl_enable(&inode->sb->lock);
227
}
228

229
bool vfs_inode_is_available(const struct inode *inode, int access_mode) {
230
	struct inode_info info;
231
	bool write_access;
232
	bool read_access;
233

234
	vfs_inode_load_info(inode, &info);
235

236
	if (info.owner == getuid()) {
237
		write_access = info.mode & S_IRUSR;
238
		read_access = info.mode & S_IWUSR;
239
	}
240
	else if (info.group == getgid()) {
241
		write_access = info.mode & S_IRGRP;
242
		read_access = info.mode & S_IWGRP;
243
	}
244
	else {
245
		write_access = info.mode & S_IROTH;
246
		read_access = info.mode & S_IWOTH;
247
	}
248

249
	switch (access_mode & O_ACCESS_MASK) {
250
	case O_RDONLY:
251
		return read_access;
252

253
	case O_WRONLY:
254
		return write_access;
255

256
	default:
257
		return read_access & write_access;
258
	}
259
}
260

261
struct idesc *vfs_inode_open(const struct inode *inode, int oflag) {
262
	if (!vfs_inode_is_available(inode, oflag)) {
263
		return err2ptr(EACCES);
264
	}
265

266
	return inode->sb->drv->ops.open(inode, oflag);
267
}
268

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

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

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

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