embox
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*/
28int kclose(struct file_desc *desc) {29if (!desc || !desc->f_inode || !desc->f_dentry)30return -1;31
32if (!(desc->f_dentry->flags & VFS_DIR_VIRTUAL)) {33assert(desc->f_ops);34}35
36if (desc->f_ops && desc->f_ops->close) {37desc->f_ops->close(desc);38}39
40if (!dentry_ref_dec(desc->f_dentry))41dvfs_destroy_dentry(desc->f_dentry);42
43dvfs_destroy_file(desc);44return 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*/
57int kwrite(struct file_desc *desc, char *buf, int count) {58int res = 0; /* Assign to avoid compiler warning when use -O2 */59int retcode = count;60struct inode *inode;61
62if (!desc) {63return -EINVAL;64}65
66inode = desc->f_inode;67assert(inode);68
69if (!(inode->i_mode & DVFS_NO_LSEEK)70&& ((inode->i_size - desc->f_pos) < count)) {71if (inode->i_ops && inode->i_ops->ino_truncate) {72res = inode->i_ops->ino_truncate(desc->f_inode, desc->f_pos + count);73if (res) {74retcode = -EFBIG;75}76}77else {78retcode = -EFBIG;79}80}81
82if (desc->f_ops && desc->f_ops->write) {83res = desc->f_ops->write(desc, buf, count);84}85else {86retcode = -ENOSYS;87}88
89if (res > 0) {90desc->f_pos += res;91}92
93return 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*/
106int kread(struct file_desc *desc, char *buf, int count) {107int res;108int sz;109
110if (!desc) {111return -1;112}113
114sz = min(count, desc->f_inode->i_size - desc->f_pos);115
116if (sz <= 0) {117return 0;118}119
120if (desc->f_ops && desc->f_ops->read) {121res = desc->f_ops->read(desc, buf, count);122}123else {124return -ENOSYS;125}126
127if (res > 0) {128desc->f_pos += res;129}130
131return res;132}
133
134int kfstat(struct file_desc *desc, struct stat *sb) {135size_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
144sb->st_blocks = sb->st_size;145
146if (desc->f_inode->i_sb->bdev) {147block_size = block_dev_block_size(desc->f_inode->i_sb->bdev);148sb->st_blocks /= block_size;149sb->st_blocks += ((sb->st_blocks % block_size) != 0);150}151
152return 0;153}
154
155int kioctl(struct file_desc *fp, int request, void *data) {156return fp->f_ops->ioctl(fp, request, data);157}
158