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 if ( ((flags & O_ACCMODE) == O_RDONLY) &&
141 (flags & O_DIRECT) ) // Limit the usage scenario of the read cache
142 {
143 XrdFfsWcacheFbufs[fd].buf = (char*)malloc(XrdFfsRcacheBufsize);
145 }
146 else
147 {
148 XrdFfsWcacheFbufs[fd].buf = (char*)malloc(XrdFfsWcacheBufsize);
150 }
151 if (XrdFfsWcacheFbufs[fd].buf == NULL)
152 {
153 errno = ENOMEM;
154 return 0;
155 }
156 XrdFfsWcacheFbufs[fd].mlock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
157 if (XrdFfsWcacheFbufs[fd].mlock == NULL)
158 {
159 errno = ENOMEM;
160 return 0;
161 }
162 errno = pthread_mutex_init(XrdFfsWcacheFbufs[fd].mlock, NULL);
163 if (errno)
164 return 0;
165 return 1;
166}
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 168 of file XrdFfsWcache.cc.

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

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 186 of file XrdFfsWcache.cc.

187{
188 ssize_t rc;
189 fd -= XrdFfsPosix_baseFD;
190
191 if (XrdFfsWcacheFbufs[fd].len == 0 || XrdFfsWcacheFbufs[fd].buf == NULL )
192 return 0;
193
195 XrdFfsWcacheFbufs[fd].buf, XrdFfsWcacheFbufs[fd].len, XrdFfsWcacheFbufs[fd].offset);
196 if (rc > 0)
197 {
199 XrdFfsWcacheFbufs[fd].len = 0;
200 }
201 return rc;
202}
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 228 of file XrdFfsWcache.cc.

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

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