Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/disc/sfdcdio.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#include "sfdchdr.h"
23
24
/* Discipline to turn on direct IO capability.
25
** This currently only works for XFS on SGI's.
26
**
27
** Written by Kiem-Phong Vo, [email protected], 03/18/1998.
28
*/
29
30
#ifndef FDIRECT
31
#undef F_DIOINFO
32
#endif
33
34
typedef struct _direct_s
35
{ Sfdisc_t disc; /* Sfio discipline */
36
int cntl; /* file control flags */
37
#ifdef F_DIOINFO
38
struct dioattr dio; /* direct IO params */
39
#endif
40
} Direct_t;
41
42
/* convert a pointer to an int */
43
#define P2I(p) (Sfulong_t)((char*)(p) - (char*)0)
44
45
#if __STD_C
46
static ssize_t diordwr(Sfio_t* f, Void_t* buf, size_t n, Direct_t* di, int type)
47
#else
48
static ssize_t diordwr(f, buf, n, di, type)
49
Sfio_t* f;
50
Void_t* buf;
51
size_t n;
52
Direct_t* di;
53
int type;
54
#endif
55
{
56
size_t rw, done;
57
ssize_t rv;
58
59
done = 0; /* amount processed by direct IO */
60
rv = 0;
61
62
#ifdef F_DIOINFO
63
if((P2I(buf)%di->dio.d_mem) == 0 &&
64
(f->here%di->dio.d_miniosz) == 0 && n >= di->dio.d_miniosz )
65
{ /* direct IO ok, make sure we're in the right mode */
66
if(!(di->cntl & FDIRECT) )
67
{ di->cntl |= FDIRECT;
68
(void)fcntl(f->file, F_SETFL, di->cntl);
69
}
70
71
for(rw = (n/di->dio.d_miniosz)*di->dio.d_miniosz;; )
72
{ size_t io;
73
74
if((io = rw) > di->dio.d_maxiosz )
75
io = di->dio.d_maxiosz;
76
if(type == SF_READ)
77
rv = read(f->file,buf,io);
78
else rv = write(f->file,buf,io);
79
80
if(rv > 0)
81
{ rw -= rv; done += rv;
82
buf = (Void_t*)((char*)buf + rv);
83
}
84
85
if(rv < io || rw < di->dio.d_miniosz)
86
break;
87
}
88
}
89
90
if(done < n && (di->cntl & FDIRECT) )
91
{ /* turn off directIO for remaining IO operation */
92
di->cntl &= ~FDIRECT;
93
(void)fcntl(f->file, F_SETFL, di->cntl);
94
}
95
#endif /*F_DIOINFO*/
96
97
if((rw = n-done) > 0 &&
98
(rv = type == SF_READ ? read(f->file,buf,rw) : write(f->file,buf,rw)) > 0 )
99
done += rv;
100
101
return done ? done : rv;
102
}
103
104
#if __STD_C
105
static ssize_t dioread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
106
#else
107
static ssize_t dioread(f, buf, n, disc)
108
Sfio_t* f;
109
Void_t* buf;
110
size_t n;
111
Sfdisc_t* disc;
112
#endif
113
{
114
return diordwr(f, buf, n, (Direct_t*)disc, SF_READ);
115
}
116
117
#if __STD_C
118
static ssize_t diowrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
119
#else
120
static ssize_t diowrite(f, buf, n, disc)
121
Sfio_t* f;
122
Void_t* buf;
123
size_t n;
124
Sfdisc_t* disc;
125
#endif
126
{
127
return diordwr(f, (Void_t*)buf, n, (Direct_t*)disc, SF_WRITE);
128
}
129
130
#if __STD_C
131
static int dioexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
132
#else
133
static int dioexcept(f,type,data,disc)
134
Sfio_t* f;
135
int type;
136
Void_t* data;
137
Sfdisc_t* disc;
138
#endif
139
{
140
Direct_t* di = (Direct_t*)disc;
141
142
if(type == SF_FINAL || type == SF_DPOP)
143
{
144
#ifdef F_DIOINFO
145
if(di->cntl&FDIRECT)
146
{ di->cntl &= ~FDIRECT;
147
(void)fcntl(f->file,F_SETFL,di->cntl);
148
}
149
#endif
150
free(disc);
151
}
152
153
return 0;
154
}
155
156
#if __STD_C
157
int sfdcdio(Sfio_t* f, size_t bufsize)
158
#else
159
int sfdcdio(f, bufsize)
160
Sfio_t* f;
161
size_t bufsize;
162
#endif
163
{
164
#ifndef F_DIOINFO
165
return -1;
166
#else
167
int cntl;
168
struct dioattr dio;
169
Void_t* buf;
170
Direct_t* di;
171
172
if(f->extent < 0 || (f->flags&SF_STRING))
173
return -1;
174
175
if((cntl = fcntl(f->file,F_GETFL,0)) < 0)
176
return -1;
177
178
if(!(cntl&FDIRECT) )
179
{ cntl |= FDIRECT;
180
if(fcntl(f->file,F_SETFL,cntl) < 0)
181
return -1;
182
}
183
184
if(fcntl(f->file,F_DIOINFO,&dio) < 0)
185
goto no_direct;
186
187
if(bufsize > 0)
188
bufsize = (bufsize/dio.d_miniosz)*dio.d_miniosz;
189
if(bufsize <= 0)
190
bufsize = dio.d_miniosz*64;
191
if(bufsize > dio.d_maxiosz)
192
bufsize = dio.d_maxiosz;
193
194
if(!(di = (Direct_t*)malloc(sizeof(Direct_t))) )
195
goto no_direct;
196
197
if(!(buf = (Void_t*)memalign(dio.d_mem,bufsize)) )
198
{ free(di);
199
goto no_direct;
200
}
201
202
sfsetbuf(f,buf,bufsize);
203
if(sfsetbuf(f,buf,0) == buf)
204
sfset(f,SF_MALLOC,1);
205
else
206
{ free(buf);
207
free(di);
208
goto no_direct;
209
}
210
211
di->disc.readf = dioread;
212
di->disc.writef = diowrite;
213
di->disc.seekf = NIL(Sfseek_f);
214
di->disc.exceptf = dioexcept;
215
di->cntl = cntl;
216
di->dio = dio;
217
218
if(sfdisc(f,(Sfdisc_t*)di) != (Sfdisc_t*)di)
219
{ free(di);
220
no_direct:
221
cntl &= ~FDIRECT;
222
(void)fcntl(f->file,F_SETFL,cntl);
223
return -1;
224
}
225
226
return 0;
227
228
#endif /*F_DIOINFO*/
229
}
230
231