1
/* $Id: sfdcdio.c,v 1.1.1.1 2004/12/23 04:04:17 ellson Exp $ $Revision: 1.1.1.1 $ */
2
/* vim:set shiftwidth=4 ts=8: */
4
/**********************************************************
5
* This software is part of the graphviz package *
6
* http://www.graphviz.org/ *
8
* Copyright (c) 1994-2004 AT&T Corp. *
9
* and is licensed under the *
10
* Common Public License, Version 1.0 *
13
* Information and Software Systems Research *
14
* AT&T Research, Florham Park NJ *
15
**********************************************************/
19
/* Discipline to turn on direct IO capability.
20
** This currently only works for XFS on SGI's.
22
** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
25
typedef struct _direct_s {
26
Sfdisc_t disc; /* Sfio discipline */
27
int cntl; /* file control flags */
28
#ifdef HAVE_STRUCT_DIOATTR
29
struct dioattr dio; /* direct IO params */
33
/* convert a pointer to an int */
34
#define P2I(p) (Sfulong_t)((char*)(p) - (char*)0)
36
#ifdef HAVE_STRUCT_DIOATTR
38
static ssize_t diordwr(Sfio_t * f, Void_t * buf, size_t n, Direct_t * di,
41
static ssize_t diordwr(f, buf, n, di, type)
52
done = 0; /* amount processed by direct IO */
54
if ((P2I(buf) % di->dio.d_mem) == 0 && (f->here % di->dio.d_miniosz) == 0 && n >= di->dio.d_miniosz) { /* direct IO ok, make sure we're in the right mode */
55
if (!(di->cntl & FDIRECT)) {
57
(void) fcntl(f->file, F_SETFL, di->cntl);
60
for (rw = (n / di->dio.d_miniosz) * di->dio.d_miniosz;;) {
63
if ((io = rw) > di->dio.d_maxiosz)
64
io = di->dio.d_maxiosz;
66
rv = read(f->file, buf, io);
68
rv = write(f->file, buf, io);
73
buf = (Void_t *) ((char *) buf + rv);
76
if (rv < io || rw < di->dio.d_miniosz)
81
if (done < n && (di->cntl & FDIRECT)) { /* turn off directIO for remaining IO operation */
83
(void) fcntl(f->file, F_SETFL, di->cntl);
86
if ((rw = n - done) > 0 &&
88
type == SF_READ ? read(f->file, buf, rw) : write(f->file, buf,
92
return done ? done : rv;
96
static ssize_t dioread(Sfio_t * f, Void_t * buf, size_t n, Sfdisc_t * disc)
98
static ssize_t dioread(f, buf, n, disc)
105
return diordwr(f, buf, n, (Direct_t *) disc, SF_READ);
109
static ssize_t diowrite(Sfio_t * f, const Void_t * buf, size_t n,
112
static ssize_t diowrite(f, buf, n, disc)
119
return diordwr(f, (Void_t *) buf, n, (Direct_t *) disc, SF_WRITE);
123
static int dioexcept(Sfio_t * f, int type, Void_t * data, Sfdisc_t * disc)
125
static int dioexcept(f, type, data, disc)
132
Direct_t *di = (Direct_t *) disc;
134
if (type == SF_FINAL || type == SF_DPOP) {
135
if (di->cntl & FDIRECT) {
136
di->cntl &= ~FDIRECT;
137
(void) fcntl(f->file, F_SETFL, di->cntl);
144
#endif /*HAVE_STRUCT_DIOATTR */
147
int sfdcdio(Sfio_t * f, size_t bufsize)
149
int sfdcdio(f, bufsize)
154
#ifndef HAVE_STRUCT_DIOATTR
162
if (f->extent < 0 || (f->flags & SF_STRING))
165
if ((cntl = fcntl(f->file, F_GETFL, 0)) < 0)
168
if (!(cntl & FDIRECT)) {
170
if (fcntl(f->file, F_SETFL, cntl) < 0)
174
if (fcntl(f->file, F_DIOINFO, &dio) < 0)
178
bufsize = (bufsize / dio.d_miniosz) * dio.d_miniosz;
180
bufsize = dio.d_miniosz * 64;
181
if (bufsize > dio.d_maxiosz)
182
bufsize = dio.d_maxiosz;
184
if (!(di = (Direct_t *) malloc(sizeof(Direct_t))))
187
if (!(buf = (Void_t *) memalign(dio.d_mem, bufsize))) {
192
sfsetbuf(f, buf, bufsize);
193
if (sfsetbuf(f, buf, 0) == buf)
194
sfset(f, SF_MALLOC, 1);
201
di->disc.readf = dioread;
202
di->disc.writef = diowrite;
203
di->disc.seekf = NIL(Sfseek_f);
204
di->disc.exceptf = dioexcept;
208
if (sfdisc(f, (Sfdisc_t *) di) != (Sfdisc_t *) di) {
212
(void) fcntl(f->file, F_SETFL, cntl);