summaryrefslogtreecommitdiff
path: root/open-vm-tools/lib/include/fileIO.h
blob: 1c26ed239bdecaf71046c790ebaa0ea594942980 (plain)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
/*********************************************************
 * Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation version 2.1 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *********************************************************/

/*
 * fileIO.h --
 *
 *	Host-independent wrapper for low-level fileIO functions.
 *
 */

/*
 * Note:
 *
 *  . FileIO_[Read|Write]() [read|write]s exactly the number of bytes requested
 *    unless an error occurs
 *  . FileIO_Seek() supports files larger than 2 GB
 *  . If a function returns a generic error, you can call your native function
 *    to retrieve the last error code
 */

#ifndef _FILEIO_H_
#define _FILEIO_H_

#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"

#include <stdio.h>
#include <stdlib.h>
#if !defined(_WIN32)
#include <sys/types.h>
#include <dirent.h>
#endif

#include "vm_basic_types.h"
#include "unicodeTypes.h"

#include "iovector.h"        // for struct iovec

struct FileLockToken;

#if defined(_WIN32)

# include <windows.h>

typedef struct FileIODescriptor {
   HANDLE                win32;
   uint32                flags;
   Unicode               fileName;
   struct FileLockToken *lockToken;
} FileIODescriptor;

#else

typedef struct FileIODescriptor {
   int                   posix;
   int                   flags;
   Unicode               fileName;
   struct FileLockToken *lockToken;
} FileIODescriptor;

#endif

typedef enum {
   /* distance is relative to the beginning of the file */
   FILEIO_SEEK_BEGIN,
   /* distance is relative to the current position in the file */
   FILEIO_SEEK_CURRENT,
   /* distance is relative to the end of the file */
   FILEIO_SEEK_END,
} FileIOSeekOrigin;

#define FILEIO_OPEN_ACCESS_READ  (1 << 0)
#define FILEIO_OPEN_ACCESS_WRITE (1 << 1)
/*
 * Use synchronous writes (no lazy buffer cache flush)
 */
#define FILEIO_OPEN_SYNC         (1 << 2)
/*
 * Delete the file as soon as possible (i.e. when nobody uses it anymore)
 */
#define FILEIO_OPEN_DELETE_ASAP  (1 << 3)
#define FILEIO_OPEN_UNBUFFERED   (1 << 4)
/*
 * Lock the file on open
 */
#define FILEIO_OPEN_LOCKED       (1 << 5)
/*
 * Asynchronous file I/O
 */
#define FILEIO_ASYNCHRONOUS      (1 << 6)
/*
 * Open non-blocking mode
 */
#define FILEIO_OPEN_NONBLOCK     (1 << 7)
/*
 * Open with more privileges
 */
#define FILEIO_OPEN_PRIVILEGED   (1 << 8)
/*
 * Open exclusive.
 * On Windows host it doesn't pass the flag FILE_SHARE_(READ|WRITE) to
 * CreateFile. Right now, EXCLUSIVE_READ is not used and EXCLUSIVE_WRITE
 * is only used by the cdrom code to implement the exclusive option.
 * On Linux hosts, it passes O_EXCL if both are set.
 * By default, we share r/w. -Maxime
 */
#define FILEIO_OPEN_EXCLUSIVE_READ     (1 << 9)
#define FILEIO_OPEN_EXCLUSIVE_WRITE    (1 << 10)
/*
 * Open sequential.
 * This flag only changes the behavior on Windows host. It is off by default.
 */
#define  FILEIO_OPEN_SEQUENTIAL_SCAN   (1 << 11)
/*
 * Make IOCTL be run by root.  This flag only changes the behavior on Linux
 * host. It is off by default.
 *
 * XXX: This has nothing to do with fileIO, but since AIOMgr shares the flags
 * with fileIO, I had to add it here.  In some future it would be nice to
 * unshare the flags between the two at which point this could be fixed.
 * --Tommy
 */
#define  FILEIO_OPEN_PRIVILEGED_IOCTL  (1 << 12)
/*
 * Lock the file on open with a exclusive leased lock that can be broken
 * (supported on ESX file systems)
 */
