📄 sfdcdio.c
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved. */#include "sfdchdr.h"/* Discipline to turn on direct IO capability.** This currently only works for XFS on SGI's.**** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.*/#ifndef FDIRECT#undef F_FIOINFO#endiftypedef struct _direct_s{ Sfdisc_t disc; /* Sfio discipline */ int cntl; /* file control flags */#ifdef F_DIOINFO struct dioattr dio; /* direct IO params */#endif} Direct_t;/* convert a pointer to an int */#define P2I(p) (Sfulong_t)((char*)(p) - (char*)0)#if __STD_Cstatic ssize_t diordwr(Sfio_t* f, Void_t* buf, size_t n, Direct_t* di, int type)#elsestatic ssize_t diordwr(f, buf, n, di, type)Sfio_t* f;Void_t* buf;size_t n;Direct_t* di;int type;#endif{ size_t rw, done; ssize_t rv; done = 0; /* amount processed by direct IO */#ifdef F_DIOINFO 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 */ if(!(di->cntl & FDIRECT) ) { di->cntl |= FDIRECT; (void)fcntl(f->file, F_SETFL, di->cntl); } for(rw = (n/di->dio.d_miniosz)*di->dio.d_miniosz;; ) { size_t io; if((io = rw) > di->dio.d_maxiosz ) io = di->dio.d_maxiosz; if(type == SF_READ) rv = read(f->file,buf,io); else rv = write(f->file,buf,io); if(rv > 0) { rw -= rv; done += rv; buf = (Void_t*)((char*)buf + rv); } if(rv < io || rw < di->dio.d_miniosz) break; } } if(done < n && (di->cntl & FDIRECT) ) { /* turn off directIO for remaining IO operation */ di->cntl &= ~FDIRECT; (void)fcntl(f->file, F_SETFL, di->cntl); }#endif /*F_DIOINFO*/ if((rw = n-done) > 0 && (rv = type == SF_READ ? read(f->file,buf,rw) : write(f->file,buf,rw)) > 0 ) done += rv; return done ? done : rv;}#if __STD_Cstatic ssize_t dioread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)#elsestatic ssize_t dioread(f, buf, n, disc)Sfio_t* f;Void_t* buf;size_t n;Sfdisc_t* disc;#endif{ return diordwr(f, buf, n, (Direct_t*)disc, SF_READ);}#if __STD_Cstatic ssize_t diowrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)#elsestatic ssize_t diowrite(f, buf, n, disc)Sfio_t* f;Void_t* buf;size_t n;Sfdisc_t* disc;#endif{ return diordwr(f, (Void_t*)buf, n, (Direct_t*)disc, SF_WRITE);}#if __STD_Cstatic int dioexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)#elsestatic int dioexcept(f,type,data,disc)Sfio_t* f;int type;Void_t* data;Sfdisc_t* disc;#endif{ Direct_t* di = (Direct_t*)disc; if(type == SF_FINAL || type == SF_DPOP) {#ifdef F_DIOINFO if(di->cntl&FDIRECT) { di->cntl &= ~FDIRECT; (void)fcntl(f->file,F_SETFL,di->cntl); }#endif free(disc); } return 0;}#if __STD_Cint sfdcdio(Sfio_t* f, size_t bufsize)#elseint sfdcdio(f, bufsize)Sfio_t* f;size_t bufsize;#endif{#ifndef F_DIOINFO return -1;#else int cntl; struct dioattr dio; Void_t* buf; Direct_t* di; if(f->extent < 0 || (f->flags&SF_STRING)) return -1; if((cntl = fcntl(f->file,F_GETFL,0)) < 0) return -1; if(!(cntl&FDIRECT) ) { cntl |= FDIRECT; if(fcntl(f->file,F_SETFL,cntl) < 0) return -1; } if(fcntl(f->file,F_DIOINFO,&dio) < 0) goto no_direct; if(bufsize > 0) bufsize = (bufsize/dio.d_miniosz)*dio.d_miniosz; if(bufsize <= 0) bufsize = dio.d_miniosz*64; if(bufsize > dio.d_maxiosz) bufsize = dio.d_maxiosz; if(!(di = (Direct_t*)malloc(sizeof(Direct_t))) ) goto no_direct; if(!(buf = (Void_t*)memalign(dio.d_mem,bufsize)) ) { free(di); goto no_direct; } sfsetbuf(f,buf,bufsize); if(sfsetbuf(f,buf,0) == buf) sfset(f,SF_MALLOC,1); else { free(buf); free(di); goto no_direct; } di->disc.readf = dioread; di->disc.writef = diowrite; di->disc.seekf = NIL(Sfseek_f); di->disc.exceptf = dioexcept; di->cntl = cntl; di->dio = dio; if(sfdisc(f,(Sfdisc_t*)di) != (Sfdisc_t*)di) { free(di); no_direct: cntl &= ~FDIRECT; (void)fcntl(f->file,F_SETFL,cntl); return -1; } return 0;#endif /*F_DIOINFO*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -