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

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

First import

File size: 4.0 KB
Line 
1/*
2 * fat32/fat32_file.c - fat32 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 <stdint.h>
24#include <kmem.h>
25#include <string.h>
26#include <ppm.h>
27#include <pmm.h>
28#include <page.h>
29#include <mapper.h>
30#include <vfs.h>
31#include <ppn.h>
32#include <thread.h>
33#include <sys-vfs.h>
34
35#include <fat32.h>
36#include <fat32-private.h>
37
38VFS_OPEN_FILE(vfat_open) 
39{
40        return 0;
41}
42
43VFS_LSEEK_FILE(vfat_lseek)
44{
45        return 0;
46}
47
48VFS_CLOSE_FILE(vfat_close) 
49{
50        return 0;
51}
52
53VFS_RELEASE_FILE(vfat_release) 
54{
55        assert(file->fr_pv == NULL);
56        return 0;
57}
58
59
60VFS_READ_DIR(vfat_readdir) 
61{
62        struct vfat_DirEntry_s dir;
63        struct page_s *page;
64        struct mapper_s *mapper;
65        vfat_cluster_t node_cluster;
66        uint8_t *buff;
67        uint32_t found;
68
69        mapper    = file->fr_inode->i_mapper;
70        found     = 0;
71
72        /* TODO: dont call mapper every time, as page can be reused */
73        while(!found) 
74        {
75                //FIXME: synchro : either use a lock or force the writer to
76                //write the first byte of the name as the last thing he do
77                //when adding an entry
78                //also lock file offset ?
79                if ((page = mapper_get_page(mapper, 
80                                            file->fr_offset >> PMM_PAGE_SHIFT, 
81                                            MAPPER_SYNC_OP)) == NULL)
82                        return VFS_IO_ERR;
83
84                buff  = ppm_page2addr(page);
85                buff += file->fr_offset % PMM_PAGE_SIZE;
86
87                memcpy(&dir, buff, sizeof(dir));
88
89                if(dir.DIR_Name[0] == 0x00) {
90                        vfat_dmsg(3,"vfat_readdir: entries termination found (0x00)\n");
91                        goto VFS_READ_DIR_EODIR;
92                }
93
94                if(dir.DIR_Name[0] == 0xE5) {
95                        vfat_dmsg(3,"entry was freeed previously\n");
96                        vfat_getshortname((char*)dir.DIR_Name, (char*)dirent->u_name);
97                        vfat_dmsg(3,"it was %s\n",dirent->u_name);
98                        goto VFS_READ_DIR_NEXT;
99                }
100
101                if(dir.DIR_Attr == 0x0F) {
102                        vfat_dmsg(3,"this entry is a long one\n");
103                        vfat_getshortname((char*)dir.DIR_Name, (char*)dirent->u_name);
104                        vfat_dmsg(3,"trying to read its name %s\n",dirent->u_name);
105                        goto VFS_READ_DIR_NEXT;
106                }
107
108                if(dir.DIR_Name[0] == '.')
109                        goto VFS_READ_DIR_NEXT;
110
111                found = 1;
112                vfat_getshortname((char *)dir.DIR_Name, (char*)dirent->u_name);
113
114                //dirent->d_size = dir.DIR_FileSize;
115                dirent->u_attr = 0;
116
117                if(dir.DIR_Attr & VFAT_ATTR_DIRECTORY)
118                        dirent->u_attr = VFS_DIR;
119
120                if(dir.DIR_Attr & VFAT_ATTR_SYSTEM)
121                        dirent->u_attr |= VFS_SYS;
122
123                if(dir.DIR_Attr & VFAT_ATTR_ARCHIVE)
124                        dirent->u_attr |= VFS_ARCHIVE;
125
126                if(dir.DIR_Attr & VFAT_ATTR_READ_ONLY)
127                        dirent->u_attr |= VFS_RD_ONLY;
128
129                node_cluster  = dir.DIR_FstClusHI << 16;
130                node_cluster |= (0x0000FFFF & dir.DIR_FstClusLO);
131
132                if((!node_cluster) && (dirent->u_attr & VFS_SYS)
133                   && (dirent->u_attr & VFS_RD_ONLY) && (dirent->u_attr & VFS_DIR)) {
134                        dirent->u_attr |= VFS_DEV;
135                        dirent->u_attr &= ~(VFS_SYS | VFS_RD_ONLY | VFS_DIR);
136                }
137                else
138                        if((!node_cluster) && (dirent->u_attr & VFS_SYS) && (dirent->u_attr & VFS_RD_ONLY)) {
139                                dirent->u_attr |= VFS_FIFO;
140                                dirent->u_attr &= ~(VFS_SYS | VFS_RD_ONLY);
141                        }
142
143        VFS_READ_DIR_NEXT:
144                file->fr_offset += sizeof(struct vfat_DirEntry_s);
145        }
146
147VFS_READ_DIR_EODIR:
148        return (found) ? 0 : VFS_EODIR;
149}
150
151const struct vfs_file_op_s vfat_f_op =
152{
153        .open    = vfat_open,
154        .read    = vfs_default_read,
155        .write   = vfs_default_write,
156        .lseek   = NULL,
157        .readdir = vfat_readdir,
158        .close   = vfat_close,
159        .release = vfat_release,
160        .mmap    = vfs_default_mmap_file,
161        .munmap  = vfs_default_munmap_file
162};
Note: See TracBrowser for help on using the repository browser.