#define FILEIO_OPEN_EXCLUSIVE_LOCK       (1 << 13)
/*
 * Lock the file on open with a multiwriter leased lock that can be broken
 * (supported on ESX file systems)
 */
#define FILEIO_OPEN_MULTIWRITER_LOCK     (1 << 14)
/*
 * Flag the file to be cached by the vBlob caching layer
 */
#define FILEIO_OPEN_USE_AIO_CACHE        (1 << 15)
/*
 * Valid only for MacOS. It eventually results into O_EXLOCK flag passed to open
 * system call.
 *
 * O_EXLOCK, O_SHLOCK behavior is tested on Mac OS X Server 10.6, kernel 10.0.0.
 *
 * |                      | Block devices      | Regular files
 * |----------------------|--------------------|----------------
 * | Locking behavior     | mandatory          | advisory
 * |                      |                    |
 * | If O_NONBLOCK absent | open doesn't block | open blocks
 * |                      | on conflicts       | on conflicts
 */
#define FILEIO_OPEN_EXCLUSIVE_LOCK_MACOS (1 << 16)
/*
 * Open file in APPEND-only mode.  All writes go to the current end of file,
 * not to the current file pointer location.
 */
#define FILEIO_OPEN_APPEND               (1 << 17)
/*
 * Valid only on POSIXen. Don't follow a symbolic link.
 */
#define FILEIO_OPEN_ACCESS_NOFOLLOW (1 << 18)
/*
 * Valid only on Windows. Set FILE_SHARE_DELETE.
 */
#define FILEIO_OPEN_SHARE_DELETE (1 << 19)
/*
 * Strengths of file lock.
 * Advisory:
 *   Must use FileIO plus lock flags to get locking.
 *   Never uses kernel/fs-level lock, so naked open() bypasses locking.
 * Mandatory:
 *   Requires kernel/fs-level, so naked open() respects lock.
 *   Kernel/fs-level locks are available on ESX but not hosted.
 * Best:
 *   Adaptively picks between mandatory and advisory.
 * Almost all cases should use the "best" lock.
 */
#define FILEIO_OPEN_LOCK_BEST         FILEIO_OPEN_LOCKED /* historical */
#define FILEIO_OPEN_LOCK_ADVISORY     (1 << 20)
#define FILEIO_OPEN_LOCK_MANDATORY    (1 << 21)

/*
 * OPTIMISTIC is an alternative to EXCLUSIVE and MANDATORY. It applies
 * only on ESX, and gives VMkernel permission to use a type of lock
 * called "optimistic" to speed up opens. Rule-of-thumb is to use it
 * only for read-only opens of small files (< 1KB).
 */
#define FILEIO_OPEN_OPTIMISTIC_LOCK   (1 << 22)

/*
 * Flag passed to open() to not attempt to get the lun attributes as part of
 * the open operation. Applicable only to opening of SCSI devices. This
 * definition must match the definition of USEROBJ_OPEN_NOATTR in
 * user_vsiTypes.h and FS_OPEN_NOATTR in fs_public.h
 */
#define O_NOATTR 0x04000000
// Flag passed to open() to get multiwriter VMFS lock.  This definition must
// match USEROBJ_OPEN_MULTIWRITER_LOCK in user_vsiTypes.h.
#define O_MULTIWRITER_LOCK 0x08000000
// Flag passed to open() to get exclusive VMFS lock.  This definition must
// match USEROBJ_OPEN_EXCLUSIVE_LOCK in user_vsiTypes.h.
#define O_EXCLUSIVE_LOCK 0x10000000
// Flag passed to open() to enable use of oplocks on VMFS.  This definition
// must match USEROBJ_OPEN_OPTIMISTIC_LOCK in user_vsiTypes.h.
#define O_OPTIMISTIC_LOCK 0x00400000

/* File Access check args */
#define FILEIO_ACCESS_READ       (1 << 0)
#define FILEIO_ACCESS_WRITE      (1 << 1)
#define FILEIO_ACCESS_EXEC       (1 << 2)
#define FILEIO_ACCESS_EXISTS     (1 << 3)

