Annotation of prex/usr/server/fs/fatfs/fatfs_vfsops.c, Revision 1.1.1.1
1.1 nbrk 1: /*
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 <prex/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 err;
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: err = device_read(fmp->dev, bpb, &size, 0);
83: if (err) {
84: free(bpb);
85: return err;
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 err = 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: err = 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 err;
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: }
210:
CVSweb