embox

Форк
0
/
dvfs_kfile.c 
157 строк · 3.1 Кб
1
/**
2
 * @file
3
 * @brief  DVFS interface implementation
4
 * @author Denis Deryugin
5
 * @date   11 Mar 2014
6
 */
7

8
#include <assert.h>
9
#include <errno.h>
10
#include <stddef.h>
11

12
#include <drivers/block_dev.h> /* block_dev_block_size */
13
#include <fs/dentry.h>
14
#include <fs/file_desc.h>
15
#include <fs/kfile.h>
16
#include <fs/dvfs.h>
17

18
#include <util/math.h>
19

20
/**
21
 * @brief Uninitialize file descriptor
22
 * @param desc File descriptor to be uninitialized
23
 *
24
 * @return Negative error code
25
 * @retval  0 Ok
26
 * @retval -1 Descriptor fields are inconsistent
27
 */
28
int kclose(struct file_desc *desc) {
29
	if (!desc || !desc->f_inode || !desc->f_dentry)
30
		return -1;
31

32
	if (!(desc->f_dentry->flags & VFS_DIR_VIRTUAL)) {
33
		assert(desc->f_ops);
34
	}
35

36
	if (desc->f_ops && desc->f_ops->close) {
37
		desc->f_ops->close(desc);
38
	}
39

40
	if (!dentry_ref_dec(desc->f_dentry))
41
		dvfs_destroy_dentry(desc->f_dentry);
42

43
	dvfs_destroy_file(desc);
44
	return 0;
45
}
46

47
/**
48
 * @brief Application level interface to write the file
49
 * @param desc  File to be written
50
 * @param buf   Source of the data
51
 * @param count Length of the data
52
 *
53
 * @return Bytes written or negative error code
54
 * @retval       0 Ok
55
 * @retval -ENOSYS Function is not implemented in file system driver
56
 */
57
int kwrite(struct file_desc *desc, char *buf, int count) {
58
	int res = 0; /* Assign to avoid compiler warning when use -O2 */
59
	int retcode = count;
60
	struct inode *inode;
61

62
	if (!desc) {
63
		return -EINVAL;
64
	}
65

66
	inode = desc->f_inode;
67
	assert(inode);
68

69
	if (!(inode->i_mode & DVFS_NO_LSEEK)
70
	    && ((inode->i_size - desc->f_pos) < count)) {
71
		if (inode->i_ops && inode->i_ops->ino_truncate) {
72
			res = inode->i_ops->ino_truncate(desc->f_inode, desc->f_pos + count);
73
			if (res) {
74
				retcode = -EFBIG;
75
			}
76
		}
77
		else {
78
			retcode = -EFBIG;
79
		}
80
	}
81

82
	if (desc->f_ops && desc->f_ops->write) {
83
		res = desc->f_ops->write(desc, buf, count);
84
	}
85
	else {
86
		retcode = -ENOSYS;
87
	}
88

89
	if (res > 0) {
90
		desc->f_pos += res;
91
	}
92

93
	return retcode;
94
}
95

96
/**
97
 * @brief Application level interface to read the file
98
 * @param desc  File to be read
99
 * @param buf   Destination
100
 * @param count Length of the data
101
 *
102
 * @return Bytes read or negative error code
103
 * @retval       0 Ok
104
 * @retval -ENOSYS Function is not implemented in file system driver
105
 */
106
int kread(struct file_desc *desc, char *buf, int count) {
107
	int res;
108
	int sz;
109

110
	if (!desc) {
111
		return -1;
112
	}
113

114
	sz = min(count, desc->f_inode->i_size - desc->f_pos);
115

116
	if (sz <= 0) {
117
		return 0;
118
	}
119

120
	if (desc->f_ops && desc->f_ops->read) {
121
		res = desc->f_ops->read(desc, buf, count);
122
	}
123
	else {
124
		return -ENOSYS;
125
	}
126

127
	if (res > 0) {
128
		desc->f_pos += res;
129
	}
130

131
	return res;
132
}
133

134
int kfstat(struct file_desc *desc, struct stat *sb) {
135
	size_t block_size;
136

137
	*sb = (struct stat){
138
	    .st_size = desc->f_inode->i_size,
139
	    .st_mode = desc->f_inode->i_mode,
140
	    .st_uid = 0,
141
	    .st_gid = 0,
142
	};
143

144
	sb->st_blocks = sb->st_size;
145

146
	if (desc->f_inode->i_sb->bdev) {
147
		block_size = block_dev_block_size(desc->f_inode->i_sb->bdev);
148
		sb->st_blocks /= block_size;
149
		sb->st_blocks += ((sb->st_blocks % block_size) != 0);
150
	}
151

152
	return 0;
153
}
154

155
int kioctl(struct file_desc *fp, int request, void *data) {
156
	return fp->f_ops->ioctl(fp, request, data);
157
}
158

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

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

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

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