typedef enum {               //  File doesn't exist   File exists
   FILEIO_OPEN,              //  error
   FILEIO_OPEN_EMPTY,        //  error               size = 0
   FILEIO_OPEN_CREATE,       //  create
   FILEIO_OPEN_CREATE_SAFE,  //  create              error
   FILEIO_OPEN_CREATE_EMPTY, //  create              size = 0
} FileIOOpenAction;

typedef enum {
   /*
    * Generic status codes
    */

   /* No error */
   FILEIO_SUCCESS,
   /* The user cancelled the operation */
   FILEIO_CANCELLED,
   /* Generic error */
   FILEIO_ERROR,

   /*
    * Status codes specific to FileIO_Open()
    */

   /* FILEIO_OPEN_CREATE_SAFE was used and the file already existed */
   FILEIO_OPEN_ERROR_EXIST,

   /* Couldn't obtain the requested lock */
   FILEIO_LOCK_FAILED,

   /* Status codes specific to FileIO_Read() */

   /* Tried to read beyond the end of a file */
   FILEIO_READ_ERROR_EOF,

   /* Couldnt locate file */
   FILEIO_FILE_NOT_FOUND,

   /* Insufficient Permissions */
   FILEIO_NO_PERMISSION,

   /* File name too long */
   FILEIO_FILE_NAME_TOO_LONG,
   /*
    * Status codes specific for FileIO_Write()
    */

   /* Attempts to write  file that exceeds maximum file size */
   FILEIO_WRITE_ERROR_FBIG,

   /* The device containint the file has no room for the data */
   FILEIO_WRITE_ERROR_NOSPC,

   /* Attempts to write file that exceeds user's disk quota */
   FILEIO_WRITE_ERROR_DQUOT,

   /*
    * NB: Until disklib error handling is changed, there must be no more
    *     than 16 total error codes here.
    */
   FILEIO_ERROR_LAST,  /* Must be last! */

} FileIOResult;

const char *FileIO_MsgError(FileIOResult status);

void FileIO_Invalidate(FileIODescriptor *file);

Bool FileIO_IsValid(const FileIODescriptor *fd);

FileIOResult FileIO_Create(FileIODescriptor *file,
                           ConstUnicode pathName,
                           int access,
                           FileIOOpenAction action,
                           int mode);

FileIOResult FileIO_Open(FileIODescriptor *file,
                         ConstUnicode pathName,
                         int access,
                         FileIOOpenAction action);

FileIOResult FileIO_OpenRetry(FileIODescriptor *file,
                              ConstUnicode pathName,
                              int access,
                              FileIOOpenAction action,
                              uint32 msecMaxWaitTime);

uint64 FileIO_Seek(const FileIODescriptor *file,
                   int64 distance,
                   FileIOSeekOrigin origin);

FileIOResult FileIO_Read(FileIODescriptor *file,
                         void *buf,
                         size_t requested,
                         size_t *actual);

FileIOResult FileIO_Write(FileIODescriptor *file,
                          const void *buf,
                          size_t requested,
                          size_t *actual);

Unicode FileIO_AtomicTempPath(ConstUnicode path);

FileIOResult FileIO_AtomicTempFile(FileIODescriptor *fileFD,
                                   FileIODescriptor *tempFD);

Bool FileIO_AtomicUpdate(FileIODescriptor *newFD,
                         FileIODescriptor *currFD);

#if !defined(VMX86_TOOLS) || !defined(__FreeBSD__)

FileIOResult FileIO_Readv(FileIODescriptor *fd,
                          struct iovec  *v,
                          int count,
                          size_t totalSize,
                          size_t *bytesRead);

FileIOResult FileIO_Writev(FileIODescriptor *fd,
                           struct iovec *v,
                           int count,
                           size_t totalSize,
                           size_t *bytesWritten);
#endif

FileIOResult FileIO_Preadv(FileIODescriptor *fd,   // IN: File descriptor
                           struct iovec *entries,  // IN: Vector to read into
                           int numEntries,         // IN: Number of vector entries
                           uint64 offset,          // IN: Offset to start reading
                           size_t totalSize,       // IN: totalSize (bytes) in entries
                           size_t *actual);        // OUT: number of bytes read

