1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* 2005-01-12 Paul McCullagh
23
#ifndef __xt_filesys_h__
24
#define __xt_filesys_h__
38
#define XT_FILE_IN_USE(x) ((x) == ERROR_SHARING_VIOLATION)
39
#define XT_FILE_ACCESS_DENIED(x) ((x) == ERROR_ACCESS_DENIED || (x) == ERROR_NETWORK_ACCESS_DENIED)
40
#define XT_FILE_TOO_MANY_OPEN(x) ((x) == ERROR_TOO_MANY_OPEN_FILES)
41
#define XT_FILE_NOT_FOUND(x) ((x) == ERROR_FILE_NOT_FOUND || (x) == ERROR_PATH_NOT_FOUND)
42
#define XT_FILE_NOT_FOUND_ERR ERROR_FILE_NOT_FOUND
43
#define XT_FILE_IN_USE_ERR ERROR_SHARING_VIOLATION
45
#define XT_FILE_IN_USE(x) ((x) == ETXTBSY)
46
#define XT_FILE_ACCESS_DENIED(x) ((x) == EACCES)
47
#define XT_FILE_TOO_MANY_OPEN(x) ((x) == EMFILE)
48
#define XT_FILE_NOT_FOUND(x) ((x) == ENOENT)
49
#define XT_FILE_NOT_FOUND_ERR ENOENT
50
#define XT_FILE_IN_USE_ERR ETXTBSY
55
#define XT_MASK ((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))
57
#define XT_FS_DEFAULT 0 /* Open for read/write, error if does not exist. */
58
#define XT_FS_READONLY 1 /* Open for read only (otherwize read/write). */
59
#define XT_FS_CREATE 2 /* Create if the file does not exist. */
60
#define XT_FS_EXCLUSIVE 4 /* Create, and generate an error if it already exists. */
61
#define XT_FS_MISSING_OK 8 /* Set this flag if you don't want to throw an error if the file does not exist! */
62
#define XT_FS_MAKE_PATH 16 /* Create the path if it does not exist. */
63
#define XT_FS_DIRECT_IO 32 /* Use direct I/O on this file if possible (O_DIRECT). */
66
* Various types of files:
67
* XT_FT_STANDARD - Normal file on disk.
68
* XT_FT_MEM_MAP - Normal file, handled internally using memory mapping.
69
* XT_FT_HEAP - File not on disk, only in RAM
70
* XT_FT_REWRITE_FLUSH - Standard file with re-write flushing
72
enum XTFileType { XT_FT_NONE, XT_FT_STANDARD, XT_FT_MEM_MAP, XT_FT_HEAP, XT_FT_REWRITE_FLUSH };
74
xtBool xt_fs_exists(char *path);
75
xtBool xt_fs_delete(struct XTThread *self, char *path);
76
xtBool xt_fs_file_not_found(int err);
77
void xt_fs_mkdir(struct XTThread *self, char *path);
78
void xt_fs_mkpath(struct XTThread *self, char *path);
79
xtBool xt_fs_rmdir(struct XTThread *self, char *path);
80
xtBool xt_fs_stat(struct XTThread *self, char *path, off_t *size, struct timespec *mod_time);
81
void xt_fs_move(struct XTThread *self, char *from_path, char *to_path);
82
xtBool xt_fs_rename(struct XTThread *self, char *from_path, char *to_path);
86
#define XT_NULL_FD INVALID_HANDLE_VALUE
89
#define XT_NULL_FD (-1)
92
/* Note, this lock must be re-entrant,
93
* The only lock that satifies this is
94
* FILE_MAP_USE_RWMUTEX!
96
* 20.05.2009: This problem should be fixed now with mf_slock_count!
98
* The lock need no longer be re-entrant
101
#define FILE_MAP_USE_PTHREAD_RW
103
//#define FILE_MAP_USE_PTHREAD_RW
104
#define FILE_MAP_USE_XSMUTEX
105
//#define FILE_MAP_USE_SPINXSLOCK
108
#if defined(FILE_MAP_USE_PTHREAD_RW)
109
#define FILE_MAP_LOCK_TYPE xt_rwlock_type
110
#define FILE_MAP_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, i)
111
#define FILE_MAP_FREE_LOCK(s, i) xt_free_rwlock(i)
112
#define FILE_MAP_READ_LOCK(i, o) do { xt_slock_rwlock_ns(i); (void) (o); } while(0)
113
#define FILE_MAP_WRITE_LOCK(i, o) do { xt_xlock_rwlock_ns(i); (void) (o); } while(0)
114
#define FILE_MAP_UNLOCK(i, o) do { xt_unlock_rwlock_ns(i); (void) (o); } while(0)
115
#elif defined(FILE_MAP_USE_XSMUTEX)
116
#define FILE_MAP_LOCK_TYPE XTMutexXSLockRec
117
#define FILE_MAP_INIT_LOCK(s, i) xt_xsmutex_init_with_autoname(s, i)
118
#define FILE_MAP_FREE_LOCK(s, i) xt_xsmutex_free(s, i)
119
#define FILE_MAP_READ_LOCK(i, o) xt_xsmutex_slock(i, o)
120
#define FILE_MAP_WRITE_LOCK(i, o) xt_xsmutex_xlock(i, o)
121
#define FILE_MAP_UNLOCK(i, o) xt_xsmutex_unlock(i, o)
122
#elif defined(FILE_MAP_USE_SPINXSLOCK)
123
#define FILE_MAP_LOCK_TYPE XTSpinXSLockRec
124
#define FILE_MAP_INIT_LOCK(s, i) xt_spinxslock_init_with_autoname(s, i)
125
#define FILE_MAP_FREE_LOCK(s, i) xt_spinxslock_free(s, i)
126
#define FILE_MAP_READ_LOCK(i, o) xt_spinxslock_slock(i, o)
127
#define FILE_MAP_WRITE_LOCK(i, o) xt_spinxslock_xlock(i, FALSE, o)
128
#define FILE_MAP_UNLOCK(i, o) xt_spinxslock_unlock(i, o)
130
#error Please define the lock type
134
#define RR_FLUSH_USE_PTHREAD_RW
136
//#define RR_FLUSH_USE_PTHREAD_RW
137
#define RR_FLUSH_USE_XSMUTEX
140
#if defined(RR_FLUSH_USE_PTHREAD_RW)
141
#define RR_FLUSH_LOCK_TYPE xt_rwlock_type
142
#define RR_FLUSH_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, i)
143
#define RR_FLUSH_FREE_LOCK(s, i) xt_free_rwlock(i)
144
#define RR_FLUSH_READ_LOCK(i, o) do { xt_slock_rwlock_ns(i); (void) (o); } while(0)
145
#define RR_FLUSH_WRITE_LOCK(i, o) do { xt_xlock_rwlock_ns(i); (void) (o); } while(0)
146
#define RR_FLUSH_UNLOCK(i, o) do { xt_unlock_rwlock_ns(i); (void) (o); } while(0)
147
#elif defined(RR_FLUSH_USE_XSMUTEX)
148
#define RR_FLUSH_LOCK_TYPE XTMutexXSLockRec
149
#define RR_FLUSH_INIT_LOCK(s, i) xt_xsmutex_init_with_autoname(s, i)
150
#define RR_FLUSH_FREE_LOCK(s, i) xt_xsmutex_free(s, i)
151
#define RR_FLUSH_READ_LOCK(i, o) xt_xsmutex_slock(i, o)
152
#define RR_FLUSH_WRITE_LOCK(i, o) xt_xsmutex_xlock(i, o)
153
#define RR_FLUSH_UNLOCK(i, o) xt_xsmutex_unlock(i, o)
155
#error Please define the lock type
158
typedef struct XTFileMemMap {
159
xtWord1 *mm_start; /* The in-memory start of the map. */
163
off_t mm_length; /* The length of the file map. */
164
FILE_MAP_LOCK_TYPE mm_lock; /* The file map R/W lock. */
165
size_t mm_grow_size; /* The amount by which the map file is increased. */
166
} XTFileMemMapRec, *XTFileMemMapPtr;
168
typedef struct XTFileHeap {
169
FILE_MAP_LOCK_TYPE fh_lock; /* A read/write lock for the memory. */
170
xtWord1 *fh_start; /* The start of the memory block. */
171
off_t fh_length; /* The length of the memory block. */
172
size_t fh_grow_size; /* The amount by which the memory block is increased. */
173
} XTFileHeapRec, *XTFileHeapPtr;
175
#define XT_REWRITE_MAX_BLOCKS 256
177
#define XT_REWRITE_BLOCK_DISTANCE (256*1024)
179
#define XT_REWRITE_BLOCK_DISTANCE (512*1024)
181
#define XT_REWRITE_BUFFER_SIZE (256*1024)
183
typedef struct RewriteBlock {
186
} RewriteBlockRec, *RewriteBlockPtr;
188
typedef struct XTRewriteFlush {
189
XTSpinLockRec rf_lock;
190
RR_FLUSH_LOCK_TYPE rf_write_lock;
191
size_t rf_block_count;
192
RewriteBlockRec rf_blocks[XT_REWRITE_MAX_BLOCKS];
193
xt_mutex_type rf_flush_lock;
194
size_t rf_flush_block_count;
195
RewriteBlockRec rf_flush_blocks[XT_REWRITE_MAX_BLOCKS];
196
xtWord4 rf_flush_offset_lo;
197
xtWord4 rf_flush_offset_hi;
198
xtWord1 rf_flush_buffer[XT_REWRITE_BUFFER_SIZE];
199
} XTRewriteFlushRec, *XTRewriteFlushPtr;
201
typedef struct XTFile {
203
u_int fil_ref_count; /* The number of open file structure referencing this file. */
205
u_int fil_id; /* This is used by the disk cache to identify a file in the hash index. */
206
XT_FD fil_filedes; /* The shared file descriptor (pread and pwrite allow this), on Windows this is used only for mmapped files */
207
u_int fil_handle_count; /* Number of references in the case of mmapped fil_filedes, both Windows and Unix */
209
XTRewriteFlushPtr fil_rewrite; /* Data above re-write blocks. */
210
XTFileMemMapPtr fil_memmap; /* Used if the file is memory mapped. */
211
XTFileHeapPtr fil_heap; /* Used if the file is of type "heap", in-memory only. Non-NULL, if the file "exists". */
213
} XTFileRec, *XTFilePtr;
215
typedef struct XTOpenFile {
218
u_int fr_id; /* Copied from above (small optimisation). */
219
u_int mf_slock_count;
222
XTFileMemMapPtr mf_memmap;
223
XTFileHeapPtr of_heap;
225
} XTOpenFileRec, *XTOpenFilePtr;
227
void xt_fs_init(struct XTThread *self);
228
void xt_fs_exit(struct XTThread *self);
230
XTFilePtr xt_fs_get_file(struct XTThread *self, char *file_namee, XTFileType type);
231
void xt_fs_release_file(struct XTThread *self, XTFilePtr file_ptr);
233
XTOpenFilePtr xt_open_file(struct XTThread *self, char *file, XTFileType type, int mode, size_t grow_size);
234
XTOpenFilePtr xt_open_file_ns(char *file, XTFileType type, int mode, size_t grow_size);
235
xtBool xt_open_file_ns(XTOpenFilePtr *fh, char *file, XTFileType type, int mode, size_t grow_size);
237
void xt_close_file(struct XTThread *self, XTOpenFilePtr f);
238
xtBool xt_close_file_ns(XTOpenFilePtr f);
239
char *xt_file_path(XTOpenFilePtr of);
241
xtBool xt_lock_file(struct XTThread *self, XTOpenFilePtr of);
242
void xt_unlock_file(struct XTThread *self, XTOpenFilePtr of);
244
off_t xt_seek_eof_file(struct XTThread *self, XTOpenFilePtr of);
245
xtBool xt_set_eof_file(struct XTThread *self, XTOpenFilePtr of, off_t offset);
247
xtBool xt_pwrite_file(XTOpenFilePtr of, off_t offset, size_t size, void *data, struct XTIOStats *timer, struct XTThread *thread);
248
xtBool xt_pread_file(XTOpenFilePtr of, off_t offset, size_t size, size_t min_size, void *data, size_t *red_size, struct XTIOStats *timer, struct XTThread *thread);
249
xtBool xt_pread_file_4(XTOpenFilePtr of, off_t offset, xtWord4 *value, struct XTIOStats *timer, struct XTThread *thread);
250
xtBool xt_flush_file(XTOpenFilePtr of, struct XTIOStats *timer, struct XTThread *thread);
252
xtBool xt_lock_file_ptr(XTOpenFilePtr of, xtWord1 **data, off_t offset, size_t size, struct XTIOStats *timer, struct XTThread *thread);
253
void xt_unlock_file_ptr(XTOpenFilePtr of, xtWord1 *data, struct XTThread *thread);
255
typedef struct XTOpenDir {
259
WIN32_FIND_DATA od_data;
263
/* WARNING: Solaris requires od_entry.d_name member to have size at least as returned
264
* by pathconf() function on per-directory basis. This makes it impossible to statically
265
* pre-set the size. So xt_dir_open on Solaris dynamically allocates space as needed.
267
* This also means that the od_entry member should always be last in the XTOpenDir structure.
269
struct dirent od_entry;
271
} XTOpenDirRec, *XTOpenDirPtr;
273
XTOpenDirPtr xt_dir_open(struct XTThread *self, c_char *path, c_char *filter);
274
void xt_dir_close(struct XTThread *self, XTOpenDirPtr od);
275
xtBool xt_dir_next(struct XTThread *self, XTOpenDirPtr od);
276
char *xt_dir_name(struct XTThread *self, XTOpenDirPtr od);
277
xtBool xt_dir_is_file(struct XTThread *self, XTOpenDirPtr od);
278
off_t xt_dir_file_size(struct XTThread *self, XTOpenDirPtr od);
281
typedef struct XTMapFile : public XTFileRef {
282
XTFileMemMapPtr mf_memmap;
283
} XTMapFileRec, *XTMapFilePtr;
285
XTMapFilePtr xt_open_fmap(struct XTThread *self, char *file, size_t grow_size);
286
void xt_close_fmap(struct XTThread *self, XTMapFilePtr map);
287
xtBool xt_close_fmap_ns(XTMapFilePtr map);
288
xtBool xt_pwrite_fmap(XTMapFilePtr map, off_t offset, size_t size, void *data, struct XTIOStats *timer, struct XTThread *thread);
289
xtBool xt_pread_fmap(XTMapFilePtr map, off_t offset, size_t size, size_t min_size, void *data, size_t *red_size, struct XTIOStats *timer, struct XTThread *thread);
290
xtBool xt_pread_fmap_4(XTMapFilePtr map, off_t offset, xtWord4 *value, struct XTIOStats *timer, struct XTThread *thread);
291
xtBool xt_flush_fmap(XTMapFilePtr map, struct XTIOStats *stat, struct XTThread *thread);
292
xtWord1 *xt_lock_fmap_ptr(XTMapFilePtr map, off_t offset, size_t size, struct XTIOStats *timer, struct XTThread *thread);
293
void xt_unlock_fmap_ptr(XTMapFilePtr map, struct XTThread *thread);
296
void xt_fs_copy_file(struct XTThread *self, char *from_path, char *to_path);
297
void xt_fs_copy_dir(struct XTThread *self, const char *from, const char *to);