XRootD
Loading...
Searching...
No Matches
XrdFfsWcache.cc File Reference
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>
#include <cerrno>
#include <pthread.h>
#include "XrdFfs/XrdFfsWcache.hh"
#include "XrdFfs/XrdFfsPosix.hh"
Include dependency graph for XrdFfsWcache.cc:

Go to the source code of this file.

Classes

struct  XrdFfsWcacheFilebuf

Macros

#define O_DIRECT   0

Functions

int XrdFfsWcache_create (int fd, int flags)
void XrdFfsWcache_destroy (int fd)
ssize_t XrdFfsWcache_flush (int fd)
void XrdFfsWcache_init (int basefd, int maxfd)
ssize_t XrdFfsWcache_pread (int fd, char *buf, size_t len, off_t offset)
ssize_t XrdFfsWcache_pwrite (int fd, char *buf, size_t len, off_t offset)

Variables

int XrdFfsPosix_baseFD
ssize_t XrdFfsRcacheBufsize
ssize_t XrdFfsWcacheBufsize = 131072
struct XrdFfsWcacheFilebufXrdFfsWcacheFbufs
int XrdFfsWcacheNFILES

Class Documentation

◆ XrdFfsWcacheFilebuf

struct XrdFfsWcacheFilebuf

Definition at line 72 of file XrdFfsWcache.cc.

Collaboration diagram for XrdFfsWcacheFilebuf:
Class Members
char * buf
size_t bufsize
size_t len
pthread_mutex_t * mlock
off_t offset

Macro Definition Documentation

◆ O_DIRECT

#define O_DIRECT   0

Definition at line 62 of file XrdFfsWcache.cc.

Function Documentation

◆ XrdFfsWcache_create()

int XrdFfsWcache_create ( int fd,
int flags )

Definition at line 126 of file XrdFfsWcache.cc.

134{
136 fd -= XrdFfsPosix_baseFD;
137
138 XrdFfsWcacheFbufs[fd].offset = 0;
139 XrdFfsWcacheFbufs[fd].len = 0;
140 // "flag & O_RDONLY" is not equivalant to ! (flags & O_RDWR) && ! (flags & O_WRONLY)
141 if ( ! (flags & O_RDWR) &&
142 ! (flags & O_WRONLY) &&
143 (flags & O_DIRECT) ) // Limit the usage scenario of the read cache
144 {
145 XrdFfsWcacheFbufs[fd].buf = (char*)malloc(XrdFfsRcacheBufsize);
147 }
148 else
149 {
150 XrdFfsWcacheFbufs[fd].buf = (char*)malloc(XrdFfsWcacheBufsize);
152 }
153 if (XrdFfsWcacheFbufs[fd].buf == NULL)
154 {
155 errno = ENOMEM;
156 return 0;
157 }
158 XrdFfsWcacheFbufs[fd].mlock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
159 if (XrdFfsWcacheFbufs[fd].mlock == NULL)
160 {
161 errno = ENOMEM;
162 return 0;
163 }
164 errno = pthread_mutex_init(XrdFfsWcacheFbufs[fd].mlock, NULL);
165 if (errno)
166 return 0;
167 return 1;
168}
#define O_DIRECT
Definition XrdCrc32c.cc:51
void XrdFfsWcache_destroy(int fd)
ssize_t XrdFfsWcacheBufsize
ssize_t XrdFfsRcacheBufsize
int XrdFfsPosix_baseFD
struct XrdFfsWcacheFilebuf * XrdFfsWcacheFbufs

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::mlock, O_DIRECT, XrdFfsPosix_baseFD, XrdFfsRcacheBufsize, XrdFfsWcache_destroy(), XrdFfsWcacheBufsize, and XrdFfsWcacheFbufs.

Referenced by xrootdfs_create(), and xrootdfs_open().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsWcache_destroy()

void XrdFfsWcache_destroy ( int fd)

Definition at line 170 of file XrdFfsWcache.cc.

171{
172/* XrdFfsWcache_flush(fd); */
173 fd -= XrdFfsPosix_baseFD;
174
175 XrdFfsWcacheFbufs[fd].offset = 0;
176 XrdFfsWcacheFbufs[fd].len = 0;
177 if (XrdFfsWcacheFbufs[fd].buf != NULL)
178 free(XrdFfsWcacheFbufs[fd].buf);
179 XrdFfsWcacheFbufs[fd].buf = NULL;
180 if (XrdFfsWcacheFbufs[fd].mlock != NULL)
181 {
182 pthread_mutex_destroy(XrdFfsWcacheFbufs[fd].mlock);
183 free(XrdFfsWcacheFbufs[fd].mlock);
184 }
185 XrdFfsWcacheFbufs[fd].mlock = NULL;
186}

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::mlock, XrdFfsPosix_baseFD, and XrdFfsWcacheFbufs.

Referenced by XrdFfsWcache_create(), and xrootdfs_release().

Here is the caller graph for this function:

◆ XrdFfsWcache_flush()

ssize_t XrdFfsWcache_flush ( int fd)

Definition at line 188 of file XrdFfsWcache.cc.

