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
|
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1997,2007 Oracle. All rights reserved.
*
* $Id: os_rw.c,v 1.6 2007/05/17 15:15:47 bostic Exp $
*/
#include "db_config.h"
#include "db_int.h"
/*
* __os_io --
* Do an I/O.
*/
int
__os_io(dbenv, op, fhp, pgno, pgsize, relative, io_len, buf, niop)
DB_ENV *dbenv;
int op;
DB_FH *fhp;
db_pgno_t pgno;
u_int32_t pgsize, relative, io_len;
u_int8_t *buf;
size_t *niop;
{
int ret;
MUTEX_LOCK(dbenv, fhp->mtx_fh);
if ((ret = __os_seek(dbenv, fhp, pgno, pgsize, relative)) != 0)
goto err;
switch (op) {
case DB_IO_READ:
ret = __os_read(dbenv, fhp, buf, io_len, niop);
break;
case DB_IO_WRITE:
ret = __os_write(dbenv, fhp, buf, io_len, niop);
break;
default:
ret = EINVAL;
break;
}
err: MUTEX_UNLOCK(dbenv, fhp->mtx_fh);
return (ret);
}
/*
* __os_read --
* Read from a file handle.
*/
int
__os_read(dbenv, fhp, addr, len, nrp)
DB_ENV *dbenv;
DB_FH *fhp;
void *addr;
size_t len;
size_t *nrp;
{
FileInfo pInfo;
int ret;
ret = 0;
if ((*nrp = (size_t)IFILE_Read(fhp->ifp, addr, len)) != len) {
IFILE_GetInfo(fhp->ifp, &pInfo);
if (pInfo.dwSize != 0) {
ret = __os_get_syserr();
__db_syserr(dbenv, ret, "IFILE_Read: %#lx, %lu",
P_TO_ULONG(addr), (u_long)len);
ret = __os_posix_err(ret);
}
}
return (ret);
}
/*
* __os_write --
* Write to a file handle.
*/
int
__os_write(dbenv, fhp, addr, len, nwp)
DB_ENV *dbenv;
DB_FH *fhp;
void *addr;
size_t len;
size_t *nwp;
{
#ifdef HAVE_FILESYSTEM_NOTZERO
/* Zero-fill as necessary. */
if (__os_fs_notzero()) {
int ret;
if ((ret = __os_zerofill(dbenv, fhp)) != 0)
return (ret);
}
#endif
return (__os_physwrite(dbenv, fhp, addr, len, nwp));
}
/*
* __os_physwrite --
* Physical write to a file handle.
*/
int
__os_physwrite(dbenv, fhp, addr, len, nwp)
DB_ENV *dbenv;
DB_FH *fhp;
void *addr;
size_t len;
size_t *nwp;
{
int ret;
/*
* Make a last "panic" check. Imagine a thread of control running in
* Berkeley DB, going to sleep. Another thread of control decides to
* run recovery because the environment is broken. The first thing
* recovery does is panic the existing environment, but we only check
* the panic flag when crossing the public API. If the sleeping thread
* wakes up and writes something, we could have two threads of control
* writing the log files at the same time. So, before writing, make a
* last panic check. Obviously, there's still a window, but it's very,
* very small.
*/
PANIC_CHECK(dbenv);
ret = 0;
if ((*nwp = (size_t)IFILE_Write(fhp->ifp, addr, len)) != len) {
ret = __os_get_syserr();
__db_syserr(dbenv, ret, "IFILE_Write: %#lx, %lu",
P_TO_ULONG(addr), (u_long)len);
ret = __os_posix_err(ret);
}
return (ret);
}
|