source: trunk/kernel/fs/sysfs/sysfs_file.c @ 2

Last change on this file since 2 was 1, checked in by alain, 8 years ago

First import

File size: 4.0 KB
Line 
1/*
2 * sysfs/sysfs_file.c - sysfs file related operations
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <config.h>
24#include <device.h>
25#include <driver.h>
26#include <kmem.h>
27#include <kdmsg.h>
28#include <string.h>
29#include <vfs.h>
30#include <errno.h>
31#include <metafs.h>
32#include <thread.h>
33#include <task.h>
34
35#include <sysfs.h>
36#include <sysfs-private.h>
37
38KMEM_OBJATTR_INIT(sysfs_kmem_file_init)
39{
40        attr->type   = KMEM_SYSFS_FILE;
41        attr->name   = "KCM SysFs File";
42        attr->size   = sizeof(struct sysfs_file_s);
43        attr->aligne = 0;
44        attr->min    = CONFIG_SYSFS_FILE_MIN;
45        attr->max    = CONFIG_SYSFS_FILE_MAX;
46        attr->ctor   = NULL;
47        attr->dtor   = NULL;
48        return 0;
49}
50
51
52VFS_OPEN_FILE(sysfs_open)
53{
54        register struct sysfs_file_s *f_info;
55        register struct sysfs_node_s *n_info;
56        register sysfs_entry_t *entry;
57        kmem_req_t req;
58
59        n_info = file->fr_inode->i_pv;
60        f_info = file->fr_pv;
61 
62        if((file->fr_pv == NULL))
63        {
64                req.type  = KMEM_SYSFS_FILE;
65                req.size  = sizeof(*f_info);
66                req.flags = AF_KERNEL;
67
68                f_info    = kmem_alloc(&req);
69        }
70
71        if(f_info == NULL)
72                return ENOMEM;
73
74        f_info->node          = n_info->node;
75        entry                 = metafs_container(f_info->node, sysfs_entry_t, node);
76        f_info->entry         = entry;
77        f_info->current_index = 0;
78        file->fr_pv            = f_info;
79 
80        if(file->fr_inode->i_attr & VFS_DIR)
81        {
82                metafs_iter_init(f_info->node, &f_info->iter);
83                return 0;
84        }
85 
86        if(entry->op.open)
87                return entry->op.open(entry, &f_info->rq, &file->fr_offset);
88 
89        return 0;
90}
91
92VFS_READ_FILE(sysfs_read)
93{
94        register struct sysfs_file_s *info;
95        register uint_t size;
96        register error_t err;
97
98        //TODO: handle the case where the this fs is
99        //accessed remotly 
100        assert(file->f_inode.cid == current_cid);
101
102        info = file->f_remote->fr_pv;
103
104        if(info->entry->op.read == NULL)
105                return ENOSYS;
106 
107        if(info->current_index == 0)
108        {
109                if((err = info->entry->op.read(info->entry, &info->rq, &file->f_remote->fr_offset)))
110                {
111                        printk(INFO, "INFO: sysfs_read: error %d\n", err);
112                        return err;
113                }
114        }
115
116        size = buffer->size;
117        if(size > info->rq.count)
118                size = info->rq.count;
119   
120        buffer->scpy_to_buff(buffer, &info->rq.buffer[info->current_index], size);
121 
122        info->rq.count     -= size;
123        info->current_index = (info->rq.count) ? info->current_index + size : 0;
124
125        return size;
126}
127
128VFS_WRITE_FILE(sysfs_write)
129{
130        return ENOTSUPPORTED;
131}
132
133VFS_LSEEK_FILE(sysfs_lseek)
134{
135        return ENOTSUPPORTED;
136}
137
138VFS_CLOSE_FILE(sysfs_close)
139{
140        return 0;
141}
142
143VFS_RELEASE_FILE(sysfs_release)
144{ 
145        kmem_req_t req;
146 
147        if(file->fr_pv == NULL)
148                return 0;
149 
150        req.type   = KMEM_SYSFS_FILE;
151        req.ptr    = file->fr_pv;
152        kmem_free(&req);
153        file->fr_pv = NULL;
154
155        return 0;
156}
157
158VFS_READ_DIR(sysfs_readdir)
159{
160        register struct sysfs_file_s *info;
161        register struct metafs_s *current;
162 
163        info = file->fr_pv;
164
165        if((current = metafs_lookup_next(info->node, &info->iter)) == NULL)
166                return EEODIR;
167
168        dirent->u_attr = (metafs_hasChild(current)) ? VFS_DIR : 0;
169        strcpy((char*)dirent->u_name, metafs_get_name(current));
170 
171        //FIXME: better inode number
172        dirent->u_ino = (uint_t) current;
173
174        return 0;
175}
176
177const struct vfs_file_op_s sysfs_f_op = 
178{
179        .open    = sysfs_open,
180        .read    = sysfs_read,
181        .write   = sysfs_write,
182        .lseek   = sysfs_lseek,
183        .readdir = sysfs_readdir,
184        .close   = sysfs_close,
185        .release = sysfs_release,
186};
Note: See TracBrowser for help on using the repository browser.