fat: new license (LGPL)
[meinos.git] / apps / fat / sector.c
blob6f08520c073c686f525d004c9e93a3e6886d47dc
1 /*
2 fat - A FAT* CDI driver
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stddef.h>
20 #include <string.h>
22 #include "cdi/cache.h"
24 #include "fat_cdi.h"
26 /**
27 * Reads data from device for cache
28 * @param cache CDI cache
29 * @param block Block to read
30 * @param count How many blocks to read
31 * @param dest Buffer to store data in
32 * @param prv Private data (CDI filesystem)
33 * @return How many sectors read
35 int fat_sector_read_cache(struct cdi_cache *cache,uint64_t block,size_t count,void *dest,void *prv) {
36 debug("fat_sector_read_cache(0x%x,0x%x,0x%x,0x%x,0x%x)\n",cache,block,count,dest,prv);
37 struct fat_fs_filesystem *fat_fs = ((struct cdi_fs_filesystem*)prv)->opaque;
38 uint64_t start = block*fat_fs->bootsector->sector_size;
39 size_t size = count*fat_fs->bootsector->sector_size;
40 return cdi_fs_data_read(prv,start,size,dest)/fat_fs->bootsector->sector_size;
43 /**
44 * Writes data to device for cache
45 * @param cache CDI cache
46 * @param block Block to write
47 * @param count How many blocks to write
48 * @param dest Data to write
49 * @param prv Private data (CDI filesystem)
50 * @return How many sectors written
52 int fat_sector_write_cache(struct cdi_cache *cache,uint64_t block,size_t count,const void *dest,void *prv) {
53 debug("fat_sector_write_cache(0x%x,0x%x,0x%x,0x%x,0x%x)\n",cache,block,count,dest,prv);
54 struct fat_fs_filesystem *fat_fs = ((struct cdi_fs_filesystem*)prv)->opaque;
55 uint64_t start = block*fat_fs->bootsector->sector_size;
56 size_t size = count*fat_fs->bootsector->sector_size;
57 return cdi_fs_data_write(prv,start,size,dest)/fat_fs->bootsector->sector_size;
60 /**
61 * Reads data from volume (NO CLUSTER READ)
62 * @param fs Filesystem
63 * @param pos Position on volume
64 * @param size How many bytes to read
65 * @param Buffer Buffer to store data in
66 * @return How many bytes read
68 size_t fat_read(struct cdi_fs_filesystem *fs,uint64_t pos,size_t size,void *buffer) {
69 struct fat_fs_filesystem *fat_fs = fs->opaque;
70 size_t block = pos/fat_fs->bootsector->sector_size;
71 if (block>=fat_num_sectors(fat_fs->bootsector)) return 0;
72 size_t offset = pos%fat_fs->bootsector->sector_size;
73 size_t rem_size = size;
75 while (rem_size>0) {
76 struct cdi_cache_block *cache_block = cdi_cache_block_get(fat_fs->cache,block++,0);
77 size_t cur_size = rem_size>fat_fs->bootsector->sector_size?fat_fs->bootsector->sector_size:rem_size;
78 memcpy(buffer,cache_block->data+offset,cur_size);
79 cdi_cache_block_release(fat_fs->cache,cache_block);
80 buffer += cur_size;
81 rem_size -= cur_size;
82 offset = 0;
85 return size;
88 /**
89 * Writes data to volume (NO CLUSTER WRITE)
90 * @param fs Filesystem
91 * @param pos Position on volume
92 * @param size How many bytes to write
93 * @param Buffer Data to write to volume
94 * @return How many bytes written
96 size_t fat_write(struct cdi_fs_filesystem *fs,uint64_t pos,size_t size,const void *buffer) {
97 struct fat_fs_filesystem *fat_fs = fs->opaque;
98 size_t block = pos/fat_fs->bootsector->sector_size;
99 if (block>=fat_num_sectors(fat_fs->bootsector)) return 0;
100 size_t offset = pos%fat_fs->bootsector->sector_size;
101 size_t rem_size = size;
103 while (rem_size>0) {
104 struct cdi_cache_block *cache_block = cdi_cache_block_get(fat_fs->cache,block++,0);
105 size_t cur_size = rem_size>fat_fs->bootsector->sector_size?fat_fs->bootsector->sector_size:rem_size;
106 memcpy(cache_block->data+offset,buffer,cur_size);
107 cdi_cache_block_release(fat_fs->cache,cache_block);
108 buffer += cur_size;
109 rem_size -= cur_size;
110 offset = 0;
113 return size;