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