189{
190 ssize_t rc;
191 fd -= XrdFfsPosix_baseFD;
192
193 if (XrdFfsWcacheFbufs[fd].len == 0 || XrdFfsWcacheFbufs[fd].buf == NULL )
194 return 0;
195
197 XrdFfsWcacheFbufs[fd].buf, XrdFfsWcacheFbufs[fd].len, XrdFfsWcacheFbufs[fd].offset);
198 if (rc > 0)
199 {
200 XrdFfsWcacheFbufs[fd].offset = 0;
201 XrdFfsWcacheFbufs[fd].len = 0;
202 }
203 return rc;
204}
ssize_t XrdFfsPosix_pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::len, XrdFfsWcacheFilebuf::offset, XrdFfsPosix_baseFD, XrdFfsPosix_pwrite(), and XrdFfsWcacheFbufs.

Referenced by XrdFfsWcache_pwrite(), xrootdfs_fsync(), xrootdfs_ftruncate(), xrootdfs_read(), and xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsWcache_init()

void XrdFfsWcache_init ( int basefd,
int maxfd )

Definition at line 85 of file XrdFfsWcache.cc.

86{
87 int fd;
88/* We are now using virtual file descriptors (from Xrootd Posix interface) in XrdFfsXrootdfs.cc so we need to set
89 * base (lowest) file descriptor, and max number of file descriptors..
90 *
91 struct rlimit rlp;
92
93 getrlimit(RLIMIT_NOFILE, &rlp);
94 XrdFfsWcacheNFILES = rlp.rlim_cur;
95 XrdFfsWcacheNFILES = (XrdFfsWcacheNFILES == (int)RLIM_INFINITY? 4096 : XrdFfsWcacheNFILES);
96 */
97
98 XrdFfsPosix_baseFD = basefd;
99 XrdFfsWcacheNFILES = maxfd;
100
101/* printf("%d %d\n", XrdFfsWcacheNFILES, sizeof(struct XrdFfsWcacheFilebuf)); */
103 for (fd = 0; fd < XrdFfsWcacheNFILES; fd++)
104 {
105 XrdFfsWcacheFbufs[fd].offset = 0;
106 XrdFfsWcacheFbufs[fd].len = 0;
107 XrdFfsWcacheFbufs[fd].buf = NULL;
108 XrdFfsWcacheFbufs[fd].mlock = NULL;
109 }
110 if (!getenv("XRDCL_EC"))
111 {
112 XrdFfsRcacheBufsize = 1024 * 128;
113 }
114 else
115 {
116 char *savptr;
117 int nbdat = atoi(strtok_r(getenv("XRDCL_EC"), ",", &savptr));
118 strtok_r(NULL, ",", &savptr);
119 int chsz = atoi(strtok_r(NULL, ",", &savptr));
120 XrdFfsRcacheBufsize = nbdat * chsz;
121 }
122 if (getenv("XROOTDFS_WCACHESZ"))
123 XrdFfsRcacheBufsize = atoi(getenv("XROOTDFS_WCACHESZ"));
124}
int XrdFfsWcacheNFILES

References XrdFfsPosix_baseFD, XrdFfsRcacheBufsize, XrdFfsWcacheFbufs, and XrdFfsWcacheNFILES.

Referenced by xrootdfs_init().

Here is the caller graph for this function:

◆ XrdFfsWcache_pread()

ssize_t XrdFfsWcache_pread ( int fd,
char * buf,
size_t len,
off_t offset )

Definition at line 230 of file XrdFfsWcache.cc.