FileIOResult FileIO_Pwritev(FileIODescriptor *fd,  // IN: File descriptor
                            struct iovec *entries, // IN: Vector to write from
                            int numEntries,        // IN: Number of vector entries
                            uint64 offset,         // IN: Offset to start writing
                            size_t totalSize,      // IN: Total size (bytes) in entries
                            size_t *actual);       // OUT: number of bytes written

FileIOResult FileIO_Pread(FileIODescriptor *fd,    // IN: File descriptor
                          void *buf,               // IN: Buffer to read into
                          size_t len,              // IN: Length of the buffer
                          uint64 offset);          // IN: Offset to start reading

FileIOResult FileIO_Pwrite(FileIODescriptor *fd,   // IN: File descriptor
                           void const *buf,        // IN: Buffer to write from
                           size_t len,             // IN: Length of the buffer
                           uint64 offset);         // IN: Offset to start writing

FileIOResult FileIO_Access(ConstUnicode pathName,
                           int accessMode);

Bool    FileIO_Truncate(FileIODescriptor *file,
                        uint64 newSize);

int     FileIO_Sync(const FileIODescriptor *file);

FileIOResult FileIO_GetAllocSize(const FileIODescriptor *fd,
                                 uint64 *logicalBytes,
                                 uint64 *allocedBytes);
int64   FileIO_GetSize(const FileIODescriptor *fd);

Bool    FileIO_SetAllocSize(const FileIODescriptor *fd, uint64 size);

FileIOResult FileIO_GetAllocSizeByPath(ConstUnicode pathName,
                                       uint64 *logicalBytes,
                                       uint64 *allocedBytes);

int64   FileIO_GetSizeByPath(ConstUnicode pathName);

Bool    FileIO_Close(FileIODescriptor *file);

Bool    FileIO_CloseAndUnlink(FileIODescriptor *file);

uint32  FileIO_GetFlags(FileIODescriptor *file);

Bool    FileIO_GetVolumeSectorSize(const char *name,
                                   uint32 *sectorSize);

Bool    FileIO_SupportsFileSize(const FileIODescriptor *file,
                                uint64 testSize);

int64   FileIO_GetModTime(const FileIODescriptor *fd);

FileIOResult FileIO_Lock(FileIODescriptor *file,
                         int access);

FileIOResult FileIO_Unlock(FileIODescriptor *file);

/* Only users not using FileIO_Open should use these two */
void FileIO_Init(FileIODescriptor *fd,
                 ConstUnicode pathName);

void FileIO_Cleanup(FileIODescriptor *fd);

const char *FileIO_ErrorEnglish(FileIOResult status);

void FileIO_OptionalSafeInitialize(void);

#if defined(_WIN32)
FileIODescriptor FileIO_CreateFDWin32(HANDLE win32,
                                      DWORD access,
                                      DWORD attributes);
#else
FileIODescriptor FileIO_CreateFDPosix(int posix,
                                      int flags);

int FileIO_PrivilegedPosixOpen(ConstUnicode pathName,
                               int flags);
#endif

FILE *FileIO_DescriptorToStream(FileIODescriptor *fd,
                                Bool textMode);

ConstUnicode FileIO_Filename(FileIODescriptor *fd);

/*
 *-------------------------------------------------------------------------
 * 
 * FileIO_IsSuccess --
 *
 *      Returns TRUE if the error code is success.
 *
 * Result:
 *      TRUE/FALSE.
 *
 * Side effects:
 *      None.
 *
 *-------------------------------------------------------------------------
 */

#if !defined(sun) || __GNUC__ >= 3
static INLINE Bool
FileIO_IsSuccess(FileIOResult res)      // IN
{
   return res == FILEIO_SUCCESS;
}
#else
/*
 * XXX: Crosscompiler used for Solaris tools builds (gcc 2.95.3) complains
 * whenever the above definition is unused, even though that shouldn't be
 * a problem for static functions that are also inline.  So for Solaris, we
 * have a separate definition that is neither static nor inline.
 */
Bool FileIO_IsSuccess(FileIOResult res);
#endif

Bool FileIO_SupportsPrealloc(const char *pathName, Bool fsCheck);

#endif // _FILEIO_H_