Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / vol / ihandle.h
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 /* An IHandle_t is an abstraction allowing the file and volume operations to
11 * pass the elements required to identify a file to the underlying file
12 * systen. For the usual Vice inode operations, this is no more than the
13 * usual device and inode numbers. For the user space file system used on NT
14 * we also need the volume id to identify the file.
15 *
16 * An FdHandle_t is an abstraction used to associate file descroptors
17 * with Inode handles. IH_OPEN is used to get a file descriptor that
18 * can be used in subsequent I/O operations. File descriptor handles are
19 * cached by IO_CLOSE. To make sure a file descriptor is really closed call
20 * IH_REALLYCLOSE.
21 *
22 * Note that IH_REALLYCLOSE does not guarantee that all file descriptors are
23 * closed (or are marked as needing close) by the time it returns, in the case
24 * of an IH_OPEN being executed in parallel. If a separate thread is running
25 * an IH_OPEN on the same IHandle_t at around the same time, it is possible for
26 * it to open the file, then IH_REALLYCLOSE runs, and then IH_OPEN associates
27 * the file handle with the IHandle_t. For this reason, it is probably an
28 * error if it is ever possible to have an IH_OPEN call run at the same time as
29 * an IH_REALLYCLOSE call on the same IHandle_t. If such functionality is
30 * required, ihandle must be changed to accomodate this.
31 *
32 * The IHandle_t also provides a place to do other optimizations. In the
33 * NT user space file system, we keep a separate special file for the
34 * link counts and using the IHandle_t allows keeping the details of
35 * that at a lower level than the IDEC and IINC calls.
36 *
37 * To use the IHandle_t there are a new set of IH_xxxx/FDH_XXXX operations.
38 * Each takes a pointer to an IHandle_t or an FdHandle_t as the first
39 * argument. This pointer is considered an in/out variable. In particular,
40 * the open file descriptors for a given Inode are stored in a linked list
41 * of FdHandle_t hanging off of each IHandle_t. IH_OPEN returns NULL on error,
42 * and a valid FdHandle_t otherwise. All other IH_xxxx/FDH_xxxx macros return
43 * -1 on error and 0 on success.
44 *
45 * Inode handle operations:
46 * IH_INIT - Initialize the Inode handle with the device, volume id, and ino
47 * IH_COPY - Copy Inode handle info to a new handle with no open descriptors.
48 * IH_REALLYCLOSE - Close all cached file descriptors for Inode handle
49 * IH_RELEASE - release a Inode handle, close all cached file descriptors
50 * IH_CONDSYNC - snyc the Inode if it has any open file descriptors
51 *
52 * Inode operation replacements:
53 * IH_CREATE - create a file in the underlying filesystem and setup the
54 * information needed to reference this file in the IHandle_t.
55 * IH_OPEN - open the file belonging to the associated inode and set the
56 * file descriptor.
57 * IH_IREAD/IH_IWRITE - read/write an Inode.
58 * IH_INC/IH_DEC - increment/decrement the link count.
59 *
60 * Replacements for C runtime file operations
61 * FDH_READ/FDH_WRITE - read/write using the file descriptor.
62 * FDH_READV/FDH_WRITEV - readv/writev (Unix only)
63 * FDH_SEEK - set file handle's read/write position
64 * FDH_CLOSE - return a file descriptor to the cache
65 * FDH_REALLYCLOSE - Close a file descriptor, do not return to the cache
66 * FDH_SYNC - Unconditionally sync an open file.
67 * FDH_TRUNC - Truncate a file
68 * FDH_LOCKFILE - Lock a whole file
69 * FDH_UNLOCKFILE - Unlock a whole file
70 *
71 * status information:
72 * FDH_SIZE - returns the size of the file.
73 * FDH_NLINK - returns the link count of the file.
74 * FDH_ISUNLINKED - returns if the file has been unlinked out from under us
75 *
76 * Miscellaneous:
77 * FDH_FDOPEN - create a descriptor for buffered I/O
78 * STREAM_READ/STREAM_WRITE - buffered file I/O
79 */
80
81 #ifndef _IHANDLE_H_
82 #define _IHANDLE_H_
83
84 #ifdef AFS_PTHREAD_ENV
85 # include <pthread.h>
86 extern pthread_once_t ih_glock_once;
87 extern pthread_mutex_t ih_glock_mutex;
88 extern void ih_glock_init(void);
89 # define IH_LOCK \
90 do { opr_Verify(pthread_once(&ih_glock_once, ih_glock_init) == 0); \
91 opr_mutex_enter(&ih_glock_mutex); \
92 } while (0)
93 # define IH_UNLOCK opr_mutex_exit(&ih_glock_mutex)
94 #else /* AFS_PTHREAD_ENV */
95 # define IH_LOCK
96 # define IH_UNLOCK
97 #endif /* AFS_PTHREAD_ENV */
98
99 #ifndef DLL_INIT_LIST
100 /*
101 * Macro to initialize a doubly linked list, lifted from Encina
102 */
103 # define DLL_INIT_LIST(head, tail) \
104 do { \
105 (head) = NULL; \
106 (tail) = NULL; \
107 } while(0)
108
109 /*
110 * Macro to remove an element from a doubly linked list
111 */
112 # define DLL_DELETE(ptr,head,tail,next,prev) \
113 do { \
114 if ((ptr)->next) \
115 (ptr)->next->prev = (ptr)->prev; \
116 else \
117 (tail) = (ptr)->prev; \
118 if ((ptr)->prev) \
119 (ptr)->prev->next = (ptr)->next; \
120 else \
121 (head) = (ptr)->next; \
122 (ptr)->next = (ptr)->prev = NULL; \
123 opr_Assert(!(head) || !((head)->prev)); \
124 } while(0)
125
126 /*
127 * Macro to insert an element at the tail of a doubly linked list
128 */
129 # define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
130 do { \
131 (ptr)->next = NULL; \
132 (ptr)->prev = (tail); \
133 (tail) = (ptr); \
134 if ((ptr)->prev) \
135 (ptr)->prev->next = (ptr); \
136 else \
137 (head) = (ptr); \
138 opr_Assert((head) && ((head)->prev == NULL)); \
139 } while(0)
140
141 #endif /* DLL_INIT_LIST */
142
143 #ifdef AFS_NT40_ENV
144 typedef __int64 Inode;
145 #else
146 # include <afs/afssyscalls.h>
147 #endif
148
149 /* The dir package's page hashing function is dependent upon the layout of
150 * IHandle_t as well as the containing DirHandle in viced/viced.h. Make
151 * Sure the volume id is still used as the hash after any changes to either
152 * structure.
153 */
154
155 /* forward declaration */
156 struct IHandle_s;
157
158 /* File descriptors are HANDLE's on NT. The following typedef helps catch
159 * type errors. duplicated in libadmin/vos/afs_vosAdmin.c
160 */
161 #ifdef AFS_NT40_ENV
162 typedef HANDLE FD_t;
163 # define INVALID_FD INVALID_HANDLE_VALUE
164 #else
165 typedef int FD_t;
166 # define INVALID_FD ((FD_t)-1)
167 #endif
168
169 /* file descriptor handle */
170 typedef struct FdHandle_s {
171 int fd_status; /* status flags */
172 int fd_refcnt; /* refcnt */
173 FD_t fd_fd; /* file descriptor */
174 struct IHandle_s *fd_ih; /* Pointer to Inode handle */
175 struct FdHandle_s *fd_next; /* LRU/Avail list pointers */
176 struct FdHandle_s *fd_prev;
177 struct FdHandle_s *fd_ihnext; /* Inode handle's list of file descriptors */
178 struct FdHandle_s *fd_ihprev;
179 } FdHandle_t;
180
181 /* File descriptor status values */
182 #define FD_HANDLE_AVAIL 1 /* handle is not open and available */
183 #define FD_HANDLE_OPEN 2 /* handle is open and not in use */
184 #define FD_HANDLE_INUSE 3 /* handle is open and in use */
185 #define FD_HANDLE_CLOSING 4 /* handle is open, in use, and has been
186 * IH_REALLYCLOSE'd. It should not be
187 * used for subsequent opens. */
188
189 /* buffered file descriptor handle */
190 #define STREAM_HANDLE_BUFSIZE 2048 /* buffer size for STR_READ/STR_WRITE */
191 typedef struct StreamHandle_s {
192 FD_t str_fd; /* file descriptor */
193 int str_direction; /* current read/write direction */
194 afs_sfsize_t str_buflen; /* bytes remaining in buffer */
195 afs_foff_t str_bufoff; /* current offset into buffer */
196 afs_foff_t str_fdoff; /* current offset into file */
197 int str_error; /* error code */
198 int str_eof; /* end of file flag */
199 struct StreamHandle_s *str_next; /* Avail list pointers */
200 struct StreamHandle_s *str_prev;
201 char str_buffer[STREAM_HANDLE_BUFSIZE]; /* data buffer */
202 } StreamHandle_t;
203
204 #define STREAM_DIRECTION_NONE 1 /* stream is in initial mode */
205 #define STREAM_DIRECTION_READ 2 /* stream is in input mode */
206 #define STREAM_DIRECTION_WRITE 3 /* stream is in output mode */
207
208 /* number handles allocated at a shot */
209 #define I_HANDLE_MALLOCSIZE ((size_t)((4096/sizeof(IHandle_t))))
210 #define FD_HANDLE_MALLOCSIZE ((size_t)((4096/sizeof(FdHandle_t))))
211 #define STREAM_HANDLE_MALLOCSIZE 1
212
213 /* Possible values for the vol_io_params.sync_behavior option.
214 * These dictate what actually happens when you call FDH_SYNC or IH_CONDSYNC. */
215 #define IH_SYNC_ALWAYS (1) /* This makes FDH_SYNCs do what you'd probably
216 * expect: a synchronous fsync() */
217 #define IH_SYNC_ONCLOSE (2) /* This makes FDH_SYNCs just flag the ih as "I
218 * need to sync", and does not perform the actual
219 * fsync() until we IH_REALLYCLOSE. This provides a
220 * little assurance over IH_SYNC_NEVER when a volume
221 * has gone offline, and a few other situations. */
222 #define IH_SYNC_NEVER (3) /* This makes FDH_SYNCs do nothing. Faster, but
223 * obviously less durable. The OS may ensure that
224 * our data hits the disk eventually, depending on
225 * the platform and various OS-specific tuning
226 * parameters. */
227
228
229 /* READ THIS.
230 *
231 * On modern platforms tuned for I/O intensive workloads, there may be
232 * thousands of file descriptors available (64K on 32-bit Solaris 7,
233 * for example), and threading in Solaris 9 and Linux 2.6 (NPTL) are
234 * tuned for (many) thousands of concurrent threads at peak.
235 *
236 * On these platforms, it makes sense to allow administrators to set
237 * appropriate limits for their hardware. Clients may now set desired
238 * values in the exported vol_io_params, of type ih_init_params.
239 */
240
241 typedef struct ih_init_params
242 {
243 afs_uint32 fd_handle_setaside; /* for non-cached i/o, trad. was 128 */
244 afs_uint32 fd_initial_cachesize; /* what was 'default' */
245 afs_uint32 fd_max_cachesize; /* max open files if large-cache activated */
246
247 int sync_behavior; /* one of the IH_SYNC_* constants */
248 } ih_init_params;
249
250 /* Number of file descriptors needed for non-cached I/O */
251 #define FD_HANDLE_SETASIDE 128 /* Match to MAX_FILESERVER_THREAD */
252
253 /* Which systems have 8-bit fileno? On GNU/Linux systems, the
254 * fileno member of FILE is an int. On NetBSD 5, it's a short.
255 * Ditto for OpenBSD 4.5. Through Solaris 10 8/07 it's unsigned char.
256 */
257
258 /* Don't try to have more than 256 files open at once if you are planning
259 * to use fopen or fdopen. The FILE structure has an eight bit field for
260 * the file descriptor. */
261 #define FD_DEFAULT_CACHESIZE (255-FD_HANDLE_SETASIDE)
262
263 /* We need some limit on the number of files open at once. Some systems
264 * say we can open lots of files, but when we do they run out of slots
265 * in the file table.
266 */
267 #define FD_MAX_CACHESIZE (2000 - FD_HANDLE_SETASIDE)
268
269 /* On modern platforms, this is sized higher than the note implies.
270 * For HP, see http://forums11.itrc.hp.com/service/forums/questionanswer.do?admit=109447626+1242508538748+28353475&threadId=302950
271 * On AIX, it's said to be self-tuning (sar -v)
272 * On Solaris, http://www.princeton.edu/~unix/Solaris/troubleshoot/kerntune.html
273 * says stdio limit (FILE) may exist, but then backtracks and says the 64bit
274 * solaris and POLL (rather than select) io avoid the issue. Solaris Internals
275 * states that Solaris 7 and above deal with up to 64K on 32bit.
276 * However, extended FILE must be enabled to use this. See
277 * enable_extended_FILE_stdio(3C)
278 */
279
280 /* Inode handle */
281 typedef struct IHandle_s {
282 VolumeId ih_vid; /* Parent volume id. */
283 int ih_dev; /* device id. */
284 int ih_flags; /* Flags */
285 int ih_synced; /* should be synced next time */
286 Inode ih_ino; /* Inode number */
287 int ih_refcnt; /* reference count */
288 struct FdHandle_s *ih_fdhead; /* List of open file desciptors */
289 struct FdHandle_s *ih_fdtail;
290 struct IHandle_s *ih_next; /* Links for avail list/hash chains */
291 struct IHandle_s *ih_prev;
292 } IHandle_t;
293
294 /* Flags for the Inode handle */
295 #define IH_REALLY_CLOSED 1
296
297 /* Hash function for inode handles */
298 #define I_HANDLE_HASH_SIZE 2048 /* power of 2 */
299
300 /* The casts to int's ensure NT gets the xor operation correct. */
301 #define IH_HASH(D, V, I) ((int)(((D)^(V)^((int)(I)))&(I_HANDLE_HASH_SIZE-1)))
302
303 /*
304 * Hash buckets for inode handles
305 */
306 typedef struct IHashBucket_s {
307 IHandle_t *ihash_head;
308 IHandle_t *ihash_tail;
309 } IHashBucket_t;
310
311 /* Prototypes for handle support routines. */
312 #ifdef AFS_NAMEI_ENV
313 # ifdef AFS_NT40_ENV
314 # include "ntops.h"
315 # endif
316 # include "namei_ops.h"
317
318 extern void ih_clear(IHandle_t * h);
319 extern Inode ih_create(IHandle_t * h, int dev, char *part, Inode nI, int p1,
320 int p2, int p3, int p4);
321 extern FD_t *ih_fdopen(FdHandle_t * h, char *fdperms);
322 #endif /* AFS_NAMEI_ENV */
323
324 /*
325 * Prototypes for file descriptor cache routines
326 */
327 extern void ih_PkgDefaults(void);
328 extern void ih_Initialize(void);
329 extern void ih_UseLargeCache(void);
330 extern int ih_SetSyncBehavior(const char *behavior);
331 extern IHandle_t *ih_init(int /*@alt Device@ */ dev, int /*@alt VolId@ */ vid,
332 Inode ino);
333 extern IHandle_t *ih_copy(IHandle_t * ihP);
334 extern FdHandle_t *ih_open(IHandle_t * ihP);
335 extern int fd_close(FdHandle_t * fdP);
336 extern int fd_reallyclose(FdHandle_t * fdP);
337 extern StreamHandle_t *stream_fdopen(FD_t fd);
338 extern StreamHandle_t *stream_open(const char *file, const char *mode);
339 extern afs_sfsize_t stream_read(void *ptr, afs_fsize_t size,
340 afs_fsize_t nitems, StreamHandle_t * streamP);
341 extern afs_sfsize_t stream_write(void *ptr, afs_fsize_t size,
342 afs_fsize_t nitems,
343 StreamHandle_t * streamP);
344 extern int stream_aseek(StreamHandle_t * streamP, afs_foff_t offset);
345 extern int stream_flush(StreamHandle_t * streamP);
346 extern int stream_close(StreamHandle_t * streamP, int reallyClose);
347 extern int ih_reallyclose(IHandle_t * ihP);
348 extern int ih_release(IHandle_t * ihP);
349 extern int ih_condsync(IHandle_t * ihP);
350 extern FdHandle_t *ih_attachfd(IHandle_t * ihP, FD_t fd);
351
352 /* Macros common to user space and inode API's. */
353 #define IH_INIT(H, D, V, I) ((H) = ih_init((D), (V), (I)))
354
355 #define IH_COPY(D, S) ((D) = ih_copy(S))
356
357 #define IH_NLINK(H) ih_nlink(H)
358
359 #define IH_OPEN(H) ih_open(H)
360
361 #define FDH_CLOSE(H) (fd_close(H), (H)=NULL)
362
363 #define FDH_REALLYCLOSE(H) (fd_reallyclose(H), (H)=NULL)
364
365 #define FDH_FDOPEN(H, A) stream_fdopen((H)->fd_fd)
366
367 #define STREAM_FDOPEN(A, B) stream_fdopen(A)
368
369 #define STREAM_OPEN(A, B) stream_open(A, B)
370
371 #define STREAM_READ(A, B, C, H) stream_read(A, B, C, H)
372
373 #define STREAM_WRITE(A, B, C, H) stream_write(A, B, C, H)
374
375 #define STREAM_ASEEK(H, A) stream_aseek(H, A)
376
377 #define STREAM_FLUSH(H) stream_flush(H)
378
379 #define STREAM_ERROR(H) ((H)->str_error)
380
381 #define STREAM_EOF(H) ((H)->str_eof)
382
383 #define STREAM_CLOSE(H) stream_close(H, 0)
384
385 #define STREAM_REALLYCLOSE(H) stream_close(H, 1)
386
387 #define IH_RELEASE(H) (ih_release(H), (H)=NULL)
388
389 #define IH_REALLYCLOSE(H) ih_reallyclose(H)
390
391 #define IH_CONDSYNC(H) ih_condsync(H)
392
393 #ifdef HAVE_PIO
394 # define AFS_IHANDLE_PIO_ENV 1
395 # ifdef O_LARGEFILE
396 # define OS_PREAD(FD, B, S, O) pread64(FD, B, S, O)
397 # define OS_PWRITE(FD, B, S, O) pwrite64(FD, B, S, O)
398 # else /* !O_LARGEFILE */
399 # define OS_PREAD(FD, B, S, O) pread(FD, B, S, O)
400 # define OS_PWRITE(FD, B, S, O) pwrite(FD, B, S, O)
401 # endif /* !O_LARGEFILE */
402 #elif defined(AFS_NT40_ENV)
403 # define AFS_IHANDLE_PIO_ENV 1
404 # define OS_PREAD(FD, B, S, O) nt_pread(FD, B, S, O)
405 # define OS_PWRITE(FD, B, S, O) nt_pwrite(FD, B, S, O)
406 #else
407 extern ssize_t ih_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset);
408 extern ssize_t ih_pwrite(FD_t fd, const void * buf, size_t count, afs_foff_t offset);
409 # define OS_PREAD(FD, B, S, O) ih_pread(FD, B, S, O)
410 # define OS_PWRITE(FD, B, S, O) ih_pwrite(FD, B, S, O)
411 #endif
412
413 #ifdef AFS_NT40_ENV
414 # define OS_LOCKFILE(FD, O) (!LockFile(FD, (DWORD)((O) & 0xFFFFFFFF), (DWORD)((O) >> 32), 2, 0))
415 # define OS_UNLOCKFILE(FD, O) (!UnlockFile(FD, (DWORD)((O) & 0xFFFFFFFF), (DWORD)((O) >> 32), 2, 0))
416 # define OS_ERROR(X) nterr_nt2unix(GetLastError(), X)
417 # define OS_UNLINK(X) nt_unlink(X)
418 /* we can't have a file unlinked out from under us on NT */
419 # define OS_ISUNLINKED(X) (0)
420 # define OS_DIRSEP "\\"
421 # define OS_DIRSEPC '\\'
422 #else
423 # define OS_LOCKFILE(FD, O) flock(FD, LOCK_EX)
424 # define OS_UNLOCKFILE(FD, O) flock(FD, LOCK_UN)
425 # define OS_ERROR(X) X
426 # define OS_UNLINK(X) unlink(X)
427 # define OS_ISUNLINKED(X) ih_isunlinked(X)
428 extern int ih_isunlinked(FD_t fd);
429 # define OS_DIRSEP "/"
430 # define OS_DIRSEPC '/'
431 #endif
432
433 #if defined(AFS_NT40_ENV) || !defined(AFS_NAMEI_ENV)
434 # define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \
435 ih_icreate_init(H, D, P, N, P1, P2, P3, P4)
436 #endif
437
438 #ifdef AFS_NAMEI_ENV
439
440 # ifdef AFS_NT40_ENV
441 # define OS_OPEN(F, M, P) nt_open(F, M, P)
442 # define OS_CLOSE(FD) nt_close(FD)
443
444 # define OS_READ(FD, B, S) nt_read(FD, B, S)
445 # define OS_WRITE(FD, B, S) nt_write(FD, B, S)
446 # define OS_SEEK(FD, O, F) nt_seek(FD, O, F)
447
448 # define OS_SYNC(FD) nt_fsync(FD)
449 # define OS_TRUNC(FD, L) nt_ftruncate(FD, L)
450
451 # else /* AFS_NT40_ENV */
452
453 /*@+fcnmacros +macrofcndecl@*/
454 # ifdef S_SPLINT_S
455 extern Inode IH_CREATE(IHandle_t * H, int /*@alt Device @ */ D,
456 char *P, Inode N, int /*@alt VolumeId @ */ P1,
457 int /*@alt VnodeId @ */ P2,
458 int /*@alt Unique @ */ P3,
459 int /*@alt unsigned @ */ P4);
460 extern FD_t OS_IOPEN(IHandle_t * H);
461 extern int OS_OPEN(const char *F, int M, mode_t P);
462 extern int OS_CLOSE(FD_t FD);
463 extern ssize_t OS_READ(FD_t FD, void *B, size_t S);
464 extern ssize_t OS_WRITE(FD_t FD, void *B, size_t S);
465 extern ssize_t OS_PREAD(FD_t FD, void *B, size_t S, afs_foff_t O);
466 extern ssize_t OS_PWRITE(FD_t FD, void *B, size_t S, afs_foff_t O);
467 extern int OS_SYNC(FD_t FD);
468 extern afs_sfsize_t OS_SIZE(FD_t FD);
469 extern int IH_INC(IHandle_t * H, Inode I, int /*@alt VolId, VolumeId @ */ P);
470 extern int IH_DEC(IHandle_t * H, Inode I, int /*@alt VolId, VolumeId @ */ P);
471 extern afs_sfsize_t IH_IREAD(IHandle_t * H, afs_foff_t O, void *B,
472 afs_fsize_t S);
473 extern afs_sfsize_t IH_IWRITE(IHandle_t * H, afs_foff_t O, void *B,
474 afs_fsize_t S);
475 # ifdef O_LARGEFILE
476 # define OFFT off64_t
477 # else
478 # define OFFT off_t
479 # endif
480
481 extern OFFT OS_SEEK(FD_t FD, OFFT O, int F);
482 extern int OS_TRUNC(FD_t FD, OFFT L);
483 # endif /*S_SPLINT_S */
484
485 # ifdef O_LARGEFILE
486 # define OS_OPEN(F, M, P) open64(F, M, P)
487 # else /* !O_LARGEFILE */
488 # define OS_OPEN(F, M, P) open(F, M, P)
489 # endif /* !O_LARGEFILE */
490 # define OS_CLOSE(FD) close(FD)
491
492 # define OS_READ(FD, B, S) read(FD, B, S)
493 # define OS_WRITE(FD, B, S) write(FD, B, S)
494 # ifdef O_LARGEFILE
495 # define OS_SEEK(FD, O, F) lseek64(FD, (off64_t) (O), F)
496 # define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
497 # else /* !O_LARGEFILE */
498 # define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
499 # define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
500 # endif /* !O_LARGEFILE */
501
502 # define OS_SYNC(FD) fsync(FD)
503 # define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \
504 namei_icreate_init(H, D, P, P1, P2, P3, P4)
505
506 /*@=fcnmacros =macrofcndecl@*/
507 # endif /* AFS_NT40_ENV */
508 # define IH_INC(H, I, P) namei_inc(H, I, P)
509 # define IH_DEC(H, I, P) namei_dec(H, I, P)
510 # define IH_IREAD(H, O, B, S) namei_iread(H, O, B, S)
511 # define IH_IWRITE(H, O, B, S) namei_iwrite(H, O, B, S)
512 # define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
513 namei_icreate(H, P, P1, P2, P3, P4)
514 # define OS_IOPEN(H) namei_iopen(H)
515
516
517 #else /* AFS_NAMEI_ENV */
518 extern Inode ih_icreate(IHandle_t * ih, int dev, char *part, Inode nI, int p1,
519 int p2, int p3, int p4);
520
521 # define IH_CREATE(H, D, P, N, P1, P2, P3, P4) \
522 ih_icreate(H, D, P, N, P1, P2, P3, P4)
523
524 # ifdef AFS_LINUX22_ENV
525 # define OS_IOPEN(H) -1
526 # else
527 # ifdef O_LARGEFILE
528 # define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR|O_LARGEFILE))
529 # else
530 # define OS_IOPEN(H) (IOPEN((H)->ih_dev, (H)->ih_ino, O_RDWR))
531 # endif
532 # endif
533 # define OS_OPEN(F, M, P) open(F, M, P)
534 # define OS_CLOSE(FD) close(FD)
535
536 # define OS_READ(FD, B, S) read(FD, B, S)
537 # define OS_WRITE(FD, B, S) write(FD, B, S)
538 # ifdef O_LARGEFILE
539 # define OS_SEEK(FD, O, F) lseek64(FD, (off64_t) (O), F)
540 # define OS_TRUNC(FD, L) ftruncate64(FD, (off64_t) (L))
541 # else /* !O_LARGEFILE */
542 # define OS_SEEK(FD, O, F) lseek(FD, (off_t) (O), F)
543 # define OS_TRUNC(FD, L) ftruncate(FD, (off_t) (L))
544 # endif /* !O_LARGEFILE */
545
546 # define OS_SYNC(FD) fsync(FD)
547
548 # ifdef AFS_LINUX22_ENV
549 # define IH_INC(H, I, P) -1
550 # define IH_DEC(H, I, P) -1
551 # define IH_IREAD(H, O, B, S) -1
552 # define IH_IWRITE(H, O, B, S) -1
553 # else
554 # define IH_INC(H, I, P) IINC((H)->ih_dev, I, P)
555 # define IH_DEC(H, I, P) IDEC((H)->ih_dev, I, P)
556 # define IH_IREAD(H, O, B, S) inode_read((H)->ih_dev, (H)->ih_ino, (H)->ih_vid,\
557 O, B, S)
558 # define IH_IWRITE(H, O, B, S) \
559 inode_write((H)->ih_dev, (H)->ih_ino, (H)->ih_vid, O, B, S)
560 # endif /* AFS_LINUX22_ENV */
561
562 #endif /* AFS_NAMEI_ENV */
563
564 #define OS_SIZE(FD) ih_size(FD)
565 extern afs_sfsize_t ih_size(FD_t);
566
567 #ifndef AFS_NT40_ENV
568 # define FDH_READV(H, I, N) readv((H)->fd_fd, I, N)
569 # define FDH_WRITEV(H, I, N) writev((H)->fd_fd, I, N)
570 #endif
571
572 #ifdef HAVE_PIOV
573 # ifdef O_LARGEFILE
574 # define FDH_PREADV(H, I, N, O) preadv64((H)->fd_fd, I, N, O)
575 # define FDH_PWRITEV(H, I, N, O) pwritev64((H)->fd_fd, I, N, O)
576 # else /* !O_LARGEFILE */
577 # define FDH_PREADV(H, I, N, O) preadv((H)->fd_fd, I, N, O)
578 # define FDH_PWRITEV(H, I, N, O) pwritev((H)->fd_fd, I, N, O)
579 # endif /* !O_LARGEFILE */
580 #endif
581
582 #define FDH_PREAD(H, B, S, O) OS_PREAD((H)->fd_fd, B, S, O)
583 #define FDH_PWRITE(H, B, S, O) OS_PWRITE((H)->fd_fd, B, S, O)
584 #define FDH_READ(H, B, S) OS_READ((H)->fd_fd, B, S)
585 #define FDH_WRITE(H, B, S) OS_WRITE((H)->fd_fd, B, S)
586 #define FDH_SEEK(H, O, F) OS_SEEK((H)->fd_fd, O, F)
587
588 #define FDH_SYNC(H) ih_fdsync(H)
589 #define FDH_TRUNC(H, L) OS_TRUNC((H)->fd_fd, L)
590 #define FDH_SIZE(H) OS_SIZE((H)->fd_fd)
591 #define FDH_LOCKFILE(H, O) OS_LOCKFILE((H)->fd_fd, O)
592 #define FDH_UNLOCKFILE(H, O) OS_UNLOCKFILE((H)->fd_fd, O)
593 #define FDH_ISUNLINKED(H) OS_ISUNLINKED((H)->fd_fd)
594
595 extern int ih_fdsync(FdHandle_t *fdP);
596
597 #ifdef AFS_NT40_ENV
598 # define afs_stat_st __stat64
599 # define afs_stat _stat64
600 # define afs_fstat _fstat64
601 # define afs_fopen fopen
602 # define afs_open open
603 # define afs_lseek(FD, O, F) _lseeki64(FD, O, F)
604 #else /* AFS_NT40_ENV */
605 # ifdef O_LARGEFILE
606 # define afs_stat_st stat64
607 # define afs_stat stat64
608 # define afs_fstat fstat64
609 # define afs_fopen fopen64
610 # define afs_open open64
611 # ifdef S_SPLINT_S
612 extern off64_t afs_lseek(int FD, off64_t O, int F);
613 # endif /*S_SPLINT_S */
614 # define afs_lseek(FD, O, F) lseek64(FD, (off64_t) (O), F)
615 # define afs_ftruncate ftruncate64
616 # define afs_mmap mmap64
617 # ifdef AFS_AIX_ENV
618 extern void * mmap64(); /* ugly hack since aix build env appears to be somewhat broken */
619 # endif
620 # else /* !O_LARGEFILE */
621 # define afs_stat_st stat
622 # define afs_stat stat
623 # define afs_fstat fstat
624 # define afs_fopen fopen
625 # define afs_open open
626 # ifdef S_SPLINT_S
627 extern off_t afs_lseek(int FD, off_t O, int F);
628 # endif /*S_SPLINT_S */
629 # define afs_lseek(FD, O, F) lseek(FD, (off_t) (O), F)
630 # define afs_ftruncate ftruncate
631 # define afs_mmap mmap
632 # endif /* !O_LARGEFILE */
633 # if AFS_HAVE_STATVFS64
634 # define afs_statvfs statvfs64
635 # else
636 # if AFS_HAVE_STATFS64
637 # define afs_statfs statfs64
638 # else
639 # if AFS_HAVE_STATVFS
640 # define afs_statvfs statvfs
641 # else
642 # define afs_statfs statfs
643 # endif /* !AFS_HAVE_STATVFS */
644 # endif /* !AFS_HAVE_STATFS64 */
645 # endif /* !AFS_HAVE_STATVFS64 */
646 #endif /* !AFS_NT40_ENV */
647
648 #endif /* _IHANDLE_H_ */