231{
232 ssize_t rc;
233 fd -= XrdFfsPosix_baseFD;
234 if (fd < 0)
235 {
236 errno = EBADF;
237 return -1;
238 }
239
240 char *bufptr;
241 size_t bufsize = XrdFfsWcacheFbufs[fd].bufsize;
242
243 pthread_mutex_lock(XrdFfsWcacheFbufs[fd].mlock);
244
245 // identity which block to cache
246 if (XrdFfsWcacheFbufs[fd].len == 0 ||
247 (offset / bufsize != XrdFfsWcacheFbufs[fd].offset / bufsize))
248 {
249 XrdFfsWcacheFbufs[fd].offset = (offset / bufsize) * bufsize;
251 XrdFfsWcacheFbufs[fd].buf,
252 bufsize,
253 XrdFfsWcacheFbufs[fd].offset);
254 } // when XrdFfsWcacheFbufs[fd].len < bufsize, the block is partially cached.
255
256
257 // fetch data from the cache, up to the block's upper boundary.
258 if (XrdFfsWcacheFbufs[fd].offset <= offset &&
259 offset < XrdFfsWcacheFbufs[fd].offset + (off_t)XrdFfsWcacheFbufs[fd].len)
260 { // read from cache,
261//----------------------------------------------------------
262// FUSE doesn't like this block of the code, unless direct_io is enabled, or
263// O_DIRECT flags is used. Otherwise, FUSES will stop reading prematurely
264// when two processes read the same file at the same time.
265 bufptr = &XrdFfsWcacheFbufs[fd].buf[offset - XrdFfsWcacheFbufs[fd].offset];
266 rc = (len < XrdFfsWcacheFbufs[fd].len - (offset - XrdFfsWcacheFbufs[fd].offset))?
267 len : XrdFfsWcacheFbufs[fd].len - (offset - XrdFfsWcacheFbufs[fd].offset);
268 memcpy(buf, bufptr, rc);
269//----------------------------------------------------------
270 }
271 else
272 { // offset fall into the uncached part of the partically cached block
273 rc = XrdFfsPosix_pread(fd + XrdFfsPosix_baseFD, buf, len, offset);
274 }
275 pthread_mutex_unlock(XrdFfsWcacheFbufs[fd].mlock);
276/*
277 // prefetch the next block
278 if ( (offset + rc) ==
279 (XrdFfsWcacheFbufs[fd].offset + bufsize) )
280 {
281 pthread_t thread;
282 pthread_attr_t attr;
283 //size_t stacksize = 4*1024*1024;
284
285 pthread_attr_init(&attr);
286 //pthread_attr_setstacksize(&attr, stacksize);
287 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
288
289 struct fd_n_offset nextblock(fd, (offset + bufsize));
290 if (! pthread_create(&thread, &attr, XrdFfsWcache_updateReadCache, &nextblock))
291 pthread_detach(thread);
292 pthread_attr_destroy(&attr);
293 }
294*/
295 return rc;
296}
ssize_t XrdFfsPosix_pread(int fildes, void *buf, size_t nbyte, off_t offset)

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::bufsize, XrdFfsWcacheFilebuf::len, XrdFfsWcacheFilebuf::mlock, XrdFfsWcacheFilebuf::offset, XrdFfsPosix_baseFD, XrdFfsPosix_pread(), and XrdFfsWcacheFbufs.

Referenced by xrootdfs_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsWcache_pwrite()

ssize_t XrdFfsWcache_pwrite ( int fd,
char * buf,
size_t len,
off_t offset )

Definition at line 298 of file XrdFfsWcache.cc.

299{
300 ssize_t rc;
301 char *bufptr;
302 fd -= XrdFfsPosix_baseFD;
303 if (fd < 0)
304 {
305 errno = EBADF;
306 return -1;
307 }
308
309/* do not use caching under these cases */
310 if (len > (size_t)(XrdFfsWcacheBufsize/2) || fd >= XrdFfsWcacheNFILES)
311 {
312 rc = XrdFfsPosix_pwrite(fd + XrdFfsPosix_baseFD, buf, len, offset);
313 return rc;
314 }
315
316 pthread_mutex_lock(XrdFfsWcacheFbufs[fd].mlock);
317 rc = XrdFfsWcacheFbufs[fd].len;
318/*
319 in the following two cases, a XrdFfsWcache_flush is required:
320 1. current offset isnn't pointing to the tail of data in buffer
321 2. adding new data will exceed the current buffer
322*/
323 if (offset != (off_t)(XrdFfsWcacheFbufs[fd].offset + XrdFfsWcacheFbufs[fd].len) ||
324 (off_t)(offset + len) > (XrdFfsWcacheFbufs[fd].offset + XrdFfsWcacheBufsize))
326
327 errno = 0;
328 if (rc < 0)
329 {
330 errno = ENOSPC;
331 pthread_mutex_unlock(XrdFfsWcacheFbufs[fd].mlock);
332 return -1;
333 }
334
335 bufptr = &XrdFfsWcacheFbufs[fd].buf[XrdFfsWcacheFbufs[fd].len];
336 memcpy(bufptr, buf, len);
337 if (XrdFfsWcacheFbufs[fd].len == 0)
338 XrdFfsWcacheFbufs[fd].offset = offset;
339 XrdFfsWcacheFbufs[fd].len += len;
340
341 pthread_mutex_unlock(XrdFfsWcacheFbufs[fd].mlock);
342 return (ssize_t)len;
343}
ssize_t XrdFfsWcache_flush(int fd)

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::len, XrdFfsWcacheFilebuf::mlock, XrdFfsWcacheFilebuf::offset, XrdFfsPosix_baseFD, XrdFfsPosix_pwrite(), XrdFfsWcache_flush(), XrdFfsWcacheBufsize, XrdFfsWcacheFbufs, and XrdFfsWcacheNFILES.

Referenced by xrootdfs_write().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ XrdFfsPosix_baseFD

◆ XrdFfsRcacheBufsize

ssize_t XrdFfsRcacheBufsize

Definition at line 69 of file XrdFfsWcache.cc.

Referenced by XrdFfsWcache_create(), and XrdFfsWcache_init().

◆ XrdFfsWcacheBufsize

ssize_t XrdFfsWcacheBufsize = 131072

Definition at line 70 of file XrdFfsWcache.cc.

Referenced by XrdFfsWcache_create(), and XrdFfsWcache_pwrite().

◆ XrdFfsWcacheFbufs

◆ XrdFfsWcacheNFILES

int XrdFfsWcacheNFILES

Definition at line 84 of file XrdFfsWcache.cc.

Referenced by XrdFfsWcache_init(), and XrdFfsWcache_pwrite().