Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / usr / server / fs / fatfs / fatfs_vfsops.c @ 03e9c04a

History | View | Annotate | Download (5.32 KB)

1 03e9c04a Brad Neuman
/*
2
 * Copyright (c) 2005-2008, Kohsuke Ohtani
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
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include <sys/prex.h>
31
32
#include <sys/stat.h>
33
#include <sys/vnode.h>
34
#include <sys/file.h>
35
#include <sys/mount.h>
36
#include <sys/buf.h>
37
38
#include <ctype.h>
39
#include <unistd.h>
40
#include <errno.h>
41
#include <string.h>
42
#include <stdlib.h>
43
#include <fcntl.h>
44
45
#include "fatfs.h"
46
47
static int fatfs_mount        (mount_t mp, char *dev, int flags, void *data);
48
static int fatfs_unmount(mount_t mp);
49
#define fatfs_sync        ((vfsop_sync_t)vfs_nullop)
50
static int fatfs_vget        (mount_t mp, vnode_t vp);
51
#define fatfs_statfs        ((vfsop_statfs_t)vfs_nullop)
52
53
/*
54
 * File system operations
55
 */
56
struct vfsops fatfs_vfsops = {
57
        fatfs_mount,                /* mount */
58
        fatfs_unmount,                /* unmount */
59
        fatfs_sync,                /* sync */
60
        fatfs_vget,                /* vget */
61
        fatfs_statfs,                /* statfs */
62
        &fatfs_vnops,                /* vnops */
63
};
64
65
/*
66
 * Read BIOS parameter block.
67
 * Return 0 on sucess.
68
 */
69
static int
70
fat_read_bpb(struct fatfsmount *fmp)
71
{
72
        struct fat_bpb *bpb;
73
        size_t size;
74
        int error;
75
76
        bpb = malloc(SEC_SIZE);
77
        if (bpb == NULL)
78
                return ENOMEM;
79
80
        /* Read boot sector (block:0) */
81
        size = SEC_SIZE;
82
        error = device_read(fmp->dev, bpb, &size, 0);
83
        if (error) {
84
                free(bpb);
85
                return error;
86
        }
87
        if (bpb->bytes_per_sector != SEC_SIZE) {
88
                DPRINTF(("fatfs: invalid sector size\n"));
89
                free(bpb);
90
                return EINVAL;
91
        }
92
93
        /* Build FAT mount data */
94
        fmp->fat_start = bpb->hidden_sectors + bpb->reserved_sectors;
95
        fmp->root_start = fmp->fat_start +
96
                (bpb->num_of_fats * bpb->sectors_per_fat);
97
        fmp->data_start =
98
                fmp->root_start + (bpb->root_entries / DIR_PER_SEC);
99
        fmp->sec_per_cl = bpb->sectors_per_cluster;
100
        fmp->cluster_size = bpb->sectors_per_cluster * SEC_SIZE;
101
        fmp->last_cluster = (bpb->total_sectors - fmp->data_start) /
102
                bpb->sectors_per_cluster + CL_FIRST;
103
        fmp->free_scan = CL_FIRST;
104
105
        if (!strncmp((const char *)bpb->file_sys_id, "FAT12   ", 8)) {
106
                fmp->fat_type = 12;
107
                fmp->fat_mask = FAT12_MASK;
108
                fmp->fat_eof = CL_EOF & FAT12_MASK;
109
        } else if (!strncmp((const char *)bpb->file_sys_id, "FAT16   ", 8)) {
110
                fmp->fat_type = 16;
111
                fmp->fat_mask = FAT16_MASK;
112
                fmp->fat_eof = CL_EOF & FAT16_MASK;
113
        } else {
114
                /* FAT32 is not supported now! */
115
                DPRINTF(("fatfs: invalid FAT type\n"));
116
                free(bpb);
117
                return EINVAL;
118
        }
119
        free(bpb);
120
121
        DPRINTF(("----- FAT info -----\n"));
122
        DPRINTF(("drive:%x\n", (int)bpb->physical_drive));
123
        DPRINTF(("total_sectors:%d\n", (int)bpb->total_sectors));
124
        DPRINTF(("heads       :%d\n", (int)bpb->heads));
125
        DPRINTF(("serial      :%x\n", (int)bpb->serial_no));
126
        DPRINTF(("cluster size:%u sectors\n", (int)fmp->sec_per_cl));
127
        DPRINTF(("fat_type    :FAT%u\n", (int)fmp->fat_type));
128
        DPRINTF(("fat_eof     :0x%x\n\n", (int)fmp->fat_eof));
129
        return 0;
130
}
131
132
/*
133
 * Mount file system.
134
 */
135
static int
136
fatfs_mount(mount_t mp, char *dev, int flags, void *data)
137
{
138
        struct fatfsmount *fmp;
139
        vnode_t vp;
140
        int error = 0;
141
142
        DPRINTF(("fatfs_mount device=%s\n", dev));
143
144
        fmp = malloc(sizeof(struct fatfsmount));
145
        if (fmp == NULL)
146
                return ENOMEM;
147
148
        fmp->dev = mp->m_dev;
149
        if (fat_read_bpb(fmp) != 0)
150
                goto err1;
151
152
        error = ENOMEM;
153
        fmp->io_buf = malloc(fmp->sec_per_cl * SEC_SIZE);
154
        if (fmp->io_buf == NULL)
155
                goto err1;
156
157
        fmp->fat_buf = malloc(SEC_SIZE * 2);
158
        if (fmp->fat_buf == NULL)
159
                goto err2;
160
161
        fmp->dir_buf = malloc(SEC_SIZE);
162
        if (fmp->dir_buf == NULL)
163
                goto err3;
164
165
        mutex_init(&fmp->lock);
166
        mp->m_data = fmp;
167
        vp = mp->m_root;
168
        vp->v_blkno = CL_ROOT;
169
        return 0;
170
 err3:
171
        free(fmp->fat_buf);
172
 err2:
173
        free(fmp->io_buf);
174
 err1:
175
        free(fmp);
176
        return error;
177
}
178
179
/*
180
 * Unmount the file system.
181
 */
182
static int
183
fatfs_unmount(mount_t mp)
184
{
185
        struct fatfsmount *fmp;
186
187
        fmp = mp->m_data;
188
        free(fmp->dir_buf);
189
        free(fmp->fat_buf);
190
        free(fmp->io_buf);
191
        mutex_destroy(&fmp->lock);
192
        free(fmp);
193
        return 0;
194
}
195
196
/*
197
 * Prepare the FAT specific node and fill the vnode.
198
 */
199
static int
200
fatfs_vget(mount_t mp, vnode_t vp)
201
{
202
        struct fatfs_node *np;
203
204
        np = malloc(sizeof(struct fatfs_node));
205
        if (np == NULL)
206
                return ENOMEM;
207
        vp->v_data = np;
208
        return 0;
209
}