1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/* $NetBSD$ */
/*
* File "udf.h" is part of the UDFclient toolkit.
* File $Id: udf_unix.h,v 1.5 2011/02/01 20:43:41 reinoud Exp $ $Name: $
*
* Copyright (c) 2003, 2004, 2005, 2006, 2011
* Reinoud Zandijk <reinoud@netbsd.org>
* All rights reserved.
*
* The UDFclient toolkit is distributed under the Clarified Artistic Licence.
* A copy of the licence is included in the distribution as
* `LICENCE.clearified.artistic' and a copy of the licence can also be
* requested at the GNU foundantion's website.
*
* Visit the UDFclient toolkit homepage http://www.13thmonkey.org/udftoolkit/
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _UDF_UNIX_H_
#define _UDF_UNIX_H_
#include "udf.h"
/* Predefines */
struct udf_pri_vol;
struct udf_node;
/*
* Provides :: system buffer structure for file/metadata caching
*
* ... free after struct buf ...
*/
struct udf_buf {
UDF_MUTEX(b_interlock);
uint32_t b_lblk; /* logical block number for vnode */
struct udf_node *b_vp; /* points to its parent udf_node */
uint32_t b_flags; /* B_* flags */
uint8_t *b_data; /* buffer itself */
uint8_t *b_private; /* private pointer for FS */
uint32_t b_bufsize; /* allocated size */
uint32_t b_bcount; /* size used */
uint32_t b_resid; /* size remaining */
LIST_ENTRY(udf_buf) b_hash;
TAILQ_ENTRY(udf_buf) b_vnbufs; /* used for vnode bufs */
TAILQ_ENTRY(udf_buf) b_lru; /* lru queue (reuse) */
};
TAILQ_HEAD(udf_buf_queue, udf_buf);
/*
* These flags are kept in b_flags. Copied from NetBSD's <sys/buf.h>
*/
#define B_AGE 0x00000001 /* Move to age queue when I/O done. */
#define B_ASYNC 0x00000004 /* Start I/O, do not wait. */
#define B_BAD 0x00000008 /* Bad block revectoring in progress. */
#define B_BUSY 0x00000010 /* I/O in progress. */
#define B_SCANNED 0x00000020 /* Block already pushed during sync */
#define B_CALL 0x00000040 /* Call b_iodone from biodone. */
#define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */
#define B_DIRTY 0x00000100 /* Dirty page to be pushed out async. */
#define B_DONE 0x00000200 /* I/O completed. */
#define B_EINTR 0x00000400 /* I/O was interrupted */
#define B_ERROR 0x00000800 /* I/O error occurred. */
#define B_GATHERED 0x00001000 /* LFS: already in a segment. */
#define B_INVAL 0x00002000 /* Does not contain valid info. */
#define B_LOCKED 0x00004000 /* Locked in core (not reusable). */
#define B_NOCACHE 0x00008000 /* Do not cache block after use. */
#define B_CACHE 0x00020000 /* Bread found us in the cache. */
#define B_PHYS 0x00040000 /* I/O to user memory. */
#define B_RAW 0x00080000 /* Set by physio for raw transfers. */
#define B_READ 0x00100000 /* Read buffer. */
#define B_TAPE 0x00200000 /* Magnetic tape I/O. */
#define B_WANTED 0x00800000 /* Process wants this buffer. */
#define B_WRITE 0x00000000 /* Write buffer (pseudo flag). */
#define B_XXX 0x02000000 /* Debugging flag. */
#define B_VFLUSH 0x04000000 /* Buffer is being synced. */
#define B_NEEDALLOC 0x08000000 /* TEMP */
#define BUF_FLAGBITS \
"\20\1AGE\3ASYNC\4BAD\5BUSY\6SCANNED\7CALL\10DELWRI" \
"\11DIRTY\12DONE\13EINTR\14ERROR\15GATHERED\16INVAL\17LOCKED\20NOCACHE" \
"\22CACHE\23PHYS\24RAW\25READ\26TAPE\30WANTED\32XXX\33VFLUSH"
struct udf_bufcache {
/* udf_node buf's multiplexed in one hashtable on (inode, b_lblk) */
LIST_HEAD(bufcache, udf_buf) udf_bufs[UDF_BUFCACHE_HASHSIZE];
UDF_MUTEX(bufcache_lock);
int32_t bcnt; /* temp var counting alloc/free */
uint32_t lru_len_data, lru_len_metadata;
uint32_t lru_len_dirty_data, lru_len_dirty_metadata;
struct udf_buf_queue lru_bufs_data;
struct udf_buf_queue lru_bufs_metadata;
/* thread support for bufs & nodes purge (bufcache emulation) */
pthread_t purgethread_id;
pthread_mutex_t purgethread_lock; /* lock the thread code out */
pthread_cond_t purgethread_signal; /* signal there is work to be done */
int purgethread_kicked; /* sanity for spurious wakeups */
pthread_mutex_t processed_lock; /* lock for main threads to wait on */
pthread_cond_t processed_signal; /* signals an action has been done */
int thread_active;
int finish_purgethread; /* ask thread to stop what its doing and exit */
int flushall; /* flusha all dirty buffers */
};
extern struct udf_bufcache *udf_bufcache;
/* bufcache emulation */
extern int udf_get_buf_entry(struct udf_node *udf_node, struct udf_buf **buf_entry_p);
extern void udf_free_buf_entry(struct udf_buf *buf_entry);
extern int udf_attach_buf_to_node(struct udf_node *udf_node, struct udf_buf *buf_entry);
extern int udf_detach_buf_from_node(struct udf_node *udf_node, struct udf_buf *buf_entry);
extern int udf_build_udf_node(struct udf_node *dir_node, struct fileid_desc *fid, struct udf_node **res_sub_node);
extern int udf_lookup_node_buf(struct udf_node *udf_node, uint32_t lblk, struct udf_buf **buf_p);
extern void udf_mark_buf_clean(struct udf_node *udf_node, struct udf_buf *buf_entry);
extern void udf_mark_buf_dirty(struct udf_node *udf_node, struct udf_buf *buf_entry);
/* maybe not strictly udf_unix */
extern void udf_mark_buf_needing_allocate(struct udf_node *udf_node, struct udf_buf *buf_entry);
extern void udf_mark_buf_allocated(struct udf_node *udf_node, struct udf_buf *buf_entry);
extern int udf_unix_init(void);
extern int udf_start_unix_thread(void);
extern int udf_stop_unix_thread(void); /* HELP ! need good clear closedown */
/* TEMP */
extern int udf_purgethread_kick(char *why);
#endif /* _UDF_UNIX_H_ */
|