2 * fat - A FAT* CDI driver
4 * Copyright (C) 2008 Janosch Gräf
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 3 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "cdi/cache.h"
28 * Reads data from device for cache
29 * @param cache CDI cache
30 * @param block Block to read
31 * @param count How many blocks to read
32 * @param dest Buffer to store data in
33 * @param prv Private data (CDI filesystem)
34 * @return How many sectors read
36 int fat_sector_read_cache(struct cdi_cache
*cache
,uint64_t block
,size_t count
,void *dest
,void *prv
) {
37 debug("fat_sector_read_cache(0x%x,0x%x,0x%x,0x%x,0x%x)\n",cache
,block
,count
,dest
,prv
);
38 struct fat_fs_filesystem
*fat_fs
= ((struct cdi_fs_filesystem
*)prv
)->opaque
;
39 uint64_t start
= block
*fat_fs
->bootsector
->sector_size
;
40 size_t size
= count
*fat_fs
->bootsector
->sector_size
;
41 return cdi_fs_data_read(prv
,start
,size
,dest
)/fat_fs
->bootsector
->sector_size
;
45 * Writes data to device for cache
46 * @param cache CDI cache
47 * @param block Block to write
48 * @param count How many blocks to write
49 * @param dest Data to write
50 * @param prv Private data (CDI filesystem)
51 * @return How many sectors written
53 int fat_sector_write_cache(struct cdi_cache
*cache
,uint64_t block
,size_t count
,const void *dest
,void *prv
) {
54 debug("fat_sector_write_cache(0x%x,0x%x,0x%x,0x%x,0x%x)\n",cache
,block
,count
,dest
,prv
);
55 struct fat_fs_filesystem
*fat_fs
= ((struct cdi_fs_filesystem
*)prv
)->opaque
;
56 uint64_t start
= block
*fat_fs
->bootsector
->sector_size
;
57 size_t size
= count
*fat_fs
->bootsector
->sector_size
;
58 return cdi_fs_data_write(prv
,start
,size
,dest
)/fat_fs
->bootsector
->sector_size
;
62 * Reads data from volume (NO CLUSTER READ)
63 * @param fs Filesystem
64 * @param pos Position on volume
65 * @param size How many bytes to read
66 * @param Buffer Buffer to store data in
67 * @return How many bytes read
69 size_t fat_read(struct cdi_fs_filesystem
*fs
,uint64_t pos
,size_t size
,void *buffer
) {
70 struct fat_fs_filesystem
*fat_fs
= fs
->opaque
;
71 size_t block
= pos
/fat_fs
->bootsector
->sector_size
;
72 if (block
>=fat_num_sectors(fat_fs
->bootsector
)) return 0;
73 size_t offset
= pos
%fat_fs
->bootsector
->sector_size
;
74 size_t rem_size
= size
;
77 struct cdi_cache_block
*cache_block
= cdi_cache_block_get(fat_fs
->cache
,block
++,0);
78 size_t cur_size
= rem_size
>fat_fs
->bootsector
->sector_size
?fat_fs
->bootsector
->sector_size
:rem_size
;
79 memcpy(buffer
,cache_block
->data
+offset
,cur_size
);
80 cdi_cache_block_release(fat_fs
->cache
,cache_block
);
90 * Writes data to volume (NO CLUSTER WRITE)
91 * @param fs Filesystem
92 * @param pos Position on volume
93 * @param size How many bytes to write
94 * @param Buffer Data to write to volume
95 * @return How many bytes written
97 size_t fat_write(struct cdi_fs_filesystem
*fs
,uint64_t pos
,size_t size
,const void *buffer
) {
98 struct fat_fs_filesystem
*fat_fs
= fs
->opaque
;
99 size_t block
= pos
/fat_fs
->bootsector
->sector_size
;
100 if (block
>=fat_num_sectors(fat_fs
->bootsector
)) return 0;
101 size_t offset
= pos
%fat_fs
->bootsector
->sector_size
;
102 size_t rem_size
= size
;
105 struct cdi_cache_block
*cache_block
= cdi_cache_block_get(fat_fs
->cache
,block
++,0);
106 size_t cur_size
= rem_size
>fat_fs
->bootsector
->sector_size
?fat_fs
->bootsector
->sector_size
:rem_size
;
107 memcpy(cache_block
->data
+offset
,buffer
,cur_size
);
108 cdi_cache_block_release(fat_fs
->cache
,cache_block
);
110 rem_size
-= cur_size
;