root/headers/private/userlandfs/legacy/cache.h
/*
        Copyright 1999-2001, Be Incorporated.   All Rights Reserved.
        This file may be used under the terms of the Be Sample Code License.
*/

#ifndef _CACHE_H_
#define _CACHE_H_

#include <BeBuild.h>

#include <legacy/lock.h>

#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL
#endif

typedef struct hash_ent {
        int              dev;
        off_t            bnum;
        off_t            hash_val;
        void            *data;
        struct hash_ent *next;
} hash_ent;


typedef struct hash_table {
    hash_ent **table;
    int        max;
    int        mask;          /* == max - 1 */
    int        num_elements;
} hash_table;


#define HT_DEFAULT_MAX   128


typedef struct cache_ent {
        int               dev;
        off_t             block_num;
        int               bsize;
        volatile int      flags;

        void             *data;
        void             *clone;         /* copy of data by set_block_info() */
        int               lock;

        void            (*func)(off_t bnum, size_t num_blocks, void *arg);
        off_t             logged_bnum;
        void             *arg;

        struct cache_ent *next,          /* points toward mru end of list */
                         *prev;          /* points toward lru end of list */

} cache_ent;

#define CE_NORMAL    0x0000     /* a nice clean pristine page */
#define CE_DIRTY     0x0002     /* needs to be written to disk */
#define CE_BUSY      0x0004     /* this block has i/o happening, don't touch it */


typedef struct cache_ent_list {
        cache_ent *lru;              /* tail of the list */
        cache_ent *mru;              /* head of the list */
} cache_ent_list;


typedef struct block_cache {
        struct lock             lock;
        int                             flags;
    int                         cur_blocks;
        int                             max_blocks;
        hash_table              ht;

        cache_ent_list  normal,       /* list of "normal" blocks (clean & dirty) */
                                        locked;       /* list of clean and locked blocks */
} block_cache;

#if 0   /* XXXdbg -- need to deal with write through caches */
#define DC_WRITE_THROUGH    0x0001  /* cache is write-through (for floppies) */
#endif

#define ALLOW_WRITES  1
#define NO_WRITES     0

#ifdef __cplusplus
        extern "C" {
#endif

extern _IMPEXP_KERNEL int   init_block_cache(int max_blocks, int flags);
extern _IMPEXP_KERNEL void  shutdown_block_cache(void);

extern _IMPEXP_KERNEL void  force_cache_flush(int dev, int prefer_log_blocks);
extern _IMPEXP_KERNEL int   flush_blocks(int dev, off_t bnum, int nblocks);
extern _IMPEXP_KERNEL int   flush_device(int dev, int warn_locked);

extern _IMPEXP_KERNEL int   init_cache_for_device(int fd, off_t max_blocks);
extern _IMPEXP_KERNEL int   remove_cached_device_blocks(int dev, int allow_write);

extern _IMPEXP_KERNEL void *get_block(int dev, off_t bnum, int bsize);
extern _IMPEXP_KERNEL void *get_empty_block(int dev, off_t bnum, int bsize);
extern _IMPEXP_KERNEL int   release_block(int dev, off_t bnum);
extern _IMPEXP_KERNEL int   mark_blocks_dirty(int dev, off_t bnum, int nblocks);


extern _IMPEXP_KERNEL int  cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int  cached_write(int dev, off_t bnum, const void *data,
                                  off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int  cached_write_locked(int dev, off_t bnum, const void *data,
                                                 off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int  set_blocks_info(int dev, off_t *blocks, int nblocks,
                                         void (*func)(off_t bnum, size_t nblocks, void *arg),
                                         void *arg);


extern _IMPEXP_KERNEL size_t read_phys_blocks (int fd, off_t bnum, void *data, uint num_blocks, int bsize);
extern _IMPEXP_KERNEL size_t write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize);

#ifdef __cplusplus
        }       // extern "C"
#endif

#endif /* _CACHE_H_ */