source: trunk/kernel/fs/fatfs/fat32_context.c @ 8

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

First import

File size: 5.8 KB
Line 
1/*
2 * fat32/fat32_context.c - fat32 context 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 <kdmsg.h>
24#include <device.h>
25#include <driver.h>
26#include <kmem.h>
27#include <rwlock.h>
28#include <string.h>
29#include <page.h>
30#include <cluster.h>
31#include <thread.h>
32#include <mapper.h>
33#include <atomic.h>
34#include <vfs.h>
35 
36#include <fat32.h>
37#include <fat32-private.h>
38
39static error_t vfat_context_init(struct vfat_context_s *ctx)
40{
41        size_t blk_sz;
42        dev_params_t params;
43        struct vfat_bpb_s *bpb;
44        struct page_s *page;
45        struct mapper_s *mapper;
46 
47        if((ctx->dev->op.dev.get_params(ctx->dev, &params)))
48                return -1;
49
50        blk_sz                = params.sector_size;
51        ctx->bytes_per_sector = blk_sz;
52        mapper                = ctx->mapper;
53       
54        page = mapper_get_page(mapper, 0, MAPPER_SYNC_OP);
55
56        if(page == NULL) 
57        {
58                printk(ERROR, "ERROR: VFAT context_init: I/O error, could not read bpb from the device.\n");
59                return -1;
60        }
61
62        bpb = (struct vfat_bpb_s *) ppm_page2addr(page);
63
64        ctx->bytes_per_sector = bpb->BPB_BytsPerSec;
65
66        if (blk_sz != ctx->bytes_per_sector)
67                PANIC("VFAT drv error: bpb/device block size mismatch bpb block %d, devBlk %d\n",
68                      ctx->bytes_per_sector, blk_sz);
69
70        ctx->fat_begin_lba         = bpb->BPB_RsvdSecCnt;
71        ctx->fat_blk_count         = bpb->BPB_FATSz32;
72        ctx->cluster_begin_lba     = ctx->fat_begin_lba + (bpb->BPB_NumFATs * bpb->BPB_FATSz32);
73        ctx->sectors_per_cluster   = bpb->BPB_SecPerClus;
74        ctx->rootdir_first_cluster = bpb->BPB_RootClus;
75        ctx->bytes_per_cluster     = ctx->bytes_per_sector * ctx->sectors_per_cluster;
76        ctx->last_allocated_sector = ctx->fat_begin_lba;
77        ctx->last_allocated_index  = 2;
78
79        vfat_dmsg(1, 
80                  "%s:\n\tbegin_lba %d\n\tblk_count %d\n\tcluster_begin_lba %d\n\t"
81                  "sectors_per_cluster %d\n\trootdir_first_cluster  %d\n\tbytes_per_cluster %d\n\t"
82                  "MediaType %x (@%x)\n",
83                  __FUNCTION__,
84                  ctx->fat_begin_lba, 
85                  ctx->fat_blk_count,
86                  ctx->cluster_begin_lba, 
87                  ctx->sectors_per_cluster,
88                  ctx->rootdir_first_cluster, 
89                  ctx->bytes_per_cluster,
90                  bpb->BPB_Media,
91                  &bpb->BPB_Media);
92
93        vfat_dmsg(1, "DEBUG: context_init: last allocated sector %d, last allocated index %d\n",
94                  ctx->last_allocated_sector, ctx->last_allocated_index);
95
96       
97        return 0;
98}
99
100VFS_CREATE_CONTEXT(vfat_create_context)
101{
102        kmem_req_t req;
103        struct vfat_context_s *vfat_ctx;
104        struct mapper_s *mapper;
105        error_t err;
106
107        vfat_dmsg(1, "%s: started\n", __FUNCTION__);
108 
109        vfat_ctx = &context->ctx_vfat;
110
111        vfat_ctx->dev = context->ctx_dev;//necessary ?
112
113        rwlock_init(&vfat_ctx->lock);
114
115        req.type = KMEM_MAPPER;
116        req.size = sizeof(*mapper);
117        mapper   = kmem_alloc(&req);
118
119        if(mapper == NULL)
120        {
121                err = ENOMEM;
122                goto fail_mapper;
123        }
124
125        err = mapper_init(mapper, &vfat_inode_mapper_op, NULL, vfat_ctx);
126
127        if(err)
128        {
129                printk(ERROR, "ERROR: %s: failed to init mapper, err %d\n", __FUNCTION__, err);
130                goto fail_mapper_init;
131        }
132
133        vfat_ctx->mapper = mapper;
134        vfat_ctx->fat_cid = current_cid;
135
136        if ((err = vfat_context_init(vfat_ctx)))
137        {
138                printk(ERROR, "ERROR: vfat_create_context: INITIALIZING VFAT CONTEXT err %d\n",err);
139                goto fail_ctx_init;
140        }
141
142        context->ctx_flags      |= VFS_FS_USE_MAPPER;
143        context->ctx_type       = VFS_VFAT_TYPE;
144        context->ctx_blksize    = vfat_ctx->bytes_per_sector;
145        context->ctx_op         = (struct vfs_context_op_s *) &vfat_ctx_op;
146        context->ctx_inode_op   = (struct vfs_inode_op_s *) &vfat_i_op;
147        context->ctx_dirent_op  = (struct vfs_dirent_op_s *) &vfat_d_op;
148        context->ctx_file_op    = (struct vfs_file_op_s *) &vfat_f_op;
149
150        return 0;
151
152fail_ctx_init:
153fail_mapper_init:
154        mapper_destroy(mapper, false);
155        req.type = KMEM_MAPPER;
156        req.ptr  = mapper;
157        kmem_free(&req);
158
159fail_mapper:
160        req.type = KMEM_VFAT_CTX;
161        req.ptr  = vfat_ctx;
162        kmem_free(&req);
163
164        rwlock_destroy(&vfat_ctx->lock);
165        return err;
166}
167
168VFS_DESTROY_CONTEXT(vfat_destroy_context)
169{
170        struct vfat_context_s *ctx;
171
172        ctx = &context->ctx_vfat;
173        mapper_destroy(ctx->mapper, true);
174        rwlock_destroy(&ctx->lock);
175        return 0;
176}
177
178
179VFS_READ_ROOT(vfat_read_root)
180{
181        struct vfat_context_s *ctx;
182        struct vfat_inode_s * i_info;
183       
184        ctx = &context->ctx_vfat;
185
186        root->i_type            |= VFS_DIR;//?
187        root->i_links           = 1;
188        root->i_attr            |= VFS_DIR;
189        root->i_size            = vfat_cluster_count(ctx, ctx->rootdir_first_cluster);//does a dir has a size?
190        root->i_mapper->m_inode = root;
191        root->i_mapper->m_ops   = &vfat_inode_mapper_op;
192        root->i_number          = vfs_inum_new(context);
193
194        assert(root->i_pv);
195        i_info                 = root->i_pv;
196        i_info->flags          = VFAT_ATTR_DIRECTORY;
197        i_info->first_cluster  = ctx->rootdir_first_cluster;
198        //i_info->parent_cluster = 0;
199        //i_info->entry_index    = 0;
200
201        return 0;
202}
203
204
205VFS_WRITE_ROOT(vfat_write_root)
206{
207        return 0;
208}
209
210
211KMEM_OBJATTR_INIT(vfat_kmem_context_init)
212{
213        attr->type   = KMEM_VFAT_CTX;
214        attr->name   = "KCM VFAT CTX";
215        attr->size   = sizeof(struct vfat_context_s);
216        attr->aligne = 0;
217        attr->min    = CONFIG_VFAT_CTX_MIN;
218        attr->max    = CONFIG_VFAT_CTX_MAX;
219        attr->ctor   = NULL;
220        attr->dtor   = NULL;
221        return 0;
222}
223
224const struct vfs_context_op_s vfat_ctx_op =
225{
226        .create     = vfat_create_context,
227        .destroy    = vfat_destroy_context,
228        .read_root  = vfat_read_root,
229        .write_root = vfat_write_root,
230        .repli_root = NULL
231};
Note: See TracBrowser for help on using the repository browser.