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
|
/*-
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
* See the file LICENSE for redistribution information.
*/
#include "wt_internal.h"
/*
* __wt_read --
* Read a chunk.
*/
int
__wt_read(
WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, void *buf)
{
size_t chunk;
size_t nr;
uint8_t *addr;
BOOL ret;
OVERLAPPED overlapped = { 0 };
nr = 0;
WT_STAT_FAST_CONN_INCR(session, read_io);
WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
"%s: read %zu bytes at offset %" PRIuMAX,
fh->name, len, (uintmax_t)offset));
/* Assert direct I/O is aligned and a multiple of the alignment. */
WT_ASSERT(session,
!fh->direct_io ||
S2C(session)->buffer_alignment == 0 ||
(!((uintptr_t)buf &
(uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
len >= S2C(session)->buffer_alignment &&
len % S2C(session)->buffer_alignment == 0));
/* Break reads larger than 1GB into 1GB chunks. */
for (addr = buf; len > 0; addr += nr, len -= (size_t)nr, offset += nr) {
chunk = WT_MIN(len, WT_GIGABYTE);
overlapped.Offset = UINT32_MAX & offset;
overlapped.OffsetHigh = UINT32_MAX & (offset >> 32);
if (!ReadFile(fh->filehandle, addr, chunk, &nr, &overlapped))
WT_RET_MSG(session, nr == 0 ? WT_ERROR : __wt_errno(),
"%s read error: failed to read %zu bytes at "
"offset %" PRIuMAX,
fh->name, chunk, (uintmax_t)offset);
}
return (0);
}
/*
* __wt_write --
* Write a chunk.
*/
int
__wt_write(WT_SESSION_IMPL *session,
WT_FH *fh, wt_off_t offset, size_t len, const void *buf)
{
size_t chunk;
size_t nw;
const uint8_t *addr;
OVERLAPPED overlapped = { 0 };
nw = 0;
WT_STAT_FAST_CONN_INCR(session, write_io);
WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
"%s: write %zu bytes at offset %" PRIuMAX,
fh->name, len, (uintmax_t)offset));
/* Assert direct I/O is aligned and a multiple of the alignment. */
WT_ASSERT(session,
!fh->direct_io ||
S2C(session)->buffer_alignment == 0 ||
(!((uintptr_t)buf &
(uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
len >= S2C(session)->buffer_alignment &&
len % S2C(session)->buffer_alignment == 0));
/* Break writes larger than 1GB into 1GB chunks. */
for (addr = buf; len > 0; addr += nw, len -= (size_t)nw, offset += nw) {
chunk = WT_MIN(len, WT_GIGABYTE);
overlapped.Offset = UINT32_MAX & offset;
overlapped.OffsetHigh = UINT32_MAX & (offset >> 32);
if (!WriteFile(fh->filehandle, addr, chunk, &nw, &overlapped))
WT_RET_MSG(session, __wt_errno(),
"%s write error: failed to write %zu bytes at "
"offset %" PRIuMAX,
fh->name, chunk, (uintmax_t)offset);
}
return (0);
}
|