1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_rw.c,v 1.14 2008/05/07 01:52:37 david Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_io --
15 *	Do an I/O.
16 */
17int
18__os_io(env, op, fhp, pgno, pgsize, relative, io_len, buf, niop)
19	ENV *env;
20	int op;
21	DB_FH *fhp;
22	db_pgno_t pgno;
23	u_int32_t pgsize, relative, io_len;
24	u_int8_t *buf;
25	size_t *niop;
26{
27	int ret;
28
29	MUTEX_LOCK(env, fhp->mtx_fh);
30
31	if ((ret = __os_seek(env, fhp, pgno, pgsize, relative)) != 0)
32		goto err;
33	switch (op) {
34	case DB_IO_READ:
35		ret = __os_read(env, fhp, buf, io_len, niop);
36		break;
37	case DB_IO_WRITE:
38		ret = __os_write(env, fhp, buf, io_len, niop);
39		break;
40	default:
41		ret = EINVAL;
42		break;
43	}
44
45err:	MUTEX_UNLOCK(env, fhp->mtx_fh);
46
47	return (ret);
48
49}
50
51/*
52 * __os_read --
53 *	Read from a file handle.
54 */
55int
56__os_read(env, fhp, addr, len, nrp)
57	ENV *env;
58	DB_FH *fhp;
59	void *addr;
60	size_t len;
61	size_t *nrp;
62{
63	FileInfo pInfo;
64	int ret;
65	size_t offset, nr;
66	char *taddr;
67
68	ret = 0;
69
70#if defined(HAVE_STATISTICS)
71	++fhp->read_count;
72#endif
73
74	for (taddr = addr, offset = 0, nr = 0;
75	    offset < len; taddr += nr, offset += (u_int32_t)nr) {
76		LAST_PANIC_CHECK_BEFORE_IO(env);
77		nr = (size_t)IFILE_Read(fhp->ifp, addr, len);
78		/* an error occured, or we reached the end of the file */
79		if (nr == 0)
80			break;
81	}
82	if (nr == 0) {
83		IFILE_GetInfo(fhp->ifp, &pInfo);
84		if (pInfo.dwSize != 0) {/* not an empty file */
85	/* if we have not reached the end of the file, we got an error in IFILE_Read */
86			if (IFILE_Seek(fhp->ifp, _SEEK_CURRENT, 0) != pInfo.dwSize) {
87				ret = __os_get_syserr();
88				__db_syserr(env, ret, "IFILE_Read: %#lx, %lu",
89				    P_TO_ULONG(addr), (u_long)len);
90				ret = __os_posix_err(ret);
91			}
92		}
93	}
94	*nrp = (size_t)(taddr - (u_int8_t *)addr);
95	return (ret);
96}
97
98/*
99 * __os_write --
100 *	Write to a file handle.
101 */
102int
103__os_write(env, fhp, addr, len, nwp)
104	ENV *env;
105	DB_FH *fhp;
106	void *addr;
107	size_t len;
108	size_t *nwp;
109{
110
111#ifdef HAVE_FILESYSTEM_NOTZERO
112	/* Zero-fill as necessary. */
113	if (__os_fs_notzero()) {
114		int ret;
115		if ((ret = __db_zero_fill(env, fhp)) != 0)
116			return (ret);
117	}
118#endif
119	return (__os_physwrite(env, fhp, addr, len, nwp));
120}
121
122/*
123 * __os_physwrite --
124 *	Physical write to a file handle.
125 */
126int
127__os_physwrite(env, fhp, addr, len, nwp)
128	ENV *env;
129	DB_FH *fhp;
130	void *addr;
131	size_t len;
132	size_t *nwp;
133{
134	int ret;
135
136	ret = 0;
137
138#if defined(HAVE_STATISTICS)
139	++fhp->write_count;
140#endif
141
142	LAST_PANIC_CHECK_BEFORE_IO(env);
143	if ((*nwp = (size_t)IFILE_Write(fhp->ifp, addr, len)) != len) {
144		ret = __os_get_syserr();
145		__db_syserr(env, ret, "IFILE_Write: %#lx, %lu",
146		    P_TO_ULONG(addr), (u_long)len);
147		ret = __os_posix_err(ret);
148	}
149	return (ret);
150}
151