XRootD
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 
138  XrdFfsWcacheFbufs[fd].offset = 0;
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
Definition: XrdFfsWcache.cc:70
#define O_DIRECT
Definition: XrdFfsWcache.cc:62
pthread_mutex_t * mlock
Definition: XrdFfsWcache.cc:77
ssize_t XrdFfsRcacheBufsize
Definition: XrdFfsWcache.cc:69
int XrdFfsPosix_baseFD
Definition: XrdFfsWcache.cc:84
struct XrdFfsWcacheFilebuf * XrdFfsWcacheFbufs
Definition: XrdFfsWcache.cc:80

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 
173  XrdFfsWcacheFbufs[fd].offset = 0;
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  {
198  XrdFfsWcacheFbufs[fd].offset = 0;
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)
Definition: XrdFfsPosix.cc:152

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
Definition: XrdFfsWcache.cc:84

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)
Definition: XrdFfsPosix.cc:142

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: