43static void fsw_blockcache_free(
struct fsw_volume *vol);
45#define MAX_CACHE_LEVEL (5)
115 fsw_blockcache_free(vol);
151 fsw_blockcache_free(vol);
182 fsw_u32 i, discard_level, new_bcache_size;
192 for (i = 0; i < vol->bcache_size; i++) {
193 if (vol->bcache[i].phys_bno ==
phys_bno) {
197 vol->bcache[i].refcount++;
198 *buffer_out = vol->bcache[i].data;
204 for (i = 0; i < vol->bcache_size; i++) {
208 if (i >= vol->bcache_size) {
209 for (discard_level = 0; discard_level <=
MAX_CACHE_LEVEL; discard_level++) {
210 for (i = 0; i < vol->bcache_size; i++) {
211 if (vol->bcache[i].refcount == 0 && vol->bcache[i].cache_level <= discard_level)
214 if (i < vol->bcache_size)
218 if (i >= vol->bcache_size) {
220 if (vol->bcache_size < 16)
221 new_bcache_size = 16;
223 new_bcache_size = vol->bcache_size << 1;
227 if (vol->bcache_size > 0)
229 for (i = vol->bcache_size; i < new_bcache_size; i++) {
233 new_bcache[i].
data = NULL;
235 i = vol->bcache_size;
238 if (vol->bcache != NULL)
240 vol->bcache = new_bcache;
241 vol->bcache_size = new_bcache_size;
246 if (vol->bcache[i].data == NULL) {
247 status =
fsw_alloc(vol->phys_blocksize, &vol->bcache[i].data);
251 status = vol->host_table->read_block(vol,
phys_bno, vol->bcache[i].data);
257 vol->bcache[i].refcount = 1;
258 *buffer_out = vol->bcache[i].data;
275 for (i = 0; i < vol->bcache_size; i++) {
276 if (vol->bcache[i].phys_bno ==
phys_bno && vol->bcache[i].refcount > 0)
277 vol->bcache[i].refcount--;
286static void fsw_blockcache_free(
struct fsw_volume *vol)
294 if (vol->
bcache != NULL) {
343 fsw_dnode_register(
vol, dno);
378 for (dno =
vol->dnode_head; dno; dno = dno->
next) {
399 if (parent_dno != NULL) {
411 fsw_dnode_register(
vol, dno);
457 if (
vol->dnode_head == dno)
461 vol->fstype_table->dnode_free(
vol, dno);
489 return dno->
vol->fstype_table->dnode_fill(dno->
vol, dno);
511 status = dno->
vol->fstype_table->dnode_stat(dno->
vol, dno, sb);
540 return dno->
vol->fstype_table->dir_lookup(dno->
vol, dno, lookup_name, child_dno_out);
555 struct fsw_string *lookup_path,
char separator,
565 remaining_path = *lookup_path;
569 for (root_if_empty = 1;
fsw_strlen(&remaining_path) > 0; root_if_empty = 0) {
574 lookup_name.
len, lookup_name.
data,
575 remaining_path.
len, remaining_path.
data));
579 child_dno = vol->
root;
621 if (dno->
parent == NULL) {
646 *child_dno_out = dno;
652 if (child_dno != NULL)
678 saved_pos = shand->
pos;
679 status = dno->
vol->fstype_table->dir_read(dno->
vol, dno, shand, child_dno_out);
681 shand->
pos = saved_pos;
705 return dno->
vol->fstype_table->readlink(dno->
vol, dno, target_name);
744 if ((
int)buffer_size < s.
size)
779 *target_dno_out = dno;
782 if (dno->
parent == NULL) {
865 fsw_u8 *buffer, *block_buffer;
867 fsw_u32 log_bno, pos_in_extent, phys_bno, pos_in_physblock;
871 *buffer_size_inout = 0;
877 buflen = *buffer_size_inout;
881 if (buflen > dno->
size - pos)
888 log_bno < shand->extent.log_start ||
911 if (copylen > buflen)
915 status =
fsw_block_get(vol, phys_bno, cache_level, (
void **)&block_buffer);
920 fsw_memcpy(buffer, block_buffer + pos_in_physblock, copylen);
925 if (copylen > buflen)
931 if (copylen > buflen)
942 *buffer_size_inout = (
fsw_u32)(pos - shand->
pos);
951 fsw_u32 array_capacity, array_len;
956#define START_BUF_SIZE 5
974 if (array_len == array_capacity) {
975 temp_arr_ptr = array;
981 for (i = 0; i < (
fsw_s64) array_len; ++i)
982 array[i] = temp_arr_ptr[i];
989 array = temp_arr_ptr;
1000 out_path->
len += array[array_len].
len + 1;
1006#define SEP_CHAR L'\\'
1009 if (out_path->
len == 0) {
1019 if (array_len > 0) {
1020 for (i = (
fsw_s64) array_len - 1; i >= 0; --i) {
1023 temp_char_ptr += array[i].
len;
1032 for (i = 0; i < (
fsw_s64) array_len; ++i)
1043 status =
vol->fstype_table->get_bless_info(
vol,
type, &dnode);
#define FSW_MSG_DEBUG(params)
fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_inout, void *buffer_in)
fsw_status_t fsw_dnode_stat(struct fsw_dnode *dno, struct fsw_dnode_stat *sb)
fsw_status_t fsw_dnode_fill(struct fsw_dnode *dno)
fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32 cache_level, void **buffer_out)
fsw_status_t fsw_dnode_create_root(struct fsw_volume *vol, fsw_u32 dnode_id, struct fsw_dnode **dno_out)
int fsw_dnode_is_root(struct fsw_dnode *dno)
fsw_status_t fsw_dnode_dir_read(struct fsw_shandle *shand, struct fsw_dnode **child_dno_out)
void fsw_shandle_close(struct fsw_shandle *shand)
fsw_status_t fsw_dnode_lookup_path(struct fsw_dnode *dno, struct fsw_string *lookup_path, char separator, struct fsw_dnode **child_dno_out)
void fsw_set_blocksize(struct fsw_volume *vol, fsw_u32 phys_blocksize, fsw_u32 log_blocksize)
fsw_status_t fsw_shandle_open(struct fsw_dnode *dno, struct fsw_shandle *shand)
fsw_status_t fsw_dnode_get_path(struct fsw_volume *vol, struct fsw_dnode *dno, struct fsw_string *out_path)
fsw_status_t fsw_volume_stat(struct fsw_volume *vol, struct fsw_volume_stat *sb)
void fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, void *buffer)
fsw_status_t fsw_dnode_lookup(struct fsw_dnode *dno, struct fsw_string *lookup_name, struct fsw_dnode **child_dno_out)
fsw_status_t fsw_get_bless_info(struct fsw_volume *vol, int type, struct fsw_string *out_path)
fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_dno_out)
fsw_status_t fsw_dnode_readlink_data(struct fsw_dnode *dno, struct fsw_string *link_target)
fsw_status_t fsw_mount(void *host_data, struct fsw_host_table *host_table, struct fsw_fstype_table *fstype_table, struct fsw_volume **vol_out)
void fsw_unmount(struct fsw_volume *vol)
fsw_status_t fsw_dnode_create(struct fsw_volume *vol, struct fsw_dnode *parent_dno, fsw_u32 dnode_id, int type, struct fsw_string *name, struct fsw_dnode **dno_out)
void fsw_dnode_release(struct fsw_dnode *dno)
void fsw_dnode_retain(struct fsw_dnode *dno)
fsw_status_t fsw_dnode_readlink(struct fsw_dnode *dno, struct fsw_string *target_name)
void fsw_dnode_mkcomplete(struct fsw_dnode *dno)
void fsw_strfree(struct fsw_string *s)
int fsw_streq_cstr(struct fsw_string *s1, const char *s2)
int fsw_strlen(struct fsw_string *s)
@ FSW_EXTENT_TYPE_PHYSBLOCK
@ FSW_EXTENT_TYPE_INVALID
fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src)
void fsw_strsplit(struct fsw_string *lookup_name, struct fsw_string *buffer, char separator)
fsw_status_t fsw_alloc_zero(int len, void **ptr_out)
@ FSW_STRING_TYPE_ISO88591
#define fsw_memcpy(dest, src, size)
#define fsw_memzero(dest, size)
#define fsw_alloc(size, ptrptr)
#define DivU64x32(x, y, z)
fsw_u32 phys_bno
Physical block number.
void * data
Block data buffer.
fsw_u32 refcount
Reference count.
fsw_u32 cache_level
Level of importance of this block.
fsw_u64 used_bytes
Bytes actually used by the file on disk.
struct VOLSTRUCTNAME * vol
The volume this dnode belongs to.
struct fsw_dnode * prev
Doubly-linked list of all dnodes: next dnode.
fsw_u32 dnode_id
Unique id number (usually the inode number)
fsw_u64 size
Data size in bytes.
struct fsw_dnode * next
Doubly-linked list of all dnodes: previous dnode.
fsw_u32 complete
Flag to be set on all dnode info was filled.
fsw_u32 refcount
Reference count.
struct DNODESTRUCTNAME * parent
Parent directory dnode.
int type
Type of the dnode - file, dir, symlink, special.
struct fsw_string name
Name of this item in the parent directory.
int type
Type of extent specification.
fsw_u32 log_count
Logical block count.
fsw_u32 log_start
Starting logical block number.
void * buffer
Allocated buffer pointer (for FSW_EXTENT_TYPE_BUFFER only)
fsw_u32 phys_start
Starting physical block number (for FSW_EXTENT_TYPE_PHYSBLOCK only)
fsw_u32 volume_struct_size
Size for allocating the fsw_volume structure.
fsw_status_t(* volume_stat)(struct VOLSTRUCTNAME *vol, struct fsw_volume_stat *sb)
void(* volume_free)(struct VOLSTRUCTNAME *vol)
fsw_status_t(* dir_lookup)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno, struct fsw_string *lookup_name, struct DNODESTRUCTNAME **child_dno)
fsw_status_t(* get_extent)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno, struct fsw_extent *extent)
fsw_status_t(* volume_mount)(struct VOLSTRUCTNAME *vol)
int native_string_type
String type used by the host environment.
void(* change_blocksize)(struct fsw_volume *vol, fsw_u32 old_phys_blocksize, fsw_u32 old_log_blocksize, fsw_u32 new_phys_blocksize, fsw_u32 new_log_blocksize)
struct fsw_extent extent
Current extent.
fsw_u64 pos
Current file pointer in bytes.
struct fsw_dnode * dnode
The dnode this handle reads data from.
void * data
Data pointer (may be NULL if type is EMPTY or len is zero)
int len
Length in characters.
int size
Total data size in bytes.
int type
Encoding of the string - empty, ISO-8859-1, UTF8, UTF16.
fsw_u32 phys_blocksize
Block size for disk access / file system structures.
struct fsw_blockcache * bcache
Array of block cache entries.
struct fsw_dnode * dnode_head
List of all dnodes allocated for this volume.
struct fsw_string label
Volume label.
fsw_u32 log_blocksize
Block size for logical file data.
int host_string_type
String type used by the host environment.
fsw_u32 bcache_size
Number of entries in the block cache array.
struct fsw_fstype_table * fstype_table
Dispatch table for file system specific functions.
struct fsw_host_table * host_table
Dispatch table for host-specific functions.
void * host_data
Hook for a host-specific data structure.
struct DNODESTRUCTNAME * root
Root directory dnode.