33 #include <sys/param.h>
34 #include <sys/types.h>
37 #if defined(_POSIX_MAPPED_FILES)
59 char XrdOssMio::MM_on = 1;
60 char XrdOssMio::MM_chk = 0;
61 char XrdOssMio::MM_okmlock = 1;
62 char XrdOssMio::MM_preld = 0;
63 long long XrdOssMio::MM_pagsz = (
long long)sysconf(_SC_PAGESIZE);
65 long long XrdOssMio::MM_pages = 1024*1024*1024;
67 long long XrdOssMio::MM_pages = (
long long)sysconf(_SC_PHYS_PAGES);
69 long long XrdOssMio::MM_max = MM_pagsz*MM_pages/2;
70 long long XrdOssMio::MM_inuse = 0;
83 snprintf(buff,
sizeof(buff),
" oss.memfile %s%s%s max %lld",
84 (MM_on ?
"" :
"off "),
85 (MM_preld ?
"preload" :
""),
86 (MM_chk ?
"check xattr" :
""), MM_max);
96 #if defined(_POSIX_MAPPED_FILES)
106 if (
fstat(fd, &statb))
113 int st_devSZ =
sizeof(statb.st_dev);
115 hashname,
sizeof(hashname),
false);
118 hashname+st_devSZ,
sizeof(hashname) - st_devSZ,
false);
122 mapMutex.
Lock(&MM_Mutex);
126 if ((mp = MM_Hash.
Find(hashname)))
127 {
DEBUG(
"Reusing mmap; usecnt=" <<mp->inUse <<
" path=" <<path);
128 if (!(mp->Status &
OSSMIO_MPRM) && !mp->inUse) Reclaim(mp);
135 if (MM_inuse + statb.st_size > MM_max)
136 {
if (!Reclaim(statb.st_size))
137 {
OssEroute.
Emsg(
"Mio",
"Unable to reclaim enough storage to mmap",path);
141 MM_inuse += statb.st_size;
145 if ((thefile = mmap(0,statb.st_size,PROT_READ,MAP_PRIVATE,fd,0))==MAP_FAILED)
148 }
else {
DEBUG(
"mmap " <<statb.st_size <<
" bytes for " <<path);}
153 {
if (mlock((
char *)thefile, statb.st_size))
154 {
if (errno == ENOSYS || errno == ENOTSUP)
155 {
OssEroute.
Emsg(
"Mio",
"mlock() not supported; feature disabled.");
158 else if (errno == EPERM)
159 {
OssEroute.
Emsg(
"Mio",
"Not privileged for mlock(); feature disabled.");
163 }
else {
DEBUG(
"Locked " <<statb.st_size <<
" bytes for " <<path);}
169 {
OssEroute.
Emsg(
"Mio",
"Unable to allocate mmap file object for", path);
170 munmap((
char *)thefile, statb.st_size);
177 mp->Size = statb.st_size;
178 mp->Dev = statb.st_dev;
179 mp->Ino = statb.st_ino;
184 if (MM_Hash.
Add(hashname, mp))
186 munmap((
char *)thefile, statb.st_size);
194 {mp->Next = MM_Perm; MM_Perm = mp;
195 DEBUG(
"Placed file on permanent queue " <<path);
200 if (MM_preld && mp->inUse == 1)
205 {
OssEroute.
Emsg(
"Mio", retc,
"creating mmap preload thread");
208 else DEBUG(
"started mmap preload thread; tid=" <<(
unsigned long)tid);
226 char *Base = (
char *)(mp->Base);
227 char *Bend = Base + mp->Size;
228 long long MY_pagsz = MM_pagsz;
233 while(Base < Bend) Base += (*Base ? MY_pagsz : MM_pagsz);
247 int XrdOssMio::Reclaim(off_t amount)
251 DEBUG(
"Trying to reclaim " <<amount <<
" bytes.");
255 while((mp = MM_Idle) && amount > 0)
257 MM_inuse -= mp->Size;
259 MM_Hash.
Del(mp->HashName);
276 while(cmp && mp != cmp) {pmp = cmp; cmp = cmp->Next;}
281 {
if (pmp) pmp->Next = mp->Next;
282 else MM_Idle = mp->Next;
283 if (MM_IdleLast == cmp) MM_IdleLast = pmp;
285 else {
DEBUG(
"Cannot find mapping for " <<mp->Dev <<
':' <<mp->Ino);}
302 {
OssEroute.
Emsg(
"Mio",
"MM usecount underflow for ", mp->HashName);
304 }
else if (mp->inUse > 0)
return;
309 {
if (MM_IdleLast) MM_IdleLast->Next = mp;
322 if (V_on >= 0) MM_on = (char)V_on;
323 if (V_preld >= 0) MM_preld = (char)V_preld;
324 if (V_check >= 0) MM_chk = (char)V_check;
329 if (V_max > 0) MM_max = V_max;
330 else if (V_max < 0) MM_max = MM_pagsz*MM_pages*(-V_max)/100;
339 #if defined(_POSIX_MAPPED_FILES)
340 munmap((
char *)Base, Size);
int stat(const char *path, struct stat *buf)
int fstat(int fildes, struct stat *buf)
static XrdOssMioFile * Map(char *path, int fd, int opts)
static void Recycle(XrdOssMioFile *mp)
static void * preLoad(void *arg)
static void Set(int V_off, int V_preld, int V_check)
static void Display(XrdSysError &Eroute)
int Del(const char *KeyVal, XrdOucHash_Options opt=Hash_default)
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
T * Find(const char *KeyVal, time_t *KeyTime=0)
static char * bin2hex(char *inbuff, int dlen, char *buff, int blen, bool sep=true)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
void Lock(XrdSysMutex *Mutex)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)