source: mainline/uspace/srv/fs/fat/fat_ops.c@ 79dbc3e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 79dbc3e was 79dbc3e, checked in by Jakub Jermar <jakub@…>, 17 years ago

Introduce and also use the foundation of block cache API in FAT's match
operation.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file fat_ops.c
35 * @brief Implementation of VFS operations for the FAT file system server.
36 */
37
38#include "fat.h"
39#include "../../vfs/vfs.h"
40#include <libfs.h>
41#include <ipc/ipc.h>
42#include <async.h>
43#include <errno.h>
44#include <string.h>
45#include <byteorder.h>
46
47#define FAT_NAME_LEN 8
48#define FAT_EXT_LEN 3
49
50#define FAT_PAD ' '
51
52#define FAT_DENTRY_UNUSED 0x00
53#define FAT_DENTRY_E5_ESC 0x05
54#define FAT_DENTRY_DOT 0x2e
55#define FAT_DENTRY_ERASED 0xe5
56
57static void dentry_name_canonify(fat_dentry_t *d, char *buf)
58{
59 int i;
60
61 for (i = 0; i < FAT_NAME_LEN; i++) {
62 if (d->name[i] == FAT_PAD) {
63 buf++;
64 break;
65 }
66 if (d->name[i] == FAT_DENTRY_E5_ESC)
67 *buf++ = 0xe5;
68 else
69 *buf++ = d->name[i];
70 }
71 if (d->ext[0] != FAT_PAD)
72 *buf++ = '.';
73 for (i = 0; i < FAT_EXT_LEN; i++) {
74 if (d->ext[i] == FAT_PAD) {
75 *buf = '\0';
76 return;
77 }
78 if (d->ext[i] == FAT_DENTRY_E5_ESC)
79 *buf++ = 0xe5;
80 else
81 *buf++ = d->ext[i];
82 }
83}
84
85/* TODO and also move somewhere else */
86typedef struct {
87 void *data;
88} block_t;
89
90static block_t *block_get(dev_handle_t dev_handle, off_t offset)
91{
92 return NULL; /* TODO */
93}
94
95static block_t *fat_block_get(fat_node_t *node, off_t offset) {
96 return NULL; /* TODO */
97}
98
99static void block_put(block_t *block)
100{
101 /* TODO */
102}
103
104static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
105{
106 return NULL; /* TODO */
107}
108
109#define BS_BLOCK 0
110
111static void *fat_match(void *prnt, const char *component)
112{
113 fat_node_t *parentp = (fat_node_t *)prnt;
114 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
115 unsigned i, j;
116 unsigned dps; /* dentries per sector */
117 unsigned blocks;
118 fat_dentry_t *d;
119 block_t *bb;
120 block_t *b;
121 fat_bs_t *bs;
122
123 bb = block_get(parentp->dev_handle, BS_BLOCK);
124 if (!bb)
125 return NULL;
126 bs = (fat_bs_t *)bb->data;
127 dps = bs->bps / sizeof(fat_dentry_t);
128 blocks = parentp->size / bs->bps + (parentp->size % bs->bps != 0);
129 block_put(bb);
130 for (i = 0; i < blocks; i++) {
131 unsigned dentries;
132
133 b = fat_block_get(parentp, i);
134 if (!b)
135 return NULL;
136
137 dentries = (i == blocks - 1) ?
138 parentp->size % sizeof(fat_dentry_t) :
139 dps;
140 for (j = 0; j < dentries; j++) {
141 d = ((fat_dentry_t *)b->data) + j;
142 if (d->attr & FAT_ATTR_VOLLABEL) {
143 /* volume label entry */
144 continue;
145 }
146 if (d->name[0] == FAT_DENTRY_ERASED) {
147 /* not-currently-used entry */
148 continue;
149 }
150 if (d->name[0] == FAT_DENTRY_UNUSED) {
151 /* never used entry */
152 block_put(b);
153 return NULL;
154 }
155 if (d->name[0] == FAT_DENTRY_DOT) {
156 /*
157 * Most likely '.' or '..'.
158 * It cannot occur in a regular file name.
159 */
160 continue;
161 }
162
163 dentry_name_canonify(d, name);
164 if (strcmp(name, component) == 0) {
165 /* hit */
166 void *node = fat_node_get(parentp->dev_handle,
167 (fs_index_t)uint16_t_le2host(d->firstc));
168 block_put(b);
169 return node;
170 }
171 }
172 block_put(b);
173 }
174
175 return NULL;
176}
177
178/** libfs operations */
179libfs_ops_t fat_libfs_ops = {
180 .match = fat_match,
181 .node_get = fat_node_get,
182 .create = NULL,
183 .destroy = NULL,
184 .link = NULL,
185 .unlink = NULL,
186 .index_get = NULL,
187 .size_get = NULL,
188 .lnkcnt_get = NULL,
189 .has_children = NULL,
190 .root_get = NULL,
191 .plb_get_char = NULL,
192 .is_directory = NULL,
193 .is_file = NULL
194};
195
196void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
197{
198 libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
199}
200
201/**
202 * @}
203 */
Note: See TracBrowser for help on using the repository browser.