XRootD
Loading...
Searching...
No Matches
XrdFfsWcache.hh File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

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)
 

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
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}
void XrdFfsWcache_destroy(int fd)
ssize_t XrdFfsWcacheBufsize
#define O_DIRECT
pthread_mutex_t * mlock
ssize_t XrdFfsRcacheBufsize
int XrdFfsPosix_baseFD
struct XrdFfsWcacheFilebuf * XrdFfsWcacheFbufs

References XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::bufsize, XrdFfsWcacheFilebuf::len, XrdFfsWcacheFilebuf::mlock, O_DIRECT, XrdFfsWcacheFilebuf::offset, 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
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::len, XrdFfsWcacheFilebuf::mlock, XrdFfsWcacheFilebuf::offset, 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 {
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 {
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 XrdFfsWcacheFilebuf::buf, XrdFfsWcacheFilebuf::len, XrdFfsWcacheFilebuf::mlock, XrdFfsWcacheFilebuf::offset, 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: